From 897686a0ef8ec51d18282ffd6d959f38483f39fd Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Mon, 22 Sep 2025 09:02:07 -0400 Subject: [PATCH] Document rollouts with Workers Static Assets This commit provides a thorough description of the problem and solutions for gradual rollouts with static assets. --- .../gradual-deployments.mdx | 14 ++- .../routing/advanced/gradual-rollouts.mdx | 113 ++++++++++++++++++ 2 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 src/content/docs/workers/static-assets/routing/advanced/gradual-rollouts.mdx diff --git a/src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx b/src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx index 32470ad93ff911..636b6d5ab6ecef 100644 --- a/src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx +++ b/src/content/docs/workers/configuration/versions-and-deployments/gradual-deployments.mdx @@ -93,10 +93,10 @@ npx wrangler versions deploy 2. Select **Create application** > **Hello World** template > deploy your Worker. -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. -5. To save changes, select the **down arrow** next to **Deploy** > **Save**. This will create a new version of your Worker. -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**. -7. cURL your Worker to test the split deployment. +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. +4. To save changes, select the **down arrow** next to **Deploy** > **Save**. This will create a new version of your Worker. +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**. +6. cURL your Worker to test the split deployment. ```bash for j in {0..10} @@ -107,6 +107,12 @@ done 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. +## Gradual deployments with static assets + +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. + +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/). + ## Version affinity 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). diff --git a/src/content/docs/workers/static-assets/routing/advanced/gradual-rollouts.mdx b/src/content/docs/workers/static-assets/routing/advanced/gradual-rollouts.mdx new file mode 100644 index 00000000000000..8b7f306baf93c5 --- /dev/null +++ b/src/content/docs/workers/static-assets/routing/advanced/gradual-rollouts.mdx @@ -0,0 +1,113 @@ +--- +pcx_content_type: concept +title: Gradual rollouts +sidebar: + order: 4 +head: [] +description: Provide static asset routing solutions for gradual Worker deployments. +--- + +import { Example } from "~/components"; + +[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. + +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: + +``` +dist/ +├── index.html +├── assets/ +│ ├── index-a1b2c3d4.js # Main bundle with content hash +│ ├── index-e5f6g7h8.css # Styles with content hash +│ └── logo-i9j0k1l2.svg # Images with content hash +``` + +During a gradual rollout between two versions of your application, you might have: + +**Version A (old build):** + +- `index.html` references `assets/index-a1b2c3d4.js` +- `assets/index-a1b2c3d4.js` exists + +**Version B (new build):** + +- `index.html` references `assets/index-m3n4o5p6.js` +- `assets/index-m3n4o5p6.js` exists + +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. + +This issue affects applications built with any framework that fingerprints assets, including: + +- **React** (Create React App, Next.js, Vite) +- **Vue** (Vue CLI, Nuxt.js, Vite) +- **Angular** (Angular CLI) +- **Svelte** (SvelteKit, Vite) +- **Static site generators** that optimize asset loading + +## Preventing asset mismatches with version affinity + +[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. + +### Session-based affinity + +For applications with user sessions, use session identifiers: + + + +Text in **Expression Editor**: + +```txt +http.cookie contains "session_id" +``` + +Selected operation under **Modify request header**: _Set dynamic_ + +**Header name**: `Cloudflare-Workers-Version-Key` + +**Value**: `http.cookie["session_id"]` + + + +### User-based affinity + +For authenticated applications, use user identifiers stored in cookies or headers: + + + +Text in **Expression Editor**: + +```txt +http.cookie contains "user_id" +``` + +Selected operation under **Modify request header**: _Set dynamic_ + +**Header name**: `Cloudflare-Workers-Version-Key` + +**Value**: `http.cookie["user_id"]` + + + +## Testing and monitoring + +Before rolling out to production, verify that your version affinity setup works correctly: + +```bash +# Test with version affinity - both requests should hit the same version +curl -H "Cookie: session_id=test123" https://your-worker.example.com/ +curl -H "Cookie: session_id=test123" https://your-worker.example.com/assets/index.js +``` + +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. + +## Best practices + +When deploying applications with fingerprinted assets using gradual rollouts: + +- Use version affinity (preferably session-based) to ensure consistent asset loading +- Test asset loading using version overrides before increasing rollout percentages +- Monitor 404 rates during deployments to catch issues quickly +- Have rollback procedures ready in case asset problems arise +- Choose session-based or user-based affinity depending on your application's authentication model + +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.