Pi has added a way for a waiting agent task to outlive the process that started it. A change committed to earendil-works/pi late October 17 UTC—early October 18 in Paris—gives its durable harness a stored sleeping state. The task saves when to return and which step to run next, then ends its current invocation. A host such as a Cloudflare Durable Object can supply the alarm that brings it back.
That matters for applications whose agents spend time between actions: waiting before another model request, polling a deferred response, or delaying a reminder. The work can remain unfinished while the process that was doing it disappears. Pi supplies the saved task state; the application and its host supply the wakeup.
This is an implementation on the development branch, not a newly released Pi CLI feature. The inspected changelog places it under Unreleased, after the October 15 v1.3.0 release. The durable library explicitly labels its API experimental.
The wait becomes a record
Before this change, a task could call runtime.sleep() and wait inside a running step. The new contract asks the author to divide the work at the pause. Save a deadline and a checkpoint describing the next step; return; let the scheduler run that step when it is due.
A reminder makes the distinction concrete. Its first step records “deliver this message at this time.” Once that record is stored, the step is finished. A later invocation reads the saved task and performs delivery. The original invocation is no longer the container holding the wait together.
Pi’s built-in generation retries, deferred-response polls and compaction retries use the same new state. But their deadlines were not all previously lost on restart. The earlier generation code already saved retry and polling times in checkpoints. The advance is ending the live invocation during that interval and exposing when the host needs to run again. It makes waiting explicit in the task’s lifecycle.
The distinction also keeps the claim honest. An external action performed before the sleep record is committed can run again if the process crashes in between. Saving a wait does not make every surrounding action happen exactly once.
Storage remembers; the host wakes
Cloudflare’s part already existed. Its Durable Object alarms schedule a future invocation, with at-least-once execution. Pi had added a Durable Object SQLite adapter in v1.1.0 on October 7. October 18’s finding is how Pi now hands sleeping agent work to that established hosting machinery.
The harness reports two useful facts through wake() and onWake: whether work can run now, and the earliest sleeping deadline. With that callback configured, Pi does not keep its own sleep timer. The host arms an alarm and calls resume() when it fires. Without this integration, the default Node.js timer deliberately keeps the process alive while a task sleeps.
The host’s responsibility is more than setting a clock after the fact. The completed example arms recovery before resuming work, as well as before admitting new input. Otherwise a process could commit work and disappear before arranging any way to return. While work is active, the example uses a recovery heartbeat; while it sleeps, the saved deadline determines the next wakeup.
This is a useful division of labor for an application builder. The task describes what remains to do, and the host decides how execution returns. It does not mean all Pi sessions now hibernate automatically.
A test that removes the process
The accompanying workerd tests go beyond checking the shape of a saved record. One stores a sleeping task, explicitly evicts its Durable Object, reopens it and checks that the deadline and alarm remain. It then advances the test clock, evicts the object again and invokes the alarm. The expected outcome is a completed task and no remaining alarm.
A second case interrupts a scripted model stream and checks recovery through the heartbeat. The integration work also exposed an awkward host detail: compatibility-mode timers had an unref() method, yet pending idle-memory timers still prevented eviction. Pi now declines those housekeeping timers in Workers.
These are inspectable tests of the mechanism. We read their implementation but did not execute the suites. They use a scripted model and a manually advanced clock; they do not establish production Cloudflare timing, real-model task completion or a lower bill.
The upgrade includes the stored task
Moving the wait into storage changes what an upgrade must preserve. Pi’s SQLite migration rebuilds the task table to admit the new state. Once opened by this code, that database cannot be reopened by v1.3.0 or earlier. JSONL storage needs no structural migration, but the older runtime does not resume an unfamiliar sleeping task, leaving its conversation busy.
For integrators, this is a host-and-storage change to rehearse on a copy, rather than a timer name to replace in isolation. A containing release and a pinned deployment should be tested with one real delayed task: preserve its original deadline across eviction, observe the resumed result, and make its external action safe to retry.
The useful gain is already visible in the source. Continuing an agent’s work no longer has to mean keeping its current invocation alive through every pause. The next demonstration should show that handoff working outside the test clock, with the host, saved state and external action all keeping the same promise.