ctx.continueAsNew(state) is how a long-running script run lives for weeks without growing without bound. The call finalizes the current run and enqueues a successor that keeps the run's place — same parent, same call site — but starts with a clean journal, carrying only the state the script declared.
The problem it solves
A script's durability comes from its journal: every effect is recorded, and resume replays the source against it. That is exactly right for a task-shaped run and exactly wrong for an infinite loop. A monitor that wakes hourly, checks something, and sleeps again would accumulate journal forever, and every resume would replay an ever-longer history — until it hit the hard cap of 5,000 entries or 8 MiB and failed journal-cap.
continueAsNew cuts the history at a point the script chooses. Everything worth keeping must fit in the declared state — which is a feature, not a limitation: it forces the loop's true carry-over to be explicit and small, instead of implicit in an unbounded replay.
Semantics
The current run finalizes — its journal closes, its record stays complete and inspectable, and obligations are accounted like any ending. Its output carries continuedAsRunId.
The successor is a new run row with a fresh id and continuedFromRunId pointing back. It inherits parent, tool call, agent, session, queue, budget, source, and title verbatim — so a week-long loop reads as one continuing effort rather than a pile of anonymous rows.
Crucially, each generation keeps the same parent rather than nesting under its predecessor. A loop that continued a thousand times is a thousand siblings, not a thousand-deep tree — and a parent parked on that slot never notices the handoff.
The successor's script starts from the top with state as its input and an empty journal. Replay cost and storage stay proportional to one iteration, not to the loop's lifetime.
The call itself never resolves — the VM captures the request and, once nothing else is in flight, the run ends with a continued outcome.
The shape of a day-scale loop
Sleep-check-act loops compose from three primitives, each doing one job: ctx.sleep and ctx.waitForEvent make the waiting free, SignalRun and the event bus end the waits, and continueAsNew keeps the history bounded across iterations.
Related
Time and Parking — the waits inside the loop
Scripts and the Journal — what is being bounded
Do you like what you are reading? Subscribe to receive updates.
Unsubscribe anytime