Skip to content

Allow DBDagBag TTL cache eviction without a size cap - #69774

Closed
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache
Closed

Allow DBDagBag TTL cache eviction without a size cap#69774
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache

Conversation

@aeroyorch

@aeroyorchaeroyorch commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Allow DBDagBag TTL cache eviction without a size cap (i.e. cache_size=0, cache_ttl>0).

Related to #69001 and #69007

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Claude Opus 4.8 to analyze the impact of this change in terms of docs/code.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch 2 times, most recently from 379aa9e to a112469CompareJuly 12, 2026 12:12
@aeroyorchaeroyorch changed the title Allow DBDagBag TTL cache eviction without a size capAllow DBDagBag TTL cache eviction without a size capJul 12, 2026

@SameerMesiah97SameerMesiah97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit. Looks good otherwise.

Comment threadairflow-core/src/airflow/models/dagbag.py Outdated
@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Just one nit. Looks good otherwise.

Thanks for the review! Changes already implemented

@potiukpotiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
@jason810496
jason810496 self-requested a review July 16, 2026 13:03
@lohyenshen

Copy link
Copy Markdown

hi, may I know what airflow version would this be released to?

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 5b5ca6c to d65c199CompareJuly 25, 2026 15:24

@vatsrahul1001vatsrahul1001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

@aeroyorch

aeroyorch commented Aug 2, 2026

Copy link
Copy Markdown
ContributorAuthor

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

Thanks for the review. Changes already implemented :)

@eladkaleladkal added this to the Airflow 3.3.1 milestone Aug 4, 2026
@eladkaleladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 4, 2026
@vatsrahul1001

vatsrahul1001 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

LGTM!, can be merged after code owners review

@vatsrahul1001

Copy link
Copy Markdown
Contributor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

No problem. In the meantime, I can work on some of the other items to fix #69001

Comment threadairflow-core/src/airflow/api_fastapi/common/dagbag.py
Comment threadairflow-core/src/airflow/config_templates/config.yml
Comment threadairflow-core/docs/faq.rst Outdated
@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from c55fa9a to 1a6f6e7CompareAugust 8, 2026 15:17
@aeroyorch
aeroyorch requested a review from kaxilAugust 8, 2026 15:18

@ColtenOuOColtenOuO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

Thanks for the review!

Fair point, but I'd rather leave it as is for now, the trade-off you mention is the deciding one for me: keeping it at the call site lets us name the actual config option that's wrong, which is what the user needs to fix.

Happy to revisit when the Scheduler part lands for #69001.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 1a6f6e7 to 28a8c01CompareAugust 12, 2026 23:21

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind giving more context as to why we are doing this. If your use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbounded cache there.

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Do you mind giving more context as to why we are doing this. If you use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbouded cache there.

Hi Pierre, sure.

I don't think this brings back the leak. Today cache_size=0 is a plain dict with no eviction at all. With this change, cache_size=0 + cache_ttl>0 creates a real TTLCache. That evicts exactly what grows and keeps the hot ones. Defaults don't change.

Tuning the size doesn't really help here: the scheduler cycles through all active dag_version_ids, so any cap below the active set evicts each key just before it's needed again. @kaxil raised this in the #69007 review and @potiuk asked for TTL eviction without a size cap in DBDagBag as a first step.

@pierrejeambrun

pierrejeambrun commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks for the context @aeroyorch this makes more sense. I had the wrong assumption that unbounded cache was just not possible anymore. (at all)

I would be for not allowing unbounded cache completely since we know it's a bad practice, but for backward comp I understand why unbounded is still allowed.

@uranusjr

Copy link
Copy Markdown
Member

This is superceded by #71704

@aeroyorch
aeroyorch deleted the dbdagbag-ttl-only-cache branch August 20, 2026 06:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-3-testBackport to v3-3-testready for maintainer reviewSet after triaging when all criteria pass.type:bug-fixChangelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@aeroyorch@lohyenshen@vatsrahul1001@pierrejeambrun@uranusjr@kaxil@ColtenOuO@SameerMesiah97@potiuk@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Allow `DBDagBag` TTL cache eviction without a size cap by aeroyorch · Pull Request #69774 · apache/airflow · GitHub
Skip to content

Allow DBDagBag TTL cache eviction without a size cap - #69774

Closed
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache
Closed

Allow DBDagBag TTL cache eviction without a size cap#69774
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache

Conversation

@aeroyorch

