Skip to content

Commit e9cafa0

Browse files
Document rollouts with Workers Static Assets (#25323)
This commit provides a thorough description of the problem and solutions for gradual rollouts with static assets.
1 parent ab8a17e commit e9cafa0

File tree

2 files changed

+123
-4
lines changed

2 files changed

+123
-4
lines changed

src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ npx wrangler versions deploy
9393
<DashButton url="/?to=/:account/workers-and-pages" />
9494

9595
2. Select **Create application** > **Hello World** template > deploy your Worker.
96-
4. Once the Worker is deployed, go to the online code editor through **Edit code**. Edit the Worker code (change the `Response` content) and upload the Worker.
97-
5. To save changes, select the **down arrow** next to **Deploy** > **Save**. This will create a new version of your Worker.
98-
6. Create a new deployment that splits traffic between the two versions created in step 3 and 5 by going to **Deployments** and selecting **Deploy Version**.
99-
7. cURL your Worker to test the split deployment.
96+
3. Once the Worker is deployed, go to the online code editor through **Edit code**. Edit the Worker code (change the `Response` content) and upload the Worker.
97+
4. To save changes, select the **down arrow** next to **Deploy** > **Save**. This will create a new version of your Worker.
98+
5. Create a new deployment that splits traffic between the two versions created in step 3 and 5 by going to **Deployments** and selecting **Deploy Version**.
99+
6. cURL your Worker to test the split deployment.
100100

101101
```bash
102102
for j in {0..10}
@@ -107,6 +107,12 @@ done
107107

108108
You should see 10 responses. Responses will reflect the content returned by the versions in your deployment. Responses will vary depending on the percentages configured in step #6.
109109

110+
## Gradual deployments with static assets
111+
112+
When your Worker serves [static assets](/workers/static-assets/), gradual deployments can cause asset compatibility issues where users receive HTML from one version that references assets only available in another version, leading to 404 errors.
113+
114+
For detailed guidance on handling static assets during gradual rollouts, including specific examples and configuration steps, refer to [Gradual rollouts](/workers/static-assets/routing/advanced/gradual-rollouts/).
115+
110116
## Version affinity
111117

112118
By default, the percentages configured when using gradual deployments operate on a per-request basis — a request has a X% probability of invoking one of two versions of the Worker in the [deployment](/workers/configuration/versions-and-deployments/#deployments).
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
pcx_content_type: concept
3+
title: Gradual rollouts
4+
sidebar:
5+
order: 4
6+
head: []
7+
description: Provide static asset routing solutions for gradual Worker deployments.
8+
---
9+
10+
import { Example } from "~/components";
11+
12+
[Gradual deployments](/workers/configuration/versions-and-deployments/gradual-deployments/) route requests to different Worker versions based on configured percentages. When your Worker serves static assets, this per-request routing can cause asset reference mismatches that result in 404 errors and broken user experiences.
13+
14+
Modern JavaScript frameworks commonly generate fingerprinted asset filenames during builds. For example, when you build a React application with Vite, your assets might look like:
15+
16+
```
17+
dist/
18+
├── index.html
19+
├── assets/
20+
│ ├── index-a1b2c3d4.js # Main bundle with content hash
21+
│ ├── index-e5f6g7h8.css # Styles with content hash
22+
│ └── logo-i9j0k1l2.svg # Images with content hash
23+
```
24+
25+
During a gradual rollout between two versions of your application, you might have:
26+
27+
**Version A (old build):**
28+
29+
- `index.html` references `assets/index-a1b2c3d4.js`
30+
- `assets/index-a1b2c3d4.js` exists
31+
32+
**Version B (new build):**
33+
34+
- `index.html` references `assets/index-m3n4o5p6.js`
35+
- `assets/index-m3n4o5p6.js` exists
36+
37+
If a user's initial request for `/` goes to Version A, they'll receive HTML that references `index-a1b2c3d4.js`. However, when their browser then requests `/assets/index-a1b2c3d4.js`, that request might be routed to Version B, which only contains `index-m3n4o5p6.js`, resulting in a 404 error.
38+
39+
This issue affects applications built with any framework that fingerprints assets, including:
40+
41+
- **React** (Create React App, Next.js, Vite)
42+
- **Vue** (Vue CLI, Nuxt.js, Vite)
43+
- **Angular** (Angular CLI)
44+
- **Svelte** (SvelteKit, Vite)
45+
- **Static site generators** that optimize asset loading
46+
47+
## Preventing asset mismatches with version affinity
48+
49+
[Version affinity](/workers/configuration/versions-and-deployments/gradual-deployments/#version-affinity) ensures all requests from the same user are handled by the same Worker version, preventing asset reference mismatches entirely. You can configure this using [Transform Rules](/rules/transform/request-header-modification/) to automatically set the `Cloudflare-Workers-Version-Key` header.
50+
51+
### Session-based affinity
52+
53+
For applications with user sessions, use session identifiers:
54+
55+
<Example>
56+
57+
Text in **Expression Editor**:
58+
59+
```txt
60+
http.cookie contains "session_id"
61+
```
62+
63+
Selected operation under **Modify request header**: _Set dynamic_
64+
65+
**Header name**: `Cloudflare-Workers-Version-Key`
66+
67+
**Value**: `http.cookie["session_id"]`
68+
69+
</Example>
70+
71+
### User-based affinity
72+
73+
For authenticated applications, use user identifiers stored in cookies or headers:
74+
75+
<Example>
76+
77+
Text in **Expression Editor**:
78+
79+
```txt
80+
http.cookie contains "user_id"
81+
```
82+
83+
Selected operation under **Modify request header**: _Set dynamic_
84+
85+
**Header name**: `Cloudflare-Workers-Version-Key`
86+
87+
**Value**: `http.cookie["user_id"]`
88+
89+
</Example>
90+
91+
## Testing and monitoring
92+
93+
Before rolling out to production, verify that your version affinity setup works correctly:
94+
95+
```bash
96+
# Test with version affinity - both requests should hit the same version
97+
curl -H "Cookie: session_id=test123" https://your-worker.example.com/
98+
curl -H "Cookie: session_id=test123" https://your-worker.example.com/assets/index.js
99+
```
100+
101+
During gradual rollouts, monitor your Worker's analytics for increased 404 response rates, especially for asset files (`.js`, `.css`, `.png`). Use [Analytics Engine](/analytics/analytics-engine/) or [Logpush](/workers/observability/logs/logpush/) to track these metrics and catch asset mismatch issues early.
102+
103+
## Best practices
104+
105+
When deploying applications with fingerprinted assets using gradual rollouts:
106+
107+
- Use version affinity (preferably session-based) to ensure consistent asset loading
108+
- Test asset loading using version overrides before increasing rollout percentages
109+
- Monitor 404 rates during deployments to catch issues quickly
110+
- Have rollback procedures ready in case asset problems arise
111+
- Choose session-based or user-based affinity depending on your application's authentication model
112+
113+
With proper version affinity configuration, you can safely perform gradual deployments of applications that use modern build tools and asset optimization without worrying about broken user experiences from missing assets.

0 commit comments

Comments
 (0)