---
title: "Hosting a static site for free on Cloudflare: Workers or Pages?"
description: "A comparison of hosting a static site on Cloudflare Workers and Pages on the free plans, covering trade-offs, room to grow, and how to choose."
lang: en
published: 2026-11-04
tags: ["cloudflare", "architecture"]
canonical: https://note.xavierchang.dev/en/posts/2026-11-04-workers-vs-pages/
translation: https://note.xavierchang.dev/zh/posts/2026-11-04-workers-vs-pages/index.md
author: Xavier
---

# Hosting a static site for free on Cloudflare: Workers or Pages?

> A comparison of hosting a static site on Cloudflare Workers and Pages on the free plans, covering trade-offs, room to grow, and how to choose.

Putting a front-end static site on Cloudflare without paying leaves two options: Pages, and Workers with Static Assets. This note assumes the free plans and compares the two on quotas, trade-offs, and what changes once server-side code, a database or a paid plan comes in, then ends with conditions that can be checked directly.

Limits and prices are as of November 2026 per the official docs.

## The scenario

The build produces a folder (for example `dist/`) that holds only HTML, CSS, JavaScript and images, with no code that has to run on a server. The goal: deploy automatically on every Git push, use a custom domain, and pay nothing each month.

Both products can do this. They differ in how quotas are counted, how previews are set up, what the domain has to be, and how much room there is once the site grows.

## What each one is

### Cloudflare Pages

