Creuto is now an OpenAI Select Partner Read More
Cloudflare Worker Previews give every branch its own URL, Durable Objects and traces. D1, R2 and KV stay shared until you split them. Limits and clean-up.

Cloudflare Worker Previews hand every Git branch its own Durable Object namespace automatically. They hand every branch the same D1 database, the same R2 bucket and the same KV namespace unless you say otherwise. Knowing which half of your stack is isolated is the difference between a preview environment you can trust and one that quietly writes to production data.
Cloudflare launched Worker Previews on 22 September 2026 with a specific argument: agents are pushing more lines of code than before, so more ground has to be tested before release. The mechanic is one command. Run npx wrangler preview on a branch and that branch gets a production-like place to run, with its own code, configuration, URL, observability and state.
A Preview is not a separate Worker. It lives under the same Worker as production, and the dashboard treats moving between them like switching branches. Cloudflare's docs frame the workflow as a pair: npx wrangler deploy for main and npx wrangler preview for a branch. You need Wrangler 4.135.0 or later, installed as a project dependency — a newer global install is not used by project commands.
Each Preview gets two kinds of URL. The Preview URL always serves the latest deployment on that branch, so it is the link you share with reviewers. The Deployment URL points at one specific deploy and never changes, so it is the link you paste into a pull request when a reviewer needs to see exactly what you saw.
The custom domain is the part teams underrate. Cloudflare's launch post makes the case directly: serving Preview URLs from your own domain is what makes auth providers, cookies, cross-origin resource sharing and OAuth redirects behave the way they will in production. A preview that cannot complete your login flow is a preview your team stops opening. Those URLs are public by default, so put Cloudflare Access in front of any branch carrying an unreleased feature.
Read this twice before you promise anyone an isolated environment. Cloudflare automatically provisions a new Durable Object namespace and storage, plus a new container app and container instances, for each Preview. Everything else is isolated only if you bind it to a different resource. The resources and isolation reference states the rule plainly: two Previews bound to the same account-level resource ID or name share its data or instances.
| Resource | Isolated per Preview? | What you have to do |
|---|---|---|
| Durable Objects | Yes, automatic | Export the class and add the migration |
| Containers | Yes, automatic | Declare the container under previews.containers |
| KV, D1, R2 | No | Bind to a different namespace, database or bucket |
| Queue producers | No | Bind to a different queue |
| Hyperdrive | No | Point a separate config at a separate database or schema |
| Workflows | No | Deploy a dedicated non-production Workflow and bind to it |
Durable Object state persists across deployments within one Preview and is deleted when the Preview is deleted. A failed migration stays on the branch that caused it instead of reaching the instance serving live traffic.
Three edges deserve naming before you write the CI job. Service bindings from a Preview call the bound Worker's production deployment; if you need same-Worker calls to stay inside the Preview, the docs point you at ctx.exports instead. A Preview can produce messages to a Queue but cannot consume them, because a Queue has one consumer Worker — so messages a Preview sends to a production Queue can be consumed by production. Cron Triggers and zone routes target production, and a Preview's scheduled() handler is not called at all.
There is one configuration failure worth memorising. Previews do not inherit production settings; they read the previews block of the Wrangler file on the current branch. If your code reads a binding from env and you did not declare it under previews, the binding will not exist in the Preview and the Worker can return a 1101 error. The URL is live. The runtime configuration is not.
The documented limits are per Worker: 100 Previews on the free plan, 500 on paid plans, and 100 deployments per Preview on either. When a limit is reached Cloudflare deletes the oldest to make room — the Preview deployed to least recently, or the oldest deployment inside that Preview. A long-running QA branch you have not redeployed in a month is exactly the Preview that gets evicted first.
On price, assume nothing. As of 23 September 2026 the Previews documentation publishes those limits and no separate charge for a Preview, and the Workers pricing page does not mention Previews. What you should budget for is the resources you attach: a second D1 database, a staging R2 bucket, a container image built per Preview. That is the same discipline we bring to any serverless architecture engagement — the compute is rarely the line item that surprises anyone.
Clean-up is where preview environments rot, and Cloudflare has left one piece to you. Deleting a Preview with npx wrangler preview delete --name <preview-name> removes its record and its Durable Object namespace, but the generated container app can remain visible in npx wrangler containers list. The docs tell you to check for leftovers after deletion and remove them by application ID — and explicitly warn against deleting container apps by Worker name alone, because the production app for the same Worker carries a similar name without the Preview segment.
Wire the delete into the same workflow that creates the Preview. Cloudflare's GitHub Actions example comments the Preview URL on the pull request, probes a health route with curl --fail, and runs the delete job on the closed event. Fold it into the rest of your CI/CD implementation rather than bolting it on. Teams that skip the cleanup job meet the same class of surprise as deployment retention rules on other platforms: a quota nobody read, enforced at the worst moment.
It did, and that is the strongest objection to treating this launch as new. Cloudflare has renamed the old preview URLs to Version URLs and now tells you not to use them for branch testing: a Version URL runs one uploaded version against production resources and creates no isolated branch resources. Two further limits matter — Version URLs are not generated for Workers that implement a Durable Object, and you cannot view their logs with Workers Logs, wrangler tail or Logpush. Cloudflare's comparison page recommends migrating aliased Version URLs to npx wrangler preview --name staging.
Here is the sentence to take into your next planning session. If the risk in a change lives in HTTP handling, Durable Object state or a container, a Preview is genuinely close to production and you should use one. If the risk lives in a queue consumer, a cron job, or a call to another Worker over a service binding, a Preview exercises none of it — the consumer is still production's, the schedule never fires, and the service binding resolves to the production deployment. Cloudflare lists all three as work in progress in the launch post.
Observability is the real change for teams whose agents open most of the pull requests. Every Workers Observability tool is scoped to the individual Preview, so a failed request traces as a waterfall of fetch calls, binding operations and handler invocations for that branch alone. That is what turns a URL into a loop an agent can close by itself: deploy, drive the URL, read the traces, patch, redeploy, verify.
In the systems we build, the constraint has rarely been the preview URL — it has been the data behind it. Before you enable this for a team, decide three things: which branches get their own D1 database and which share a staging one, who owns the Access policy on Preview hostnames, and what deletes a Preview when nobody closes the pull request. Get those wrong and you have a second production environment with none of the guardrails — the failure mode behind several of the Workers production issues worth learning early.
Start with one Worker whose state is Durable Objects and HTTP handlers only. That is the case Previews handle end to end today, and it is the one where you will find out within a week whether per-branch environments change how your reviews actually go.
Cloudflare Worker Previews are per-branch environments that live under the same Worker as production. Running npx wrangler preview creates or updates a Preview for the current branch with its own variables, secrets, bindings, URL, observability and Durable Object state, so you can test a change before it is merged.
Only partly. Cloudflare automatically provisions a new Durable Object namespace and container app for each Preview. KV, D1, R2, Queues, Hyperdrive and Workflows are isolated only when you bind that Preview to a different resource, because two Previews sharing a resource ID share its data.
Run npx wrangler preview on your branch with Wrangler 4.135.0 or later, then send traffic to the Preview URL from your terminal, CI, a browser or an agent. Workers Observability scopes events, errors and traces to that Preview, so failures are not mixed with production traffic.
Cloudflare documents 100 Previews per Worker on the free plan and 500 on paid plans, with 100 deployments per Preview on both. When a limit is reached, Cloudflare deletes the least recently deployed Preview, or the oldest deployment inside that Preview, to make room.
Run npx wrangler preview delete --name --skip-confirmation from a job triggered on the pull request closed event. Deleting a Preview removes its Durable Object namespace, but check npx wrangler containers list afterwards and delete any leftover container app by its application ID.
A Version URL, previously called a preview URL, runs one uploaded Worker version against production resources and creates no isolated branch resources. Cloudflare now recommends Previews for branch and pull request testing, and notes Version URLs are not generated for Workers that implement a Durable Object.
Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.
11th Floor, O-Hub, Chandaka Industrial Estate, Infocity, Bhubaneswar, Odisha 751024
Level 4, 11 York Street Sydney Startup Hub Sydney, NSW – 2000
30 N. Đinh Nghệ, Phước Mỹ Sơn Trà, Đà Nẵng / Da Nang City – 550000
Level 25, AIDP Business Tower, Dubai Marina, United Arab Emirates
50 Beauchamp Street, Wellington, WGN 5028, New Zealand