Skip to content

Static assets

Deploy a static site or attach files to a Worker with ordinary Wrangler configuration. Asset bytes use the platform’s existing storage blob engine; the assets service adds immutable manifests, upload validation, routing, retention, and serving. This is not an S3 bucket, a pull-through cache, or a CDN product, and it does not create a process per site.

[assets]
directory = "./public"
binding = "ASSETS"
run_worker_first = ["/api/*"]

Then run npx wrangler deploy after connecting Wrangler. A site with no Worker script can omit main; a full-stack Worker can use env.ASSETS.fetch(request). See Databases for the combined native example and runnable check.

Routing

Matching files are served first by default. Requests without an asset match fall through to the Worker. Set run_worker_first = true to invoke the Worker first, or use a list of path patterns and ! exclusions to protect selected paths. These patterns support one wildcard per pattern.

Supported asset behavior includes GET and HEAD, content types, ETags and If-None-Match, byte ranges, ETag-based If-Range, HTML handling modes, SPA index fallback, and nearest-parent 404.html fallback. _headers path rules and _redirects path/placeholder rules are validated during publication. Redirect statuses 301/302/303/307/308 and local 200 rewrites are supported. External proxy rewrites and hostname-based _headers rules are rejected. Date-based conditional requests are not implemented; use ETags. Named placeholders occupy a complete path segment (for example, /blog/:slug); ambiguous adjacent captures are rejected before publication.

An asset hit currently passes through a platform-injected wrapper in the same dynamic isolate as the Worker. It does not invoke the application’s fetch handler on an assets-first hit, but it is not a separate isolate-free CDN fast path. Application module initialization can therefore affect first use.

Publication and rollback

Wrangler submits a manifest, receives an expiring organization/Worker-scoped upload capability, and uploads only missing hashes. The pinned CLI’s single asset upload protocol is supported. The service checks both byte length and Wrangler’s BLAKE3 content hash, and refuses to publish an incomplete manifest.

Each Worker version records one immutable asset manifest. Code, bindings, and manifest change together at the existing routing cutover; rollback selects the old version’s manifest too. Requests already executing retain their selected version. The console’s deployment details show file count and manifest bytes.

Retained Worker versions pin their assets. After pruning, manifests and blobs remain available for the HAProxy drain budget (one hour by default), so an in-flight old isolate can still fetch its files. This grace retention remains charged to the organization. Abandoned uploads expire after one hour. The assets service periodically collects expired, unreferenced sessions and blobs. A durable control-plane cleanup outbox makes publication/pruning cleanup retryable after restart or service failure; cleanup failure does not turn a successful deployment into a reported failure.

Retention is not stale-URL routing: after a new deployment, new requests resolve against the newly active manifest. A browser holding old HTML may request an old fingerprinted URL that is absent from the new manifest and receive a 404. Include old fingerprinted files in subsequent builds when that overlap is needed. The service does not search another version’s manifest behind your back.

Isolation and quotas

Assets are scoped by organization and Worker version. Stored blobs use a private namespace outside tenant-visible R2 buckets. Tenants cannot list them using S3 or R2 bindings. Identical hashes deduplicate within an organization, not across organizations. Service credentials remain in trusted runtime bindings.

Asset allowances follow the organization tier: Free permits 64 MiB and two pending uploads, Standard permits 512 MiB and five, and Enterprise permits 2 GiB and ten. Each manifest supports up to 20,000 files and each file up to 25 MiB. Assets do not also consume the organization’s R2 bucket allowance. Expired upload slots are reclaimed by the periodic collector; referenced versions remain charged until their blobs are no longer retained.

Investigate delivery

Review the Worker’s deployment details for its asset manifest and Observability for HTTP outcomes. Missing files, conditional responses, and redirects have different meanings from service failures. Compare a reported file with the active version’s manifest before assuming storage loss.

Operators use Platform observability for delivery and upload signals and Runtime isolation for continuity checks across code and manifest changes.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close