Skip to content

feat: share the parent's charge budget with named child runs - #1155

Draft
vdusek wants to merge 5 commits into
feat/child-run-concurrency-limitfrom
feat/child-run-budget
Draft

vdusek wants to merge 5 commits into
feat/child-run-concurrency-limitfrom
feat/child-run-budget

Conversation

@vdusek

@vdusek vdusek commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Stacked on #1154.

When the parent run was started with a max_total_charge_usd, its named child runs share that budget. A named Actor.start or Actor.call reserves a charge limit for its child from the part of the budget the parent hasn't charged or reserved for other children. Without an explicit max_total_charge_usd the child gets all of that part, and a higher value is lowered to it. A start in flight counts as reserved, so parallel starts can't overspend. When the budget is used up, a named start raises a RuntimeError.

The reservations live in the child run registry, so they survive a migration of the parent. ChargingManager subtracts them from the parent's own remaining budget, which keeps the whole tree of runs within the limit. When a child finishes, only its usage_total_usd stays reserved. A failed child that gets replaced keeps its charge counted, and a resurrected child gets a new limit that includes its own earlier reservation. Runs without a name aren't tracked and pass their limit through unchanged.

Two differences from the proposal in the issue, both based on apify-core:

  • The platform gives every pay-per-event run a default limit (999,999,999 USD, capped at the account's remaining monthly usage). Splitting that would make the second parallel child fail, so the budget only applies when the run options say isMaxTotalChargeUsdSetByUser. That flag is read once from the parent run.
  • usageTotalUsd keeps growing for about 3 minutes after a run finishes, so an early read under-reports the charge. The SDK re-reads a finished child until then and only stores the charge as final after that.

Closes #1139

✍️ Drafted by Claude Code

@vdusek vdusek added the t-tooling Issues with this label are in the ownership of the tooling team. label Sep 30, 2026
@vdusek vdusek self-assigned this Sep 30, 2026
@vdusek
vdusek added this pull request to stack #1152 September 30, 2026 17:17
@vdusek vdusek linked an issue Sep 30, 2026 that may be closed by this pull request
@codecov

codecov Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.61905% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.36%. Comparing base (5bbadc2) to head (472ac5d).

Files with missing lines Patch % Lines
src/apify/_child_runs.py 97.97% 2 Missing ⚠️
src/apify/_charging.py 95.23% 1 Missing ⚠️
Additional details and impacted files
@@                         Coverage Diff                          @@
##           feat/child-run-concurrency-limit    #1155      +/-   ##
====================================================================
+ Coverage                             93.29%   93.36%   +0.06%     
====================================================================
  Files                                    54       54              
  Lines                                  3804     3916     +112     
====================================================================
+ Hits                                   3549     3656     +107     
- Misses                                  255      260       +5     
Flag Coverage Δ
e2e 32.78% <31.74%> (-0.08%) ⬇️
integration 51.63% <35.71%> (-0.42%) ⬇️
unit 90.29% <97.61%> (+0.15%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Distribute the parent's maxTotalChargeUsd across child runs

1 participant