@aeroyorchaeroyorch commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Allow DBDagBag TTL cache eviction without a size cap (i.e. cache_size=0, cache_ttl>0).

Related to #69001 and #69007

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Claude Opus 4.8 to analyze the impact of this change in terms of docs/code.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch 2 times, most recently from 379aa9e to a112469CompareJuly 12, 2026 12:12
@aeroyorchaeroyorch changed the title Allow DBDagBag TTL cache eviction without a size capAllow DBDagBag TTL cache eviction without a size capJul 12, 2026

@SameerMesiah97SameerMesiah97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit. Looks good otherwise.

Comment threadairflow-core/src/airflow/models/dagbag.py Outdated
@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Just one nit. Looks good otherwise.

Thanks for the review! Changes already implemented

@potiukpotiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
@jason810496
jason810496 self-requested a review July 16, 2026 13:03
@lohyenshen

Copy link
Copy Markdown

hi, may I know what airflow version would this be released to?

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 5b5ca6c to d65c199CompareJuly 25, 2026 15:24

@vatsrahul1001vatsrahul1001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

@aeroyorch

aeroyorch commented Aug 2, 2026

Copy link
Copy Markdown
ContributorAuthor

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

Thanks for the review. Changes already implemented :)

@eladkaleladkal added this to the Airflow 3.3.1 milestone Aug 4, 2026
@eladkaleladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 4, 2026
@vatsrahul1001

vatsrahul1001 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

LGTM!, can be merged after code owners review

@vatsrahul1001

Copy link
Copy Markdown
Contributor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

No problem. In the meantime, I can work on some of the other items to fix #69001

Comment threadairflow-core/src/airflow/api_fastapi/common/dagbag.py
Comment threadairflow-core/src/airflow/config_templates/config.yml
Comment threadairflow-core/docs/faq.rst Outdated
@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from c55fa9a to 1a6f6e7CompareAugust 8, 2026 15:17
@aeroyorch
aeroyorch requested a review from kaxilAugust 8, 2026 15:18

@ColtenOuOColtenOuO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

Thanks for the review!

Fair point, but I'd rather leave it as is for now, the trade-off you mention is the deciding one for me: keeping it at the call site lets us name the actual config option that's wrong, which is what the user needs to fix.

Happy to revisit when the Scheduler part lands for #69001.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 1a6f6e7 to 28a8c01CompareAugust 12, 2026 23:21

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind giving more context as to why we are doing this. If your use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbounded cache there.

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Do you mind giving more context as to why we are doing this. If you use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbouded cache there.

Hi Pierre, sure.

I don't think this brings back the leak. Today cache_size=0 is a plain dict with no eviction at all. With this change, cache_size=0 + cache_ttl>0 creates a real TTLCache. That evicts exactly what grows and keeps the hot ones. Defaults don't change.

Tuning the size doesn't really help here: the scheduler cycles through all active dag_version_ids, so any cap below the active set evicts each key just before it's needed again. @kaxil raised this in the #69007 review and @potiuk asked for TTL eviction without a size cap in DBDagBag as a first step.

@pierrejeambrun

pierrejeambrun commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks for the context @aeroyorch this makes more sense. I had the wrong assumption that unbounded cache was just not possible anymore. (at all)

I would be for not allowing unbounded cache completely since we know it's a bad practice, but for backward comp I understand why unbounded is still allowed.

@uranusjr

Copy link
Copy Markdown
Member

This is superceded by #71704

@aeroyorch
aeroyorch deleted the dbdagbag-ttl-only-cache branch August 20, 2026 06:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-3-testBackport to v3-3-testready for maintainer reviewSet after triaging when all criteria pass.type:bug-fixChangelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@aeroyorch@lohyenshen@vatsrahul1001@pierrejeambrun@uranusjr@kaxil@ColtenOuO@SameerMesiah97@potiuk@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Allow `DBDagBag` TTL cache eviction without a size cap by aeroyorch · Pull Request #69774 · apache/airflow · GitHub
Skip to content

Allow DBDagBag TTL cache eviction without a size cap - #69774

Closed
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache
Closed

Allow DBDagBag TTL cache eviction without a size cap#69774
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache

Conversation

@aeroyorch

@aeroyorchaeroyorch commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Allow DBDagBag TTL cache eviction without a size cap (i.e. cache_size=0, cache_ttl>0).

Related to #69001 and #69007

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Claude Opus 4.8 to analyze the impact of this change in terms of docs/code.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch 2 times, most recently from 379aa9e to a112469CompareJuly 12, 2026 12:12
@aeroyorchaeroyorch changed the title Allow DBDagBag TTL cache eviction without a size capAllow DBDagBag TTL cache eviction without a size capJul 12, 2026

