OpenClaw on Cloudflare Containers
The Worker, the Durable Object, Litestream to R2, and what the always-on bill looks like
The Cloudflare page in the docs is the most unusual of the hosting pages: one OpenClaw installation behind a Cloudflare Worker and a named Durable Object, running the official image in a Cloudflare Container, with Litestream streaming the SQLite databases to an R2 bucket. It is marked experimental, and the warning is precise: Litestream protects SQLite databases, not the complete OpenClaw state directory. Here is how the pieces fit, the deploy sequence, the verification the docs insist on, the cost model, and the limits.
How it fits together
- The Worker forwards every HTTP and WebSocket request to one stable Durable Object name; that object owns one Container instance and is the single-writer fence around the Litestream replica.
- The Container exposes the Gateway on port 8080 and the Durable Object polls the health endpoint before routing to it; the template deploys a standard-2 Container with a single instance.
- Litestream watches the state and agent SQLite roots and streams their write-ahead logs to R2; at boot the entrypoint lists the bucket as its restore manifest, rejects paths outside those roots, restores each database, and only then starts the Gateway.
- Measured on the template: about 2.4 seconds from write to replica, about 9 seconds to restore both databases, and a healthy Gateway roughly 13 seconds after start, all order-of-magnitude figures rather than guarantees.
Rehearse recovery before you need it. An untested restore path is not a backup.
Deploying it
The sequence is: clone the template, log in with Wrangler and confirm the account, create the R2 bucket and an R2 API token limited to it, build a derived image from an immutable digest of the official image for linux/amd64 and push it to a public Docker Hub repository, since Cloudflare pulls public Docker Hub images and GHCR is not supported, then deploy the Worker. Secrets go in through Wrangler: the two Litestream keys, the Gateway token, then provider and channel variables, each of which must also appear in the Container’s explicit environment allowlist. First boot needs one interactive session: enable SSH temporarily in the configuration, redeploy, connect through Wrangler, run the non-interactive onboarding with secret references and token auth, add a channel from the environment, run the doctor, and keep that recipe in a private runbook, because a fresh Container disk does not retain the generated config.
Verify, then the bill
- The health endpoint says the listener is up, the readiness endpoint needs the bearer token, and the startup endpoint reports finished startup while ignoring channel health; it exists on images from v2026.8.1 onward.
- Replication is proven by listing the replicas prefix in the bucket with an S3-compatible client, since Wrangler cannot list keys; an empty prefix after minutes of activity means it is not working. Then rehearse recovery: send a message, wait about ten seconds, delete the instance, reopen the Worker URL, and confirm the conversation is still there.
- Containers need the Workers Paid plan and bill memory and disk on provisioned resources while awake: the default instance provisions 1 vCPU, 6 GiB of memory and 12 GB of disk, and always-on for a month is roughly 40 to 50 US dollars, mostly memory. Socket channels such as Discord, Slack Socket Mode and WhatsApp keep the Container awake; webhook-only installs can sleep and bill nothing, which is the one case where this target is genuinely cheap.
OpenClaw backup and restore covers the full archives the docs point at for everything Litestream does not protect, and OpenClaw secrets the reference-based setup the bootstrap uses.
The limits
Single writer, so never raise the instance count or route around the Durable Object. A seconds-scale recovery point, since the one-second sync interval is not synchronous replication. An ephemeral disk, so config, credential files, plugins and workspaces come back only from a full archive, and scale-to-zero, enabled only when every channel is webhook-based, starts with a fresh disk after ten idle minutes. Rollback is time travel: restoring older bytes can desynchronise ratcheting channel credentials, WhatsApp especially, and rolls back approvals and delivery state. WebSocket messages are capped at 32 MiB, there is no fixed egress address, and this is a deployment template, not a cloud workers provider. OpenClaw on Fly.io and OpenClaw on Docker are the conventional routes when those limits matter.
On Diali
Diali keeps the state directory on a persistent volume, and the Backups add-on (included on Max) takes daily snapshots with one-click restore, so the SQLite-only recovery question never comes up. Hosted OpenClaw on Diali is the assistant and What OpenClaw costs sets our plans beside an always-on container.
- One Worker, one Durable Object, one Container, one writer.
- Litestream restores SQLite and nothing else.
- Sockets keep it awake; webhooks let it sleep.
Stop reading about it, build one
Set up an agent, pick a channel, and have it working inside the app you already keep open.
