Worker Previews treat each Git branch the way Git treats code: as its own copy. Every branch gets an isolated environment and URL, with its own code, configuration, URL, observability, and state, running inside the same Worker. You can run hundreds of Previews at once — each operating independently without affecting other Previews or production.
Running npx wrangler preview gives the branch its own copy of your Previews configuration on its own URL. In the dashboard, switching between environments works like switching branches: click the breadcrumb next to the Worker's name (it defaults to Production) to see all Previews. Unlike Wrangler environments, where every environment requires deploying and managing a separate Worker, Previews keep their isolation in one dashboard view; production sits alongside as many Previews as you need, so contributors don't fight over a shared staging site.
Each Preview runs as a real version of your Worker, which matters because some changes can only be validated at runtime — an API endpoint has to handle a real request and return the right response, while a UI update, a new onboarding step, or a different error state has to be experienced in context before it reaches production.
Stateful resources
Stateful resources need special handling for isolation to extend across the application, because Durable Objects run on a singleton model: one instance is responsible for a given object ID, and that instance owns its storage. Sharing a namespace with production wouldn't only mean reading stale data — a Preview could modify the same instance serving live traffic.
Every time you run npx wrangler preview, Cloudflare automatically creates a new Durable Object namespace and Container application for that Preview, so a failed migration or bad schema change stays contained to that branch. You export the class, add its migration, and access it through ctx.exports:
export class Counter extends DurableObject {}
export default {
async fetch(request, env, ctx) {
const id = ctx.exports.Counter.idFromName("demo");
const counter = ctx.exports.Counter.get(id);
return counter.fetch(request);
},
};
In production ctx.exports.Counter resolves to the production namespace; in a Preview it resolves to that Preview's namespace. That isolation opens up parallel experimentation — for something like Sandboxes, where milliseconds of startup time make or break the experience, you can run different cold-start configurations across branches at the same time and compare cold and warm performance side by side.
Testing and observation per Preview
With each branch on its own URL and its own state, traffic can reach the Preview however you normally send it: from your terminal, probed from CI, from an agent, or by clicking through it yourself. Once traffic flows, every Workers Observability tool is available scoped to that Preview. Each request's full lifecycle is traced in a waterfall covering fetch calls, binding operations, and handler invocations, so a failure can be followed without sorting through production traffic or signals from other changes. Select the Preview from the breadcrumb and open the Observability tab to see its events, errors, and traces.
Agents can be given more control with Browser Run: open the Preview URL in a headless browser, click through a login flow step by step, and capture a screenshot or record the session as replayable DOM events. A reviewer can watch in real time with Live View or step in via Human in the Loop when automation needs judgment. From both angles — what rendered and what happened at runtime — there is enough evidence to keep the loop running autonomously: deploy, open the URL with Playwright MCP, click through, query traces through the Workers Observability MCP server, patch, redeploy, and verify, all scoped to the branch.
Base configuration and overrides
You set the base configuration for Previews once, in a previews block in your Wrangler configuration file.
{
"vars": {
"ENVIRONMENT": "production"
},
"r2_buckets": [
{
"binding": "UPLOADS",
"bucket_name": "prod-uploads"
}
],
"previews": {
"vars": {
"ENVIRONMENT": "preview"
},
"r2_buckets": [
{
"binding": "UPLOADS",
"bucket_name": "r2-staging"
}
]
}
}
The dashboard shows this inlined under Worker → Settings as Production and Previews Base. Once the base is set, running npx wrangler preview from any branch creates a Preview; if the Worker is Git-connected through Workers Builds, it happens automatically on push. Any setting can be overridden for a single Preview — pointing it at its own database or test API key for migrations, for example — without touching production, the base, or other Previews.
Custom domains and access control
Preview URLs can be served from your own custom domain, so an app on example.com could run a Preview for a login branch at feature-login.previews.example.com. Auth providers, cookies, cross-origin resource sharing, and OAuth redirects then behave the way they will in production. Private previews can require visitors to sign in first by protecting them with Cloudflare Access.
Validation before merge
The result is a pre-production feedback loop for every branch: push a change, test behavior, inspect performance before merging. Each change becomes atomic, independently deployable, observable, and revisable, giving agents and humans the evidence to self-improve — catch what failed, push a fix, verify the next deployment before production sees it.
Cloudflare has been dogfooding Worker Previews internally, most notably to build and test CloudflareOS, the open-source platform for safely connecting agents to company systems. CloudflareOS lets agents work with services such as Google, GitHub, and Slack through Gatekeepers, which control what agents can access and change — making Gatekeeper changes especially sensitive, since a bug could expose data or permit an action that should never have been allowed.
Some of those bugs only appear when OAuth callbacks, permissions, approval flows, and application state run together, and testing components separately cannot show how the complete system behaves. So Cloudflare deploys an isolated Preview of CloudflareOS and its Gatekeepers for every change under review, runs the full workflow, fixes what fails, and tests again before merging. Customers report the same motivation: some problems only show themselves when the change is actually running.
"At Supermemory, we use Cloudflare heavily, and Worker Previews are exactly the kind of developer experience improvement we wanted to see. For HTTP flows, we can preview Worker changes before they reach production, including routes backed by Durable Objects, and catch issues earlier without slowing down shipping." — Dhravya Shah, Founder, Supermemory
"Previews is amazing for Inspect [Ramp's coding agent]. I used it to review and test an Inspect PR on my phone that is making reviewing and testing PRs with Inspect on phones responsive…with Inspect." — Dylan Garcia, Senior Staff Engineer, Ramp
Relationship to existing preview URLs
Version URLs pointed at specific uploaded Worker versions. They did not stand up an isolated environment per branch, and they could only reference production resources. Worker Previews replaces that model with per-change environments.
Roadmap
The launch is the starting point, not the end state. Three areas are in active development:
- Multi-Worker previews. A service binding originating from a Preview currently reaches the bound Worker's production deployment. The goal is to keep the full request path within Previews that match each other.
- Asynchronous work scoped to the branch. Previews can write to Queues but cannot consume from them today, and isolating Workflow executions needs separate configuration. The intent is for the complete asynchronous flow to be scoped to its branch automatically.
- Long-lived Previews. Private beta feedback indicates that not all branches are short-lived: some teams keep staging, QA, or per-developer environments alive across sprints. Support for these end-to-end is planned, and the team is soliciting usage details to shape it.
Availability and feedback
Worker Previews are generally available now, with getting-started documentation published. Feature requests and bug reports go to the workers-sdk GitHub issue tracker, and discussion happens in the Cloudflare Developers Discord.
Acknowledgements: This project was made possible by the design and implementation efforts of Greg Brimble, Patrick O'Donnell, Matt Price, Korinne Alpers, Max Peterson, Cina Saffary, Josh Wheeler, Thomas Ankcorn, Matt Rothenberg, and Brandon Strittmatter, with leadership from Brendan Irvine-Broque and Dan Carter.