@SameerMesiah97SameerMesiah97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit. Looks good otherwise.

Comment threadairflow-core/src/airflow/models/dagbag.py Outdated
@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Just one nit. Looks good otherwise.

Thanks for the review! Changes already implemented

@potiukpotiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
@jason810496
jason810496 self-requested a review July 16, 2026 13:03
@lohyenshen

Copy link
Copy Markdown

hi, may I know what airflow version would this be released to?

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 5b5ca6c to d65c199CompareJuly 25, 2026 15:24

@vatsrahul1001vatsrahul1001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

@aeroyorch

aeroyorch commented Aug 2, 2026

Copy link
Copy Markdown
ContributorAuthor

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

Thanks for the review. Changes already implemented :)

@eladkaleladkal added this to the Airflow 3.3.1 milestone Aug 4, 2026
@eladkaleladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 4, 2026
@vatsrahul1001

vatsrahul1001 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

LGTM!, can be merged after code owners review

@vatsrahul1001

Copy link
Copy Markdown
Contributor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

No problem. In the meantime, I can work on some of the other items to fix #69001

Comment threadairflow-core/src/airflow/api_fastapi/common/dagbag.py
Comment threadairflow-core/src/airflow/config_templates/config.yml
Comment threadairflow-core/docs/faq.rst Outdated
@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from c55fa9a to 1a6f6e7CompareAugust 8, 2026 15:17
@aeroyorch
aeroyorch requested a review from kaxilAugust 8, 2026 15:18

@ColtenOuOColtenOuO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

Thanks for the review!

Fair point, but I'd rather leave it as is for now, the trade-off you mention is the deciding one for me: keeping it at the call site lets us name the actual config option that's wrong, which is what the user needs to fix.

Happy to revisit when the Scheduler part lands for #69001.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 1a6f6e7 to 28a8c01CompareAugust 12, 2026 23:21

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind giving more context as to why we are doing this. If your use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbounded cache there.

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Do you mind giving more context as to why we are doing this. If you use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbouded cache there.

Hi Pierre, sure.

I don't think this brings back the leak. Today cache_size=0 is a plain dict with no eviction at all. With this change, cache_size=0 + cache_ttl>0 creates a real TTLCache. That evicts exactly what grows and keeps the hot ones. Defaults don't change.

Tuning the size doesn't really help here: the scheduler cycles through all active dag_version_ids, so any cap below the active set evicts each key just before it's needed again. @kaxil raised this in the #69007 review and @potiuk asked for TTL eviction without a size cap in DBDagBag as a first step.

@pierrejeambrun

pierrejeambrun commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks for the context @aeroyorch this makes more sense. I had the wrong assumption that unbounded cache was just not possible anymore. (at all)

I would be for not allowing unbounded cache completely since we know it's a bad practice, but for backward comp I understand why unbounded is still allowed.

@uranusjr

Copy link
Copy Markdown
Member

This is superceded by #71704

@aeroyorch
aeroyorch deleted the dbdagbag-ttl-only-cache branch August 20, 2026 06:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-3-testBackport to v3-3-testready for maintainer reviewSet after triaging when all criteria pass.type:bug-fixChangelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@aeroyorch@lohyenshen@vatsrahul1001@pierrejeambrun@uranusjr@kaxil@ColtenOuO@SameerMesiah97@potiuk@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Allow `DBDagBag` TTL cache eviction without a size cap by aeroyorch · Pull Request #69774 · apache/airflow · GitHub
Skip to content

Allow DBDagBag TTL cache eviction without a size cap - #69774

Closed
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache
Closed

Allow DBDagBag TTL cache eviction without a size cap#69774
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache

Conversation

@aeroyorch

@aeroyorchaeroyorch commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Allow DBDagBag TTL cache eviction without a size cap (i.e. cache_size=0, cache_ttl>0).

Related to #69001 and #69007

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Claude Opus 4.8 to analyze the impact of this change in terms of docs/code.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch 2 times, most recently from 379aa9e to a112469CompareJuly 12, 2026 12:12
@aeroyorchaeroyorch changed the title Allow DBDagBag TTL cache eviction without a size capAllow DBDagBag TTL cache eviction without a size capJul 12, 2026

@SameerMesiah97SameerMesiah97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit. Looks good otherwise.

