When an Actor migrates or is resurrected, the process restarts and every in-flight Actor.call is
lost. Nothing records which child runs were already started, so the restarted Actor starts them all
over again, paying twice and duplicating the work. A user cannot fix this from the outside, because
only the SDK sees the migration.
Proposal
An optional name on Actor.start / Actor.call:
run = await Actor.start('apify/web-scraper', run_input, name='scrape-eu')
With a name, the SDK keeps a name → run ID map in the key-value store and reattaches to the
recorded run after a restart. A new run is started only when nothing is recorded under that name, or
the recorded one ended in a state that cannot be resumed.
Actor.use_state (src/apify/_actor.py:1429) already provides a KVS-backed dict that survives
migration, so the registry can be built on it.
Prior art
apify-orchestrator, which splits this into a tracker and a find-or-start step:
✍️ Drafted by Claude Code
When an Actor migrates or is resurrected, the process restarts and every in-flight
Actor.callislost. Nothing records which child runs were already started, so the restarted Actor starts them all
over again, paying twice and duplicating the work. A user cannot fix this from the outside, because
only the SDK sees the migration.
Proposal
An optional name on
Actor.start/Actor.call:With a
name, the SDK keeps a name → run ID map in the key-value store and reattaches to therecorded run after a restart. A new run is started only when nothing is recorded under that name, or
the recorded one ended in a state that cannot be resumed.
Actor.use_state(src/apify/_actor.py:1429) already provides a KVS-backed dict that survivesmigration, so the registry can be built on it.
Prior art
apify-orchestrator, which splits this into a tracker and a find-or-start step:
✍️ Drafted by Claude Code