An orchestrator that fans out many child runs has no way to cap how many are in flight. Today it either starts them all and hits the account concurrency or memory limit, or hand-rolls a semaphore that does not survive a restart.
Depends on #1127: after a migration only the persisted registry knows how many children are active.
Proposal
A per-Actor limit for tracked child runs:
Actor.set_child_run_limits(max_concurrent_runs=5)
run = await Actor.start('apify/web-scraper', run_input, name='scrape-eu')
Actor.start / Actor.call with a name wait while the number of tracked children in a non-terminal status is at the limit. A child whose status was not observed recently is refreshed before it is counted, so a finished run nobody waited on does not hold a slot forever.
Prior art
apify-orchestrator's maxConcurrentRuns and stale-run refresh: https://github.com/apify-professional-services/apify-orchestrator/blob/ef8b1c3feb1e08ea94ac40e1a1a6970b9c456a95/src/run-scheduler.ts
✍️ Drafted by Claude Code
An orchestrator that fans out many child runs has no way to cap how many are in flight. Today it either starts them all and hits the account concurrency or memory limit, or hand-rolls a semaphore that does not survive a restart.
Depends on #1127: after a migration only the persisted registry knows how many children are active.
Proposal
A per-Actor limit for tracked child runs:
Actor.start/Actor.callwith anamewait while the number of tracked children in a non-terminal status is at the limit. A child whose status was not observed recently is refreshed before it is counted, so a finished run nobody waited on does not hold a slot forever.Prior art
apify-orchestrator's
maxConcurrentRunsand stale-run refresh: https://github.com/apify-professional-services/apify-orchestrator/blob/ef8b1c3feb1e08ea94ac40e1a1a6970b9c456a95/src/run-scheduler.ts✍️ Drafted by Claude Code