Comment threadairflow-core/src/airflow/models/dagbag.py Outdated
@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Just one nit. Looks good otherwise.

Thanks for the review! Changes already implemented

@potiukpotiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
@jason810496
jason810496 self-requested a review July 16, 2026 13:03
@lohyenshen

Copy link
Copy Markdown

hi, may I know what airflow version would this be released to?

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 5b5ca6c to d65c199CompareJuly 25, 2026 15:24

@vatsrahul1001vatsrahul1001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

@aeroyorch

aeroyorch commented Aug 2, 2026

Copy link
Copy Markdown
ContributorAuthor

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

Thanks for the review. Changes already implemented :)

@eladkaleladkal added this to the Airflow 3.3.1 milestone Aug 4, 2026
@eladkaleladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 4, 2026
@vatsrahul1001

vatsrahul1001 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

LGTM!, can be merged after code owners review

@vatsrahul1001

Copy link
Copy Markdown
Contributor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

No problem. In the meantime, I can work on some of the other items to fix #69001

Comment threadairflow-core/src/airflow/api_fastapi/common/dagbag.py
Comment threadairflow-core/src/airflow/config_templates/config.yml
Comment threadairflow-core/docs/faq.rst Outdated
@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from c55fa9a to 1a6f6e7CompareAugust 8, 2026 15:17
@aeroyorch
aeroyorch requested a review from kaxilAugust 8, 2026 15:18

@ColtenOuOColtenOuO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

Thanks for the review!

Fair point, but I'd rather leave it as is for now, the trade-off you mention is the deciding one for me: keeping it at the call site lets us name the actual config option that's wrong, which is what the user needs to fix.

Happy to revisit when the Scheduler part lands for #69001.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 1a6f6e7 to 28a8c01CompareAugust 12, 2026 23:21

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind giving more context as to why we are doing this. If your use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbounded cache there.

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Do you mind giving more context as to why we are doing this. If you use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbouded cache there.

Hi Pierre, sure.

I don't think this brings back the leak. Today cache_size=0 is a plain dict with no eviction at all. With this change, cache_size=0 + cache_ttl>0 creates a real TTLCache. That evicts exactly what grows and keeps the hot ones. Defaults don't change.

Tuning the size doesn't really help here: the scheduler cycles through all active dag_version_ids, so any cap below the active set evicts each key just before it's needed again. @kaxil raised this in the #69007 review and @potiuk asked for TTL eviction without a size cap in DBDagBag as a first step.

@pierrejeambrun

pierrejeambrun commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks for the context @aeroyorch this makes more sense. I had the wrong assumption that unbounded cache was just not possible anymore. (at all)

I would be for not allowing unbounded cache completely since we know it's a bad practice, but for backward comp I understand why unbounded is still allowed.

@uranusjr

Copy link
Copy Markdown
Member

This is superceded by #71704

@aeroyorch
aeroyorch deleted the dbdagbag-ttl-only-cache branch August 20, 2026 06:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-3-testBackport to v3-3-testready for maintainer reviewSet after triaging when all criteria pass.type:bug-fixChangelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@aeroyorch@lohyenshen@vatsrahul1001@pierrejeambrun@uranusjr@kaxil@ColtenOuO@SameerMesiah97@potiuk@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Allow `DBDagBag` TTL cache eviction without a size cap by aeroyorch · Pull Request #69774 · apache/airflow · GitHub
Skip to content

Allow DBDagBag TTL cache eviction without a size cap - #69774

Closed
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache
Closed

Allow DBDagBag TTL cache eviction without a size cap#69774
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache

Conversation

@aeroyorch

@aeroyorchaeroyorch commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Allow DBDagBag TTL cache eviction without a size cap (i.e. cache_size=0, cache_ttl>0).

Related to #69001 and #69007

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Claude Opus 4.8 to analyze the impact of this change in terms of docs/code.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch 2 times, most recently from 379aa9e to a112469CompareJuly 12, 2026 12:12
@aeroyorchaeroyorch changed the title Allow DBDagBag TTL cache eviction without a size capAllow DBDagBag TTL cache eviction without a size capJul 12, 2026

@SameerMesiah97SameerMesiah97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit. Looks good otherwise.

Comment threadairflow-core/src/airflow/models/dagbag.py Outdated
@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Just one nit. Looks good otherwise.

Thanks for the review! Changes already implemented

@potiukpotiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
@jason810496
jason810496 self-requested a review July 16, 2026 13:03
@lohyenshen

Copy link
Copy Markdown

