Cloudflare runs Pi inside a Durable Object, and the meter is wall-clock time

Cloudflare's PiHarness beta runs Pi Durable in a SQLite-backed Durable Object and meters its allocated 128 MB by wall-clock compute duration.

Cloudflare's PiHarness beta runs Pi Durable inside a Durable Object and stores transcripts, inbox messages, and tasks in the object's SQLite database. Its Lifecycle wake-up job hands work to a new alarm every 10 minutes within a 15-minute alarm limit. During a deployment, in-flight work gets up to 30 seconds to finish, while Durable Object billing measures wall-clock compute duration when the object is active or unable to hibernate.

PiHarness stores Pi Durable state in SQLite

Pi runs the agent loop: the transcript, follow-up messages, model calls, tools, retries, and crash recovery. PiHarness supplies the storage and wake-up behavior around that loop. Its tables start with pi_, which keeps Pi's records separate from application tables.

The scheduler itself runs in memory. When a session has work, PiHarness schedules a Lifecycle job. If the object is evicted during the run, the job's alarm starts the object again, Pi reopens its SQLite storage, and the run continues from its last checkpoint.

The Cloudflare Agents SDK example wires the harness into an Agent like this:

import { Agent } from "agents";
import { createModels } from "@earendil-works/pi-ai/models";
import { createRegistry, Harness } from "@earendil-works/pi-durable";
import { PiHarness } from "agents/harness/pi";
import { createAI } from "agents/models/pi-ai";

export class Assistant extends Agent {
  ai = createAI({ binding: this.env.AI });
  registry = createRegistry();

  harness = new PiHarness({
    harness: ({ storage, context }) => {
      const models = createModels();
      models.setProvider(this.ai.provider);
      return Harness.open(
        storage,
        { models, registry: this.registry },
        context,
      );
    },
    defaults: { model: this.ai("@cf/moonshotai/kimi-k2.7-code") },
  });

  constructor(ctx, env) {
    super(ctx, env);
    this.lifecycle.use(this.harness);
  }
}

The same harness can attach to a plain DurableObject with Lifecycle.install(this).use(this.harness). The two Pi packages are optional peer dependencies of agents, and PiHarness requires version 1.0 or later of each.

PiHarness alarm handoff and deployment recovery

The wake-up job waits inside an alarm invocation for long model calls. Cloudflare limits one alarm invocation to 15 minutes. PiHarness hands the job to a new alarm every 10 minutes, but that rollover does not make one model request unlimited. A request that streams for more than 15 minutes can be cut off.

Deployment interruption is a different limit. When a deployment happens mid-run, the runtime gives in-flight work 30 seconds before stopping it. The next alarm restarts the object. Pi keeps a partial answer from an interrupted model stream and makes the model call again. A tool marked replay: "safe" runs again after restart; an unmarked tool returns an interrupted result to the model instead.

Durable Object wall-clock billing

Cloudflare bills Durable Object compute duration by wall-clock time while an object is actively running or is idle in memory but cannot hibernate. On the Workers Paid plan, the included allowance is 400,000 GB-seconds per month, followed by a rate of $12.50 per million GB-seconds. The duration charge uses the 128 MB allocation assigned to the object, regardless of how much memory the code actually uses.

Durable Object hibernation requires all of these conditions: no scheduled timeout, unfinished I/O, waitUntil() promise, outbound connection, standard WebSocket, or request/event still in progress. The pricing documentation also says pending I/O can keep an object in memory for up to 15 minutes and incur duration charges.

For a Pi run, cost depends on whether the model or a tool leaves one of those conditions open. If it does, the object remains non-hibernateable while the work waits. Use this calculation:

wall-clock seconds × 0.125 GB = compute duration in GB-seconds
600 seconds × 0.125 GB = 75 GB-seconds

That 10-minute example is compute duration before the monthly allowance, billing-unit rounding, requests, and storage are applied. A long model call can therefore consume more billable duration than a short request, even when both eventually produce one answer.

PiHarness limits in the beta

Cloudflare's PiHarness documentation lists several boundaries for the beta. Pi Durable has no approval or permission step for tool calls. Event streams start with a snapshot rather than a cursor that can resume from an earlier event. Pi Durable also cannot delete a conversation through the harness API yet.

Cloudflare announced the PiHarness beta on 2026-10-02.

Sources

Last verified: 2026-10-06.

Spotted an outdated or wrong claim? Agents can report it with evidence throughPOST /api/feedback; an editor checks every report. See llms.txt for the agent API.