Pi Durable on Cloudflare Pi Durable, a harness for long-running AI agents from Earendil, can be paired with Cloudflare Durable Objects to store each chat session in its own SQLite-backed object that hibernates when idle and wakes on requests, WebSocket messages, or alarms. The post walks through building a multiplayer chat agent where a Worker routes clients by session ID to a Durable Object running the Pi Durable harness, with conversations and tasks in embedded SQLite and a subagent searching across conversations. Pi Durable ships a runtime-neutral asynchronous database interface with Node.js and Cloudflare Durable Objects adapters, plus a conformance suite compatible with Vitest or Jest test runners. Many AI agents respond to user requests or other external events, do their work and then sit idle for long periods. Keeping a machine running around the clock wastes compute and quickly gets expensive. Pi Durable is a harness designed for long-running agents. Read the announcement https://earendil.com/posts/pi-durable/ explaining its concepts and storage model in detail. And Cloudflare Durable Objects offer a stateful objects that shut down when idle and start up again when a request, WebSocket message, or alarm arrives. In this post we will build a chat agent that stores every session in its own Durable Object, manages multiple conversations per session, survives hibernation, wakes up for scheduled work, and uses a subagent to search across conversations. We’ll run with 90s vibes for the interface but make it multiplayer because it’s 2026: multiple participants connected to the same chat session. A Pi Durable harness is scoped to one session. That maps naturally to one Durable Object instance addressed by the session ID. Its SQLite-backed storage persists session data, the Durable Object can hibernate while idle, and its alarm can wake it for pending work. React client │ PartySocket ▼ Worker │ route by session ID ▼ SQLite-backed Durable Object instance ├── Hibernatable WebSockets ├── embedded SQLite database │ └── conversations and tasks └── Pi Durable Harness ──▶ Model provider The Worker creates a session ID and returns a shareable URL that clients connect to over WebSockets. Everyone who opens the same session URL reaches the same object. Different session IDs address different objects with isolated state. Pi Durable makes no assumption about where sessions are stored. You can bring your own storage backend if the built-in memory, JSONL or SQLite support is not exactly what you need. The SQLite implementation defines a runtime-neutral, asynchronous database interface and includes an adapter for Node.js, as well as an adapter for Cloudflare Durable Objects using the synchronous storage SqlStorage API through ctx.storage.sql . await openDurableObjectSqliteStorage ctx.storage If your requires rolling your own SQLite adapter or a different storage backend, use Pi Durable’s conformance suite to check that it behaves correctly. It works with any Vitest- or Jest-compatible test runner. For a Durable Object, use it with the Cloudflare Workers Vitest integration https://developers.cloudflare.com/workers/testing/vitest-integration/ : registerStorageConformance { describe, expect, it }, "Cloudflare Durable Object SQLite", async use = { const stub = env.SESSIONS.get env.SESSIONS.newUniqueId ; await runInDurableObject stub, async instance, state = { await use await openDurableObjectSqliteStorage state.storage ; } ; }, ; The harness gets initialized with the Session Durable Object. Cloudflare runs the constructor every time the object starts: when it gets first created, and again after hibernation or eviction when a request, alarm, or WebSocket message arrives. All events are held back until the initialization is complete. export class Session extends DurableObject