hi, may I know what airflow version would this be released to?

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 5b5ca6c to d65c199CompareJuly 25, 2026 15:24

@vatsrahul1001vatsrahul1001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

@aeroyorch

aeroyorch commented Aug 2, 2026

Copy link
Copy Markdown
ContributorAuthor

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

Thanks for the review. Changes already implemented :)

@eladkaleladkal added this to the Airflow 3.3.1 milestone Aug 4, 2026
@eladkaleladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 4, 2026
@vatsrahul1001

vatsrahul1001 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

LGTM!, can be merged after code owners review

@vatsrahul1001

Copy link
Copy Markdown
Contributor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

No problem. In the meantime, I can work on some of the other items to fix #69001

Comment threadairflow-core/src/airflow/api_fastapi/common/dagbag.py
Comment threadairflow-core/src/airflow/config_templates/config.yml
Comment threadairflow-core/docs/faq.rst Outdated
@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from c55fa9a to 1a6f6e7CompareAugust 8, 2026 15:17
@aeroyorch
aeroyorch requested a review from kaxilAugust 8, 2026 15:18

@ColtenOuOColtenOuO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

Thanks for the review!

Fair point, but I'd rather leave it as is for now, the trade-off you mention is the deciding one for me: keeping it at the call site lets us name the actual config option that's wrong, which is what the user needs to fix.

Happy to revisit when the Scheduler part lands for #69001.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 1a6f6e7 to 28a8c01CompareAugust 12, 2026 23:21

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind giving more context as to why we are doing this. If your use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbounded cache there.

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Do you mind giving more context as to why we are doing this. If you use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbouded cache there.

Hi Pierre, sure.

I don't think this brings back the leak. Today cache_size=0 is a plain dict with no eviction at all. With this change, cache_size=0 + cache_ttl>0 creates a real TTLCache. That evicts exactly what grows and keeps the hot ones. Defaults don't change.

Tuning the size doesn't really help here: the scheduler cycles through all active dag_version_ids, so any cap below the active set evicts each key just before it's needed again. @kaxil raised this in the #69007 review and @potiuk asked for TTL eviction without a size cap in DBDagBag as a first step.

@pierrejeambrun

pierrejeambrun commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks for the context @aeroyorch this makes more sense. I had the wrong assumption that unbounded cache was just not possible anymore. (at all)

I would be for not allowing unbounded cache completely since we know it's a bad practice, but for backward comp I understand why unbounded is still allowed.

@uranusjr

Copy link
Copy Markdown
Member

This is superceded by #71704

@aeroyorch
aeroyorch deleted the dbdagbag-ttl-only-cache branch August 20, 2026 06:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-3-testBackport to v3-3-testready for maintainer reviewSet after triaging when all criteria pass.type:bug-fixChangelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@aeroyorch@lohyenshen@vatsrahul1001@pierrejeambrun@uranusjr@kaxil@ColtenOuO@SameerMesiah97@potiuk@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Allow `DBDagBag` TTL cache eviction without a size cap by aeroyorch · Pull Request #69774 · apache/airflow · GitHub
Skip to content

Allow DBDagBag TTL cache eviction without a size cap - #69774

Closed
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache
Closed

Allow DBDagBag TTL cache eviction without a size cap#69774
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache

Conversation

@aeroyorch

@aeroyorchaeroyorch commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Allow DBDagBag TTL cache eviction without a size cap (i.e. cache_size=0, cache_ttl>0).

Related to #69001 and #69007

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Claude Opus 4.8 to analyze the impact of this change in terms of docs/code.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch 2 times, most recently from 379aa9e to a112469CompareJuly 12, 2026 12:12
@aeroyorchaeroyorch changed the title Allow DBDagBag TTL cache eviction without a size capAllow DBDagBag TTL cache eviction without a size capJul 12, 2026

@SameerMesiah97SameerMesiah97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit. Looks good otherwise.

Comment threadairflow-core/src/airflow/models/dagbag.py Outdated
@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Just one nit. Looks good otherwise.

Thanks for the review! Changes already implemented

@potiukpotiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
@jason810496
jason810496 self-requested a review July 16, 2026 13:03
@lohyenshen

Copy link
Copy Markdown

hi, may I know what airflow version would this be released to?

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 5b5ca6c to d65c199CompareJuly 25, 2026 15:24

@vatsrahul1001vatsrahul1001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

@aeroyorch

aeroyorch commented Aug 2, 2026

Copy link
Copy Markdown
ContributorAuthor

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

Thanks for the review. Changes already implemented :)