[Pages](https://developers.cloudflare.com/pages/) is Cloudflare's dedicated site hosting product. The usual setup is to connect a GitHub or GitLab repo in the dashboard, set a build command and an output folder, and from then on every push builds and deploys automatically ([Git integration](https://developers.cloudflare.com/pages/configuration/git-integration/)). Every deployment gets its own `<hash>.<project>.pages.dev` URL, and every branch gets a `<branch>.<project>.pages.dev` alias, with no extra setup; branch aliases are lowercased and non-alphanumeric characters become hyphens, so `fix/api` becomes `fix-api` ([Preview deployments](https://developers.cloudflare.com/pages/configuration/preview-deployments/)).

Without Git, [Direct Upload](https://developers.cloudflare.com/pages/get-started/direct-upload/) works too: drag and drop up to 1,000 files in the dashboard, or upload up to 20,000 files with Wrangler[^wrangler], each file up to 25 MiB. For server-side code, Pages Functions go in a `/functions` folder, and the file names decide the routes; for example, `/functions/fruits/apple.js` serves `/fruits/apple` ([Functions routing](https://developers.cloudflare.com/pages/functions/routing/)).

### Workers with Static Assets

Workers runs code on Cloudflare's edge. [Static Assets](https://developers.cloudflare.com/workers/static-assets/) lets static files be uploaded and deployed together with a Worker.

> [!DEFINITION] Workers Static Assets
> When a request path matches a static file, that file is returned without running any Worker code. When no file matches and there is no Worker code, the response is a 404. With no `main` (the Worker code entry point) in the config, the whole site is static files only; the official [static site example](https://developers.cloudflare.com/workers/static-assets/routing/static-site-generation/) config has no `main` either.

Git deploys are handled by [Workers Builds](https://developers.cloudflare.com/workers/ci-cd/builds/): connect the repo and set a build command; the deploy command defaults to `npx wrangler deploy` ([Builds configuration](https://developers.cloudflare.com/workers/ci-cd/builds/configuration/)), and every push to the production branch builds and deploys[^builds-token]. Workers Builds connects to Artifacts, GitHub, GitLab and Cursor Origin repos, and does not support self-hosted GitHub or GitLab; other providers (such as Bitbucket) can use an external CI/CD service (such as GitHub Actions) that deploys with Wrangler ([Workers Builds Git integration](https://developers.cloudflare.com/workers/ci-cd/builds/git-integration/)).

A purely static site on Workers needs only one config file:

```jsonc title="wrangler.jsonc"
{
  "name": "my-site",
  "compatibility_date": "2026-11-04",
  // No "main": no Worker code runs, static files answer every request
  "assets": {
    "directory": "./dist",
    // When a path is not found, return the nearest 404.html with status 404
    "not_found_handling": "404-page"
  }
}
```

`not_found_handling` accepts `"single-page-application"`, `"404-page"` or `"none"`, and the default is `"none"` ([Wrangler configuration](https://developers.cloudflare.com/workers/wrangler/configuration/)). Coming from Pages, the main change is how the output folder is declared. Pages detects the 404 and single-page application (SPA) behavior by itself, while Workers needs it spelled out ([migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/)):

```diff title="wrangler.jsonc"
 {
   "name": "my-site",
   "compatibility_date": "2026-11-04",
-  "pages_build_output_dir": "./dist"
+  "assets": {
+    "directory": "./dist",
+    "not_found_handling": "404-page"
+  }
 }
```

The two deploy flows look roughly like this:

```diagram
lanes: Pages | Workers + Static Assets
Pages: git push (GitHub / GitLab) -> Pages build (500 builds / month on the free plan) -> pages.dev and custom domains (a subdomain can stay on external DNS)
Workers + Static Assets: git push (4 Git providers) -> Workers Builds (3,000 minutes / month on the free plan) -> workers.dev and custom domains (the domain must be on Cloudflare)
merge: Static asset requests (free and unlimited on both)
caption: Deploy flows on Pages and Workers. Static asset requests are free on both; requests that run Functions or Worker code count toward the daily quota.
```

The `_headers` file has the same format on both: it has to end up at the root of the output folder (for example `dist/`); with a framework it usually goes in `public/`, which the build copies there. In the file, a path goes on the first line and the headers indented below it, with up to 100 rules at up to 2,000 characters per line. It applies only to static asset responses; responses generated by Pages Functions or Worker code need their headers set in that code ([Workers headers](https://developers.cloudflare.com/workers/static-assets/headers/), [Pages headers](https://developers.cloudflare.com/pages/configuration/headers/)).

```text title="public/_headers"
/*
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin

/assets/*
  Cache-Control: public, max-age=31536000, immutable
```

Replace `/assets/*` in the example with the folder where the framework actually writes hashed file names.

## Free plan comparison table

| Item (free plan) | Pages | Workers + Static Assets |
| :--- | :--- | :--- |
| Static asset requests | Free, unlimited | Free, unlimited |
| Requests that run server-side code | Pages Functions count toward the Workers Free daily quota | 100,000 per day, shared across the account (and with Pages Functions) |
| Files | 20,000 per site | 20,000 per Worker version |
| Size of one file | 25 MiB | 25 MiB |
| Build allowance | 500 builds per month | Workers Builds: 3,000 minutes per month |
| Concurrent builds | 1 per account | 1 per account |
| Build timeout | 20 minutes | 20 minutes |
| Per account | 100 projects | 100 Workers |
| Custom domains | 100 per project; a subdomain can stay on external DNS (CNAME), an apex domain must be a Cloudflare zone | The domain must be a Cloudflare zone; 100 per zone (counted per zone, not per project) |
| Previews | Created automatically for every deployment and branch, unlimited | Worker Previews, 100 per Worker, needs setup |
| Cron Triggers | Not supported | 5 per account |
| Logs | Real-time logs | Real-time logs, Workers Logs (200,000 events per day, kept 3 days) |

Sources for the numbers: [Pages limits](https://developers.cloudflare.com/pages/platform/limits/), [Pages custom domains](https://developers.cloudflare.com/pages/configuration/custom-domains/), [Pages Functions pricing](https://developers.cloudflare.com/pages/functions/pricing/), [Workers limits](https://developers.cloudflare.com/workers/platform/limits/), [Workers Builds limits](https://developers.cloudflare.com/workers/ci-cd/builds/limits-and-pricing/), [Worker Previews](https://developers.cloudflare.com/workers/previews/), [Workers custom domains](https://developers.cloudflare.com/workers/configuration/routing/custom-domains/) and [Workers pricing](https://developers.cloudflare.com/workers/platform/pricing/). Feature support comes from the [migration guide's matrix](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/).

> [!NOTE] Static asset requests are not billed
> Both sets of docs call static asset requests "free and unlimited" ([Pages Functions pricing](https://developers.cloudflare.com/pages/functions/pricing/), [Workers pricing](https://developers.cloudflare.com/workers/platform/pricing/), [Static Assets billing and limitations](https://developers.cloudflare.com/workers/static-assets/billing-and-limitations/)). No official page says word for word that requests served only by static files are left out of the 100,000 per day, but the Pages docs define a static request as one that does not invoke Functions, and the Workers docs say only requests that run Worker code are billed. A purely static site therefore normally never reaches the daily quota.

## Trade-offs and room to grow

Everything below assumes the free plans; the quota numbers are in the comparison table above.

### Pages

- **Advantages**: preview URLs for branches and for every deployment are created automatically, with no config to write; a folder can be dragged into the dashboard and go live; when the site lives on a subdomain (such as `www.example.com`), the domain's DNS can stay with another provider and point to Pages with a CNAME, while an apex domain (such as `example.com`) still has to be added as a Cloudflare zone with its nameservers moved to Cloudflare ([Pages custom domains](https://developers.cloudflare.com/pages/configuration/custom-domains/))[^cname-order]; in the [migration guide's matrix](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/), external domains are the only feature that Pages supports and Workers does not, and four more (Early Hints, Branch Deploy Controls, file-based routing, Pages Plugins) are only partially supported on Workers; 404 and SPA behavior are detected automatically; dashboard users are unlimited ([Pages limits](https://developers.cloudflare.com/pages/platform/limits/)).
- **Disadvantages**: the build allowance is counted per build, so every push counts once however short the build is; [Git integration](https://developers.cloudflare.com/pages/configuration/git-integration/) supports only GitHub and GitLab, not self-hosted instances, and other providers use Direct Upload from CI; projects created with Git integration and with Direct Upload cannot be switched to the other later ([Direct Upload](https://developers.cloudflare.com/pages/get-started/direct-upload/), [Git integration](https://developers.cloudflare.com/pages/configuration/git-integration/)), though a Git-integrated project can pause automatic deployments with branch control and deploy directly with Wrangler instead ([Git integration](https://developers.cloudflare.com/pages/configuration/git-integration/)); preview URLs are public by default; "Enable access policy" limits them to members of the Cloudflare account by default, and Access policies can add other people. It covers previews only; the `*.pages.dev` production URL and custom domains need separate, manual Access setup per the docs' Known issues[^pages-access]; the [official docs recommend Workers for new projects](https://developers.cloudflare.com/workers/best-practices/workers-best-practices/), and Cloudflare has said on its [blog](https://blog.cloudflare.com/full-stack-development-on-cloudflare-workers) that future investment, optimizations and new features go to Workers.
- **As needs grow**: for an API or form handling, add Pages Functions under `/functions`. Their requests count toward the Workers Free daily quota and are billed the same way as Workers ([Pages Functions pricing](https://developers.cloudflare.com/pages/functions/pricing/)). For a database, bindings such as D1 and KV are available, but a Durable Object cannot be created inside a Pages project; it has to be deployed as a separate Worker and bound in ([Pages Functions bindings](https://developers.cloudflare.com/pages/functions/bindings/)). Cron Triggers, Queue consumers, Workers Logs and Logpush are not supported ([migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/)). Beyond 20,000 files, the site has to move to a Pro, Business or Enterprise plan and set `PAGES_WRANGLER_MAJOR_VERSION=4` in the project to get 100,000 files per site; those plans also allow more builds, 5,000 a month on Pro and 20,000 on Business ([Pages limits](https://developers.cloudflare.com/pages/platform/limits/)). The Pages limits page does not say that Workers Paid raises this limit. When these features are needed, Cloudflare provides a [guide for moving from Pages to Workers](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/).

> [!TIP] Once Functions are added, limit them with _routes.json
> When a project has a `functions` folder, Pages generates `_routes.json` at deploy time to decide which requests run Functions. Written by hand, it can let only `/api/*` run code while every other request stays a free static asset request; paths that are not listed in `include`, or are excluded by `exclude`, do not run Functions. `_routes.json` needs at least one `include` rule, allows at most 100 `include` and `exclude` rules combined at up to 100 characters each, and `exclude` takes priority ([Functions routing](https://developers.cloudflare.com/pages/functions/routing/)).
>
> ```json title="_routes.json"
> {
>   "version": 1,
>   "include": ["/api/*"],
>   "exclude": []
> }
> ```

### Workers with Static Assets

- **Advantages**: the build allowance is counted in minutes, so a site with short builds can build many times; the config lives in `wrangler.jsonc` and is versioned with the code; server-side code, Cron Triggers or queues can be added to the same project later without changing platforms; turning on "Protect this Worker behind Access" on the Worker's Access tab with the scope set to "All traffic" protects every URL of the Worker from one setting, including routes, custom domains, `workers.dev` and preview URLs[^workers-access]; it is the approach Cloudflare [recommends for new projects](https://developers.cloudflare.com/workers/best-practices/workers-best-practices/).
- **Disadvantages**: a custom domain must be a Cloudflare zone (the docs require "An active Cloudflare zone"), which means the domain's nameservers have to be managed by Cloudflare, for subdomains too ([Workers custom domains](https://developers.cloudflare.com/workers/configuration/routing/custom-domains/), [migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/)); branch previews need Worker Previews set up, and preview URLs are public by default[^previews]; the `workers.dev` route and Version URLs are public when enabled (see the note below); a request with a `Range` header gets the full file with 200 OK instead of 206 Partial Content, which can break uses such as video playback in Safari, and the documented workaround is `run_worker_first` with `env.ASSETS.fetch()` ([Static Assets billing and limitations](https://developers.cloudflare.com/workers/static-assets/billing-and-limitations/)).
- **As needs grow**: for an API or form handling, add `main` to the config and write Worker code. Requests still look for a static file first and run the code only when nothing matches. Requests that run code count toward the 100,000 per day, each request gets at most 10 ms of CPU time, and going over the daily quota returns Error 1027, with the quota reset at midnight UTC; each route can be set to bypass the Worker when over the quota (fail open) or show the 1027 error page (fail closed) ([Workers limits](https://developers.cloudflare.com/workers/platform/limits/)). Databases and other services work on the free plan: [D1](https://developers.cloudflare.com/d1/platform/pricing/) allows 5 million rows read and 100,000 rows written per day, with 5 GB in total, and once the daily read or write limit is reached, queries fail until the reset at 00:00 UTC; [Durable Objects](https://developers.cloudflare.com/durable-objects/platform/pricing/) are limited to the SQLite backend, with 100,000 requests and 13,000 GB-s per day, 5 million rows read and 100,000 rows written per day, and 5 GB in total, and operations past a limit fail; [Queues](https://developers.cloudflare.com/queues/platform/pricing/) allow 10,000 operations per day. With more than 20,000 files, or more than 100,000 requests a day that run code, moving to Workers Paid (at least USD 5 per month per account) raises the file limit to 100,000 per version and removes the daily request limit ([Workers pricing](https://developers.cloudflare.com/workers/platform/pricing/), [Workers limits](https://developers.cloudflare.com/workers/platform/limits/)).

> [!NOTE] Does turning off workers.dev also turn off Version URLs?
> The [workers.dev page](https://developers.cloudflare.com/workers/configuration/routing/workers-dev/) says disabling the `workers.dev` route does not disable Version URLs, while the [Version URLs page](https://developers.cloudflare.com/workers/configuration/previews/) says the Version URL default follows `workers_dev` ("If `workers_dev` is disabled, Version URLs are disabled by default"), and that when `preview_urls` is left out of the config, Wrangler does not change an existing setting. Setting `preview_urls` explicitly in the config, rather than relying on the default, is therefore advisable. The [migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/)'s Worker Previews example uses `"preview_urls": true` together with a `previews` block.

> [!WARNING] run_worker_first paths count toward the quota
> With `assets.run_worker_first` set, matching paths always run the Worker first. The setting is a boolean or an array of route patterns (with `!` exceptions, at most 100 entries), and defaults to `false` ([Wrangler configuration](https://developers.cloudflare.com/workers/wrangler/configuration/)). Once the free plan's daily quota is used up, those requests get a 429 instead of falling back to the static file; paths that do not match, and paths excluded with `!/...`, are unaffected ([Static Assets billing and limitations](https://developers.cloudflare.com/workers/static-assets/billing-and-limitations/)).

### Side by side as the site grows

| Need | Pages | Workers + Static Assets |
| :--- | :--- | :--- |
| API, form handling | Pages Functions (file-based routes in `/functions`) | Worker code (add `main` to the config) |
| Cron Triggers | Not supported | 5 per account on the free plan |
| Database | D1, KV and other bindings; Durable Objects need a separate Worker | D1, KV and Durable Objects all work directly |
| Queues | Producer only | Producer and consumer; Workers Paid includes 1 million operations per month, then USD 0.40 per million |
| Logs | Real-time logs | Also Workers Logs, Logpush, Tail Workers, Source Maps; starting December 1, 2026, Workers Logs moves to Cloudflare Observability pricing |
| Files | 100,000 per site on Pro, Business or Enterprise once the environment variable is set | 100,000 per version on Workers Paid |
| Paid plan | Functions are billed at Workers rates; the file and build limits rise only on Pro or higher plans | At least USD 5 per month, including 10 million requests and 30 million CPU ms; then USD 0.30 per million requests and USD 0.02 per million CPU ms, with no egress or bandwidth charges |

Feature support comes from the [migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/) and [Pages Functions bindings](https://developers.cloudflare.com/pages/functions/bindings/), the per-plan Pages limits from [Pages limits](https://developers.cloudflare.com/pages/platform/limits/), Workers prices and log pricing from [Workers pricing](https://developers.cloudflare.com/workers/platform/pricing/) and [Workers limits](https://developers.cloudflare.com/workers/platform/limits/), and queue prices from [Queues pricing](https://developers.cloudflare.com/queues/platform/pricing/).

> [!NOTE] Pages stays supported; new features go to Workers
> In a [blog post on April 8, 2025](https://blog.cloudflare.com/full-stack-development-on-cloudflare-workers), Cloudflare said Pages will continue to be supported, while future investment, optimizations and new features go to Workers. The [Pages docs home page](https://developers.cloudflare.com/pages/) has a section titled "Are you sure you want to use Pages?" whose banner says "Start new projects with Workers"; [Workers Best Practices](https://developers.cloudflare.com/workers/best-practices/workers-best-practices/) says "If you are starting a new project, use Workers instead of Pages" and calls Static Assets the recommended way to deploy static sites. Neither the post nor the docs give an end-of-service date for Pages.

## How to choose

Pages is worth considering when:

- The site lives on a subdomain (such as `www.example.com`) whose DNS is not on Cloudflare, and moving the nameservers is not planned. An apex domain needs a Cloudflare zone on Pages too.
- Every branch and every deployment needs a preview URL, without writing a config file.
- The goal is to drag a folder into the dashboard and go live, with no more than 1,000 files.
- A Pages project is already running and uses nothing that only Workers has, such as Cron Triggers, Queue consumers or Workers Logs.

Workers with Static Assets is worth considering when:

- It is a new project and the domain is already on Cloudflare.
- Pushes would trigger more than 500 builds a month: Workers Builds counts minutes, so at 2 minutes per build, 3,000 minutes is about 1,500 builds.
- Cron Triggers, Queue consumers or Durable Objects are planned, or Workers Logs is needed for debugging.
- Cloudflare Access has to protect every URL of the site (including the production URL and custom domains), not only preview URLs: on Workers, turning on Access at the Worker level with "All traffic" protects the whole Worker however it is reached ([Cloudflare Access on Workers](https://developers.cloudflare.com/workers/configuration/cloudflare-access/)); the [Zero Trust free plan](https://www.cloudflare.com/plans/sase-zero-trust/) allows up to 50 users. Pages can do it too, but the production URL needs the generated Access application edited, and custom domains need their own Access application ([Known issues](https://developers.cloudflare.com/pages/platform/known-issues/)).

Worth watching on both:

- The file count is close to 20,000: the free limit is the same on both, but going beyond it takes different plans: Pages needs a Pro or higher plan, and Workers needs Workers Paid ([Pages limits](https://developers.cloudflare.com/pages/platform/limits/), [Workers limits](https://developers.cloudflare.com/workers/platform/limits/)).
- Requests that run server-side code would exceed 100,000 per day: Pages Functions and Workers share the same quota, so switching platforms adds nothing ([Pages Functions pricing](https://developers.cloudflare.com/pages/functions/pricing/)).
- Choosing Workers for a site with video that has to play in Safari: Workers static assets do not return 206 Partial Content, so those paths need `run_worker_first` and Worker code to handle `Range` requests; those requests run the Worker, and on the free plan they get a 429 once the daily quota is exceeded ([Static Assets billing and limitations](https://developers.cloudflare.com/workers/static-assets/billing-and-limitations/)).

> [!NOTE] What the docs do not say
> Neither set of docs says what happens when the 3,000 Workers Builds minutes or the 500 Pages builds run out (blocked, queued or charged). The [Pages docs home page](https://developers.cloudflare.com/pages/) says "500 deploys per month" while the [limits page](https://developers.cloudflare.com/pages/platform/limits/) says 500 builds, and neither says whether [Direct Upload](https://developers.cloudflare.com/pages/get-started/direct-upload/) counts toward it.

## Wrap-up

- A new static site on a domain that is on Cloudflare: use Workers with Static Assets. Static asset requests are just as free, code, Cron Triggers or a database can be added later without changing platforms, and it is the direction Cloudflare recommends.
- A site on a subdomain whose DNS is not on Cloudflare and will not move, or only zero-setup branch previews and drag-and-drop uploads needed: use Pages.
- Already on Pages with static files only: it can stay there, and move to Workers with the migration guide once Cron Triggers, Queue consumers or Workers Logs are needed.

[^wrangler]: Wrangler is the command-line interface (CLI) for the Cloudflare Developer Platform and manages Workers projects; Cloudflare recommends installing it locally in each project (`npm i -D wrangler@latest`) rather than globally ([install](https://developers.cloudflare.com/workers/wrangler/install-and-update/)). `wrangler dev` starts a local server for developing a Worker, and `wrangler deploy` deploys it to Cloudflare ([Workers commands](https://developers.cloudflare.com/workers/wrangler/commands/workers/)); `wrangler pages deploy` deploys a folder of static assets as a Pages deployment ([Pages commands](https://developers.cloudflare.com/workers/wrangler/commands/pages/)). The config file can be JSON (`wrangler.json` or `wrangler.jsonc`) or TOML (`wrangler.toml`); Cloudflare recommends `wrangler.jsonc` for new projects, and some newer features work only with a JSON config ([configuration](https://developers.cloudflare.com/workers/wrangler/configuration/)).
[^builds-token]: When "Create new token" is selected, Workers Builds creates an API token automatically, and its permissions can be changed later under My Profile > API Tokens; by default it has Account Settings read, Workers Scripts edit, Workers KV Storage edit, Workers R2 Storage edit, Workers Routes edit on all zones, and User Details and Memberships read. See [Builds configuration](https://developers.cloudflare.com/workers/ci-cd/builds/configuration/). The Worker name in the dashboard has to match `name` in the config; see [Builds troubleshooting](https://developers.cloudflare.com/workers/ci-cd/builds/troubleshoot/).
[^cname-order]: The docs warn that adding the CNAME by hand without first adding the domain in the dashboard leaves the domain failing to resolve, possibly with a 522 error.
[^pages-access]: The docs say "By default, these deployment URLs are public", and that the access policy "will only protect your preview deployments"; see [Preview deployments](https://developers.cloudflare.com/pages/configuration/preview-deployments/). Protecting `*.pages.dev` means editing the generated Access application, and each custom domain needs a new self-hosted Access application in Zero Trust with the domain added as its public hostname; the steps are in [Known issues](https://developers.cloudflare.com/pages/platform/known-issues/).
[^workers-access]: The scope can be "Previews only" or "All traffic"; Zero Trust has to be enabled on the account, and WebSockets are not supported. The feature launched on August 14, 2026; see the [changelog](https://developers.cloudflare.com/changelog/post/2026-08-14-workers-access/). For setup, see [Cloudflare Access on Workers](https://developers.cloudflare.com/workers/configuration/cloudflare-access/).
[^previews]: Worker Previews launched on September 22, 2026 (see the [changelog](https://developers.cloudflare.com/changelog/post/2026-09-22-worker-previews/)), need Wrangler 4.135.0 or later, and are created with `npx wrangler preview`. The config needs a `previews` block (it can be empty), and previews do not inherit production vars, secrets or bindings. Preview builds in Workers Builds are toggled with "Enable Preview Builds" under Settings > Build > Branch control. See [Worker Previews](https://developers.cloudflare.com/workers/previews/), its [configuration](https://developers.cloudflare.com/workers/previews/configuration/) and [Build branches](https://developers.cloudflare.com/workers/ci-cd/builds/build-branches/).