@eladkaleladkal added this to the Airflow 3.3.1 milestone Aug 4, 2026
@eladkaleladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 4, 2026
@vatsrahul1001

vatsrahul1001 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

LGTM!, can be merged after code owners review

@vatsrahul1001

Copy link
Copy Markdown
Contributor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

No problem. In the meantime, I can work on some of the other items to fix #69001

Comment threadairflow-core/src/airflow/api_fastapi/common/dagbag.py
Comment threadairflow-core/src/airflow/config_templates/config.yml
Comment threadairflow-core/docs/faq.rst Outdated
@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from c55fa9a to 1a6f6e7CompareAugust 8, 2026 15:17
@aeroyorch
aeroyorch requested a review from kaxilAugust 8, 2026 15:18

@ColtenOuOColtenOuO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

Thanks for the review!

Fair point, but I'd rather leave it as is for now, the trade-off you mention is the deciding one for me: keeping it at the call site lets us name the actual config option that's wrong, which is what the user needs to fix.

Happy to revisit when the Scheduler part lands for #69001.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 1a6f6e7 to 28a8c01CompareAugust 12, 2026 23:21

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind giving more context as to why we are doing this. If your use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbounded cache there.

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Do you mind giving more context as to why we are doing this. If you use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbouded cache there.

Hi Pierre, sure.

I don't think this brings back the leak. Today cache_size=0 is a plain dict with no eviction at all. With this change, cache_size=0 + cache_ttl>0 creates a real TTLCache. That evicts exactly what grows and keeps the hot ones. Defaults don't change.

Tuning the size doesn't really help here: the scheduler cycles through all active dag_version_ids, so any cap below the active set evicts each key just before it's needed again. @kaxil raised this in the #69007 review and @potiuk asked for TTL eviction without a size cap in DBDagBag as a first step.

@pierrejeambrun

pierrejeambrun commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks for the context @aeroyorch this makes more sense. I had the wrong assumption that unbounded cache was just not possible anymore. (at all)

I would be for not allowing unbounded cache completely since we know it's a bad practice, but for backward comp I understand why unbounded is still allowed.

@uranusjr

Copy link
Copy Markdown
Member

This is superceded by #71704

@aeroyorch
aeroyorch deleted the dbdagbag-ttl-only-cache branch August 20, 2026 06:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-3-testBackport to v3-3-testready for maintainer reviewSet after triaging when all criteria pass.type:bug-fixChangelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@aeroyorch@lohyenshen@vatsrahul1001@pierrejeambrun@uranusjr@kaxil@ColtenOuO@SameerMesiah97@potiuk@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Allow `DBDagBag` TTL cache eviction without a size cap by aeroyorch · Pull Request #69774 · apache/airflow · GitHub
Skip to content

Allow DBDagBag TTL cache eviction without a size cap - #69774

Closed
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache
Closed

Allow DBDagBag TTL cache eviction without a size cap#69774
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache

Conversation

@aeroyorch

@aeroyorchaeroyorch commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Allow DBDagBag TTL cache eviction without a size cap (i.e. cache_size=0, cache_ttl>0).

Related to #69001 and #69007

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Claude Opus 4.8 to analyze the impact of this change in terms of docs/code.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch 2 times, most recently from 379aa9e to a112469CompareJuly 12, 2026 12:12
@aeroyorchaeroyorch changed the title Allow DBDagBag TTL cache eviction without a size capAllow DBDagBag TTL cache eviction without a size capJul 12, 2026

@SameerMesiah97SameerMesiah97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit. Looks good otherwise.

Comment threadairflow-core/src/airflow/models/dagbag.py Outdated
@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Just one nit. Looks good otherwise.

Thanks for the review! Changes already implemented

@potiukpotiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
@jason810496
jason810496 self-requested a review July 16, 2026 13:03
@lohyenshen

Copy link
Copy Markdown

hi, may I know what airflow version would this be released to?

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 5b5ca6c to d65c199CompareJuly 25, 2026 15:24

@vatsrahul1001vatsrahul1001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

@aeroyorch

aeroyorch commented Aug 2, 2026

Copy link
Copy Markdown
ContributorAuthor

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

Thanks for the review. Changes already implemented :)

@eladkaleladkal added this to the Airflow 3.3.1 milestone Aug 4, 2026
@eladkaleladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 4, 2026
@vatsrahul1001

vatsrahul1001 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

LGTM!, can be merged after code owners review

@vatsrahul1001

Copy link
Copy Markdown
Contributor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

No problem. In the meantime, I can work on some of the other items to fix #69001

Comment threadairflow-core/src/airflow/api_fastapi/common/dagbag.py
Comment threadairflow-core/src/airflow/config_templates/config.yml
Comment threadairflow-core/docs/faq.rst Outdated
@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from c55fa9a to 1a6f6e7CompareAugust 8, 2026 15:17
@aeroyorch
aeroyorch requested a review from kaxilAugust 8, 2026 15:18

@ColtenOuOColtenOuO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

Thanks for the review!

Fair point, but I'd rather leave it as is for now, the trade-off you mention is the deciding one for me: keeping it at the call site lets us name the actual config option that's wrong, which is what the user needs to fix.

Happy to revisit when the Scheduler part lands for #69001.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 1a6f6e7 to 28a8c01CompareAugust 12, 2026 23:21

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind giving more context as to why we are doing this. If your use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbounded cache there.

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Do you mind giving more context as to why we are doing this. If you use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbouded cache there.

Hi Pierre, sure.

I don't think this brings back the leak. Today cache_size=0 is a plain dict with no eviction at all. With this change, cache_size=0 + cache_ttl>0 creates a real TTLCache. That evicts exactly what grows and keeps the hot ones. Defaults don't change.

Tuning the size doesn't really help here: the scheduler cycles through all active dag_version_ids, so any cap below the active set evicts each key just before it's needed again. @kaxil raised this in the #69007 review and @potiuk asked for TTL eviction without a size cap in DBDagBag as a first step.

@pierrejeambrun

pierrejeambrun commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks for the context @aeroyorch this makes more sense. I had the wrong assumption that unbounded cache was just not possible anymore. (at all)

I would be for not allowing unbounded cache completely since we know it's a bad practice, but for backward comp I understand why unbounded is still allowed.

@uranusjr

Copy link
Copy Markdown
Member

This is superceded by #71704

@aeroyorch
aeroyorch deleted the dbdagbag-ttl-only-cache branch August 20, 2026 06:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-3-testBackport to v3-3-testready for maintainer reviewSet after triaging when all criteria pass.type:bug-fixChangelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@aeroyorch@lohyenshen@vatsrahul1001@pierrejeambrun@uranusjr@kaxil@ColtenOuO@SameerMesiah97@potiuk@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Allow `DBDagBag` TTL cache eviction without a size cap by aeroyorch · Pull Request #69774 · apache/airflow · GitHub
Skip to content

Allow DBDagBag TTL cache eviction without a size cap - #69774

Closed
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache
Closed

Allow DBDagBag TTL cache eviction without a size cap#69774
aeroyorch wants to merge 4 commits into
apache:mainfrom
aeroyorch:dbdagbag-ttl-only-cache

Conversation

@aeroyorch

@aeroyorchaeroyorch commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Allow DBDagBag TTL cache eviction without a size cap (i.e. cache_size=0, cache_ttl>0).

Related to #69001 and #69007

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Claude Opus 4.8 to analyze the impact of this change in terms of docs/code.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch 2 times, most recently from 379aa9e to a112469CompareJuly 12, 2026 12:12
@aeroyorchaeroyorch changed the title Allow DBDagBag TTL cache eviction without a size capAllow DBDagBag TTL cache eviction without a size capJul 12, 2026

@SameerMesiah97SameerMesiah97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit. Looks good otherwise.

Comment threadairflow-core/src/airflow/models/dagbag.py Outdated
@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Just one nit. Looks good otherwise.

Thanks for the review! Changes already implemented

@potiukpotiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 15, 2026
@jason810496
jason810496 self-requested a review July 16, 2026 13:03
@lohyenshen

Copy link
Copy Markdown

hi, may I know what airflow version would this be released to?

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 5b5ca6c to d65c199CompareJuly 25, 2026 15:24

@vatsrahul1001vatsrahul1001 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

@aeroyorch

aeroyorch commented Aug 2, 2026

Copy link
Copy Markdown
ContributorAuthor

The DBDagBag fix itself looks right, but I don't think it's reachable from the actual config path yet. create_dag_bag() in api_fastapi/common/dagbag.py still does:

if cache_size <= 0:
return DBDagBag(cache_size=0)

That early-return fires whenever dag_cache_size <= 0 and never even reads cache_ttl_config, so setting dag_cache_size = 0 + dag_cache_ttl = 3600 in airflow.cfg still ends up as a plain unbounded dict with no eviction. test_create_dag_bag_cache_modes still asserts exactly that (the "size_zero_unbounded" case expects dict/_use_cache=False for cache_size=0, cache_ttl=3600), and config.yml's dag_cache_size description still says 0 means "unbounded dict, no eviction" with no mention of TTL-only mode.

Could you also update create_dag_bag() to pass cache_ttl through when cache_size<=0, add a case to test_create_dag_bag_cache_modes covering that combo, and touch up the config.yml wording? Otherwise this fix isn't actually reachable by anyone configuring it through airflow.cfg.

Thanks for the review. Changes already implemented :)

@eladkaleladkal added this to the Airflow 3.3.1 milestone Aug 4, 2026
@eladkaleladkal added type:bug-fix Changelog: Bug Fixes backport-to-v3-3-test Backport to v3-3-test labels Aug 4, 2026
@vatsrahul1001

vatsrahul1001 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

LGTM!, can be merged after code owners review

@vatsrahul1001

Copy link
Copy Markdown
Contributor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Moving to 3.3.2 as this is still pending code owner review and do not want to rush on merging this as it not critical

No problem. In the meantime, I can work on some of the other items to fix #69001

Comment threadairflow-core/src/airflow/api_fastapi/common/dagbag.py
Comment threadairflow-core/src/airflow/config_templates/config.yml
Comment threadairflow-core/docs/faq.rst Outdated
@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from c55fa9a to 1a6f6e7CompareAugust 8, 2026 15:17
@aeroyorch
aeroyorch requested a review from kaxilAugust 8, 2026 15:18

@ColtenOuOColtenOuO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

LGTM and Thanks for the improvement! I actually just noticed this issue myself, and was glad to see someone was already working on a fix!

Just a small idea, feel free to take it or leave it if it doesn't quite fit!

Would it make sense to move the warning logs into DBDagBag.__init__ itself? To fully close out #69001, this change will eventually need to be wired up to the Scheduler too , and at that point we'd want to warn users about the exact same negative-value cases again. If the warning lived inside DBDagBag.__init__ from the start, it'd be a lot easier to keep things consistent as more callers get hooked up down the road , one place to maintain, and no risk of some future caller quietly forgetting to warn.

The trade-off is we'd lose the ability to tell the user exactly which config option was the problem (e.g. [api] dag_cache_size vs. a future [scheduler] dag_bag_cache_size)

Thanks for the review!

Fair point, but I'd rather leave it as is for now, the trade-off you mention is the deciding one for me: keeping it at the call site lets us name the actual config option that's wrong, which is what the user needs to fix.

Happy to revisit when the Scheduler part lands for #69001.

@aeroyorch
aeroyorchforce-pushed the dbdagbag-ttl-only-cache branch from 1a6f6e7 to 28a8c01CompareAugust 12, 2026 23:21

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind giving more context as to why we are doing this. If your use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbounded cache there.

@aeroyorch

Copy link
Copy Markdown
ContributorAuthor

Do you mind giving more context as to why we are doing this. If you use case is "LRU evicts my hot dags too aggressively", tweaking the settings for your use case is probably better.

It looks like we are introducing back the memory leak this bounded cache was fixing in the first place. I don't think we should allow unbouded cache there.

Hi Pierre, sure.

I don't think this brings back the leak. Today cache_size=0 is a plain dict with no eviction at all. With this change, cache_size=0 + cache_ttl>0 creates a real TTLCache. That evicts exactly what grows and keeps the hot ones. Defaults don't change.

Tuning the size doesn't really help here: the scheduler cycles through all active dag_version_ids, so any cap below the active set evicts each key just before it's needed again. @kaxil raised this in the #69007 review and @potiuk asked for TTL eviction without a size cap in DBDagBag as a first step.

@pierrejeambrun

pierrejeambrun commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks for the context @aeroyorch this makes more sense. I had the wrong assumption that unbounded cache was just not possible anymore. (at all)

I would be for not allowing unbounded cache completely since we know it's a bad practice, but for backward comp I understand why unbounded is still allowed.

@uranusjr

Copy link
Copy Markdown
Member

This is superceded by #71704

@aeroyorch
aeroyorch deleted the dbdagbag-ttl-only-cache branch August 20, 2026 06:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-3-testBackport to v3-3-testready for maintainer reviewSet after triaging when all criteria pass.type:bug-fixChangelog: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@aeroyorch@lohyenshen@vatsrahul1001@pierrejeambrun@uranusjr@kaxil@ColtenOuO@SameerMesiah97@potiuk@eladkal