Skip to content

WIP: [DO] Document delayed code updates - #32222

Draft
iglesiasbrandon wants to merge 16 commits into
productionfrom
durable-objects-graceful-code-updates
Draft

iglesiasbrandon wants to merge 16 commits into
productionfrom
durable-objects-graceful-code-updates

Conversation

@iglesiasbrandon

Copy link
Copy Markdown
Collaborator

Summary

Documents the WIP Durable Objects behavior that lets active objects defer code updates until hibernation, reducing deployment-time interruptions to requests, storage operations, and hibernatable WebSockets.

Adds a changelog and updates lifecycle, WebSocket, storage, version-skew, and troubleshooting guidance. The final launch date, compatibility date, timeout contract, and Wrangler option remain marked as TODOs before review.

Documentation checklist

@github-actions github-actions Bot added product:durable-objects Durable Objects: https://developers.cloudflare.com/workers/learning/using-durable-objects/ product:changelog size/s labels Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

This pull request requires reviews from CODEOWNERS as it changes files that match the following patterns:

Pattern Owners
/src/content/changelog/durable-objects/ @danlapid, @iglesiasbrandon, @irvinebroque, @joshthoward, @lambrospetrou, @mikenomitch, @rita3ko, @vy-ton, @cloudflare/pm-changelogs, @cloudflare/product-owners
/src/content/docs/durable-objects/ @danlapid, @iglesiasbrandon, @irvinebroque, @joshthoward, @lambrospetrou, @mikenomitch, @rita3ko, @vy-ton, @cloudflare/product-owners
/src/content/partials/durable-objects/ @danlapid, @iglesiasbrandon, @irvinebroque, @joshthoward, @lambrospetrou, @mikenomitch, @rita3ko, @vy-ton, @cloudflare/product-owners

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Hey there, we've marked this pull request as stale because there's no recent activity on it. This label helps us identify PRs that might need updates (or to be closed out by our team if no longer relevant).

@github-actions github-actions Bot added the stale label Aug 5, 2026
Comment thread src/content/docs/durable-objects/concepts/durable-object-lifecycle.mdx Outdated
Comment thread src/content/docs/durable-objects/concepts/durable-object-lifecycle.mdx Outdated
@iglesiasbrandon
iglesiasbrandon force-pushed the durable-objects-graceful-code-updates branch from e9771db to 06b20b1 Compare August 13, 2026 21:32
@github-actions

github-actions Bot commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Preview URL: https://8339c384.preview.developers.cloudflare.com
Preview Branch URL: https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com

Files with changes (up to 15)

Original Link Updated Link
https://developers.cloudflare.com/durable-objects/deployments/durable-objects-code-updates/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/durable-objects/deployments/durable-objects-code-updates/
https://developers.cloudflare.com/changelog/post/2026-08-13-durable-objects-deferred-code-updates/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/changelog/post/2026-08-13-durable-objects-deferred-code-updates/
https://developers.cloudflare.com/durable-objects/deployments/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/durable-objects/deployments/
https://developers.cloudflare.com/durable-objects/concepts/durable-object-lifecycle/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/durable-objects/concepts/durable-object-lifecycle/
https://developers.cloudflare.com/durable-objects/best-practices/access-durable-objects-storage/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/durable-objects/best-practices/access-durable-objects-storage/
https://developers.cloudflare.com/durable-objects/best-practices/websockets/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/durable-objects/best-practices/websockets/
https://developers.cloudflare.com/durable-objects/platform/known-issues/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/durable-objects/platform/known-issues/
https://developers.cloudflare.com/durable-objects/observability/troubleshooting/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/durable-objects/observability/troubleshooting/
https://developers.cloudflare.com/durable-objects/deployments/durable-object-gradual-deployments/ https://durable-objects-graceful-code-updates.preview.developers.cloudflare.com/durable-objects/deployments/durable-object-gradual-deployments/

Comment thread src/content/docs/durable-objects/reference/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/reference/durable-objects-code-updates.mdx Outdated
---

Durable Objects may shut down at any time due to deployments, inactivity, or runtime decisions. Rather than relying on shutdown hooks (which are not provided), design your application to write state incrementally.
Durable Objects may shut down at any time due to forced code updates, inactivity, or runtime decisions. Rather than relying on shutdown hooks (which are not provided), design your application to write state incrementally.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a reference to when customers update code or something else?

think there is opportunity here to get language right:

When you deploy a code change, a Durable Object is inactive, or when Cloudflare deploys a new version of the Workers Runtime, a Durable Object will shut down. This is similar to other compute environments, where compute instances do not live forever, and where applications must persist state back to a database or storage system. For example, if you use Durable Objects for a long-running task, you should write state incrementally as the task progresses, and not rely on keeping state entirely in-memory until the task completes.

Comment thread src/content/docs/durable-objects/reference/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/reference/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/reference/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/reference/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/reference/durable-objects-code-updates.mdx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

This PR changes current filenames or deletes current files. Make sure you have redirects set up to cover the following paths:

  • /durable-objects/reference/durable-object-gradual-deployments/

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated

Deploying again before an object hibernates does not restart or extend its `max_delay`. The object applies the latest deployed version once it hibernates or the original `max_delay` is reached, and it might skip versions you deployed in between.

## Configure a code update strategy

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

##Configure a code update strategy
Show for wrangler and REST (and Terraform too?)
###Options
###Set strategy for a single deployment
Apply a code update immediately: is an example scenario of why you need to set for a single deployment

Current structure splits too much for the same content

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think we can clean this up more for better readability:

## Configure a code update strategy
### Options (put the table from `What each configuration does` here
### wrangler
### REST
### Set strategy for a single deployment


<PackageManagers type="exec" pkg="wrangler" args="versions deploy <VERSION_ID>@100% --durable-objects-code-update-mode immediate" />

The flag accepts `deferred` or `immediate` and overrides only `mode`. To use a `max_delay` other than the default, set `code_update_strategy` in your Wrangler configuration or in the REST API request instead — the flag does not accept `max_delay`.

@vy-ton vy-ton Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not make sense if you're setting CLI flags, to tell user to configure max_delay in wrangler file or REST. Options are:

(1) CLI can set all configuration options
(2) OR what Brendan's wiki had is saying CLI only gives you shortcut option to do an immediate rollout

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- A `deferred` code update strategy is best-effort. Cloudflare does not guarantee that an object keeps running its current code for the entire `max_delay`.
- A `deferred` code update does not stop an object from accepting new requests, events, or storage operations while it waits to hibernate.
- An object that is still active when `max_delay` is reached resets the same way an `immediate` update does.
- A code update strategy does not delay restarts unrelated to code updates, such as process sandbox migrations, resource limits, or Workers runtime updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing here should be updates to Workers runtime. Everything else a user should not know

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 31, 2026 •

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://durable-objects-graceful-code-updates.previews.developers.cloudflare.com (commit 8339c38)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://5b99d3ff.previews.developers.cloudflare.com 8339c38 2026-09-18T18:01:48.433Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://c6e2af87.previews.developers.cloudflare.com 0a504cb 2026-09-16T18:51:38.630Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://e144217d.previews.developers.cloudflare.com b2e2b88 2026-09-02T22:20:06.877Z Visit the dashboard ↗
  • Build: Failed ❌

View logs ↗
72cb6fb 2026-09-02T20:35:08.051Z View logs ↗
  • Build: Failed ❌

View logs ↗
6f39c32 2026-09-01T20:35:15.384Z View logs ↗
  • Build: Failed ❌

View logs ↗
14e1056 2026-09-01T18:18:10.849Z View logs ↗
  • Build: Failed ❌

View logs ↗
6216382 2026-08-31T18:50:31.931Z View logs ↗
  • Build: Failed ❌

View logs ↗
bab1e7b 2026-08-31T15:00:49.376Z View logs ↗

@@ -0,0 +1,195 @@
---
title: Defer code updates until hibernation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this generic so any dev can understand why this relates to their work (hibernation is very DO specific)

Workers code updates, Workers deployments

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

going to update to "Durable Objects code updates" to remove the DO specific lifecycle verbiage from the title

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated

Deploying again before an object hibernates does not restart or extend its `max_delay`. The object applies the latest deployed version once it hibernates or the original `max_delay` is reached, and it might skip versions you deployed in between.

## Configure a code update strategy

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think we can clean this up more for better readability:

## Configure a code update strategy
### Options (put the table from `What each configuration does` here
### wrangler
### REST
### Set strategy for a single deployment

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated

During a [gradual deployment](/workers/versions-and-deployments/gradual-deployments/with-durable-objects/), Cloudflare assigns each Durable Object to one of the versions in the deployment. Increasing a version's traffic percentage assigns more objects to that version. Only the newly assigned objects follow the mechanism described in [How it works](/durable-objects/deployments/durable-objects-code-updates/#how-it-works) above — for example, increasing a version's traffic percentage from 20% to 50% starts a `deferred` wait only for the additional 30% of objects newly assigned to it. Objects that already run that version, and objects still assigned to an earlier version, are not affected.

Different objects can be on different `max_delay` clocks at the same time. If a later progression uses a different code update strategy, that strategy applies only to the objects that progression reassigns.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what this is saying. If we clarify this comment, https://github.com/cloudflare/cloudflare-docs/pull/32222/changes#r3905182929, we dont need to explain here

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
- A `deferred` code update does not stop an object from accepting new requests, events, or storage operations while it waits to hibernate.
- An object that is still active when `max_delay` is reached resets the same way an `immediate` update does.
- A code update strategy does not delay restarts unrelated to code updates, such as Workers runtime updates.
- A code update strategy does not make incompatible Worker and Durable Object versions safe to run together. Keep your interfaces forward and backward compatible across versions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would delete, not relevant here


Deploying again before an object hibernates does not extend its `max_delay` window — a later deploy can only shorten the remaining wait, never lengthen it. Whichever deploy's `max_delay` sets the deadline, the object always applies the *latest* deployed version when that deadline arrives, not necessarily the version that set it.

For example: you deploy version A with `max_delay: 30`. Ten seconds later, you deploy version B with `max_delay: 60` before the object hibernates. The deadline stays at 30 seconds from A's deploy — B's longer window doesn't extend it — but when that deadline arrives, Cloudflare resets the object and applies version B, the latest version, not A. The same is true if the object hibernates on its own before the deadline: it always wakes up running the latest deployed version.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For you backlog, this could benefit from a diagram. Before public merge, lets convert diagrams to CF branded png

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
- Each deployment sets its own `max_delay` timer.
- The first `max_delay` timer to expire applies the latest deployed version — not necessarily the version whose timer expired.

For example: you deploy version A with `max_delay: 30`, starting a 30-second timer. Ten seconds later, you deploy version B with `max_delay: 60`, starting a separate 60-second timer. Version A's timer expires first, at the 30-second mark. When it expires, Cloudflare resets the object and applies version B — the latest deployed version — even though it was version A's timer that fired. The same is true if the object hibernates on its own before either timer expires: it always wakes up running the latest deployed version.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: add diagram here

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated

| Mode | Default `max_delay` | Behavior |
| ----------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `deferred` | 30 seconds | Cloudflare waits for an active Durable Object to hibernate before applying the update. If the object does not hibernate within `max_delay`, Cloudflare resets it and applies the update. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets document max 300s in the table too

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
```jsonc
{
"durable_objects": {
"bindings": [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iglesiasbrandon let's do this still, to highlight the minimal code snippet


`max_delay` is in seconds and only applies when `mode` is `deferred`. The maximum is `300` (five minutes). Omit `max_delay` to use the default for your compatibility date.

Pass `--durable-objects-code-update-mode` to `wrangler versions deploy` or `wrangler versions rollback` (or their `wrangler deploy` and `wrangler rollback` alternatives) to override the configured mode for a single deployment:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this + in the ## Set strategy for a single deployment section

So you have the code snippet and explanation of common task someone might need

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
@iglesiasbrandon

Copy link
Copy Markdown
Collaborator Author

/rebase

@cloudflare-docs-bot

cloudflare-docs-bot Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Review

⚠️ 7 warnings, 💡 5 suggestions found in full PR diff.

👉 Fix in your agent 👈
Fix the following review findings in PR #32222 (https://github.com/cloudflare/cloudflare-docs/pull/32222).

Before making changes, review each finding and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g. the fix requires disproportionate effort for minimal benefit,
  or the finding is factually incorrect), explain why
- If you need clarification before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

After triaging, follow this order:
1. Post a comment on this PR for any findings you are skipping, with the finding ID and your reasoning.
2. Then commit the fixes for the legitimate findings.

The comment must come before the commit — the bot reads PR comments when a new
push triggers a review, so skip comments posted after the push will be missed.

---

## Code Review

### Warnings (2)

#### CR-1b52ec6cffb5 · Placeholder compatibility date left in content
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 33
- **Issue:** The literal placeholder `COMPATIBILITY_DATE` is used in both the compatibility-date explanation (lines 33–34) and the options table (lines 87–88) instead of the actual Workers compatibility date that enables the deferred default.
- **Fix:** Replace `COMPATIBILITY_DATE` with the real compatibility date before merging/publishing, ensuring all four occurrences are updated.

#### CR-ef0dc9c8bca0 · Inconsistent storage API reference
- **File:** `src/content/docs/durable-objects/observability/troubleshooting.mdx` line 48
- **Issue:** The added paragraph uses `ctx.storage`, but the existing troubleshooting section below uses `state.storage.get()` for the same Durable Objects storage API.
- **Fix:** Use `state.storage` here to match the rest of the page and the standard constructor parameter name in the Durable Objects API.

### Suggestions (1)

#### CR-5b6afb0b53cd · Internal implementation details in tracked page comment
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 13
- **Issue:** The TODO MDX comment references an internal engineering spec field (`durable_objects_hibernation_timeout`), an internal team, and an individual's proposal as the basis for the public API shape.
- **Fix:** Remove or reword the TODO block before publication so the public source does not carry internal spec details or individual names.

---

## Conventions

### Warnings (1)

#### CV-8f54394eeae8 · Scope accuracy
- **File:** PR-level finding
- **Issue:** The description covers the new code-updates page, changelog, and content updates, but is silent on the structural change: durable-object-gradual-deployments.mdx is moved from reference/ to a new deployments/ section, with a new deployments/index.mdx added.
- **Fix:** Mention the page relocation from reference/ to deployments/ and the new deployments index page (and any needed redirects) in the PR description.

---

## Style Guide Review

### Warnings (4)

#### SG-2fbda990fd81 · No contractions in prose
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 79
- **Issue:** Line uses `can't` in body prose
- **Fix:** Rewrite as `you cannot`

#### SG-951066d7bc06 · No contractions in prose
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 122
- **Issue:** Line uses `you're` in body prose
- **Fix:** Rewrite as `you are`

#### SG-feca38b00146 · No contractions in prose
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 122
- **Issue:** Line uses `don't` in body prose
- **Fix:** Rewrite as `do not`

#### SG-14fe50284fd2 · Avoid directional words
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 201
- **Issue:** Line refers to content `above` after a direct link
- **Fix:** Remove `above`; the link to `How it works` is already a direct reference

### Suggestions (4)

#### SG-24f344e4332b · Bullet lists should have three or more items
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 33
- **Issue:** Compatibility-date defaults are introduced with a two-item bullet list
- **Fix:** Consider rewriting the before/after cases as prose

#### SG-4e1917100dc3 · Bullet lists should have three or more items
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 59
- **Issue:** Consecutive-deployment behavior is introduced with a two-item bullet list
- **Fix:** Consider rewriting the two behaviors as prose

#### SG-5a8a7c0f01bb · Bullet lists should have three or more items
- **File:** `src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx` line 196
- **Issue:** Single-deployment override examples are introduced with a two-item bullet list
- **Fix:** Consider rewriting the two examples as prose

#### SG-aba807faf937 · Serial comma
- **File:** `src/content/changelog/durable-objects/2026-08-13-durable-objects-deferred-code-updates.mdx` line 14
- **Issue:** …run long-running [agents](/agents/), maintain [long-lived WebSocket connections](/durable-objects/best-practices/websockets/) and coordinate state across many clients.
- **Fix:** Add a comma before the final `and` in the three-item list: `…websockets/), and coordinate…`.

Code Review

This code review is in beta and may not always be helpful — use your judgment.

Warnings (2)
File Issue
durable-objects/deployments/durable-objects-code-updates.mdx line 33 Placeholder compatibility date left in content — The literal placeholder COMPATIBILITY_DATE is used in both the compatibility-date explanation (lines 33–34) and the options table (lines 87–88) instead of the actual Workers compatibility date that enables the deferred default. Fix: Replace COMPATIBILITY_DATE with the real compatibility date before merging/publishing, ensuring all four occurrences are updated.
durable-objects/observability/troubleshooting.mdx line 48 Inconsistent storage API reference — The added paragraph uses ctx.storage, but the existing troubleshooting section below uses state.storage.get() for the same Durable Objects storage API. Fix: Use state.storage here to match the rest of the page and the standard constructor parameter name in the Durable Objects API.
Suggestions (1)
File Issue
durable-objects/deployments/durable-objects-code-updates.mdx line 13 Internal implementation details in tracked page comment — The TODO MDX comment references an internal engineering spec field (durable_objects_hibernation_timeout), an internal team, and an individual's proposal as the basis for the public API shape. Fix: Remove or reword the TODO block before publication so the public source does not carry internal spec details or individual names.

Conventions

Warnings (1)
File Issue
PR Scope accuracy — The description covers the new code-updates page, changelog, and content updates, but is silent on the structural change: durable-object-gradual-deployments.mdx is moved from reference/ to a new deployments/ section, with a new deployments/index.mdx added. Fix: Mention the page relocation from reference/ to deployments/ and the new deployments index page (and any needed redirects) in the PR description.

Style Guide Review

Warnings (4)
File Issue
durable-objects/deployments/durable-objects-code-updates.mdx line 79 No contractions in prose — Line uses can't in body prose Fix: Rewrite as you cannot
durable-objects/deployments/durable-objects-code-updates.mdx line 122 No contractions in prose — Line uses you're in body prose Fix: Rewrite as you are
durable-objects/deployments/durable-objects-code-updates.mdx line 122 No contractions in prose — Line uses don't in body prose Fix: Rewrite as do not
durable-objects/deployments/durable-objects-code-updates.mdx line 201 Avoid directional words — Line refers to content above after a direct link Fix: Remove above; the link to How it works is already a direct reference
Suggestions (4)
File Issue
durable-objects/deployments/durable-objects-code-updates.mdx line 33 Bullet lists should have three or more items — Compatibility-date defaults are introduced with a two-item bullet list Fix: Consider rewriting the before/after cases as prose
durable-objects/deployments/durable-objects-code-updates.mdx line 59 Bullet lists should have three or more items — Consecutive-deployment behavior is introduced with a two-item bullet list Fix: Consider rewriting the two behaviors as prose
durable-objects/deployments/durable-objects-code-updates.mdx line 196 Bullet lists should have three or more items — Single-deployment override examples are introduced with a two-item bullet list Fix: Consider rewriting the two examples as prose
changelog/durable-objects/2026-08-13-durable-objects-deferred-code-updates.mdx line 14 Serial comma — …run long-running agents, maintain long-lived WebSocket connections and coordinate state across many clients. Fix: Add a comma before the final and in the three-item list: …websockets/), and coordinate….
Commands

Only codeowners can run commands. Post a comment with the command to trigger it.

Command Description
/review Runs a review now. Incremental if a prior review exists, full if not.
/full-review Re-reviews the entire PR diff from scratch, ignoring incremental history. Useful after a rebase, when you want a fresh review, or if the bot gets out of sync and reports issues that no longer exist.
/ignore-review-limit Permanently lifts the 2-review automatic limit for this PR. Future pushes will trigger reviews as normal.
/disable-auto-review Stops automatic reviews from triggering on future pushes to this PR. Codeowners can still run /review or /full-review manually.
/rebase Rebases the PR branch against production. On conflict, attempts to resolve automatically using AI. Stops with an explanation if confidence is not high enough.

iglesiasbrandon and others added 12 commits September 2, 2026 22:11
Co-authored-by: Brendan Irvine-Broque <brendanib@gmail.com>
…review feedback

- Replace deployment_grace_period (integer) with code_update_strategy
  { mode, max_delay } to match Brendan's proposal, keeping max_delay as
  a plain integer (seconds) per Wrangler config convention rather than
  a duration string.
- Add a table covering every mode/max_delay combination, including the
  omitted-field default, the invalid immediate+max_delay case, and the
  deferred+0 degenerate case.
- Add a CLI flag (--durable-objects-code-update-mode, mode-only) and
  explain why it exists alongside Wrangler config.
- Add a Mermaid flowchart to Gradual deployments showing which objects
  start waiting on a code update strategy.
- Remove remaining relative-time phrasing ("before this feature
  existed") from the reference page.
- Rewrite working-without-shutdown-hooks.mdx to answer what triggers a
  shutdown, previously never addressed.
- Add a Worker-deployment-vs-object-adoption clarification and a link
  to versions-and-deployments in durable-object-lifecycle.mdx.
- Clean up the best-effort Limitations bullet.
- Rename the changelog entry to drop the now-inaccurate grace-period
  slug.
…e flow

Per in-person review with Vy:
- Create a new Deployments sidebar section (durable-objects/deployments/)
  and move this page and the Gradual Deployments nav stub into it. Title
  and filename unchanged; only the URL path and sidebar grouping change.
- Add a Default max_delay column to the Choose a code update strategy
  table and state the before/on-or-after compatibility-date default
  directly in that section, removing the now-redundant standalone
  Default behavior and compatibility dates section.
- Reorder What each configuration does so deferred rows precede
  immediate rows, and split the omitted-field row into two explicit
  rows (before / on-or-after the compatibility date).
- Generalize the gradual-deployments flowchart (drop version-percentage
  framing) and move it into How it works; Gradual deployments now
  links back to it instead of duplicating a diagram.
- Reorder page sections into what/mechanism/how/why/reference order:
  Choose a strategy -> How it works -> Configure -> What each
  configuration does -> Override (CLI) -> REST API -> Apply an update
  immediately -> Gradual deployments -> Limitations -> Related
  resources.
Drop 'Delay' in favor of 'Defer' to match the code_update_strategy
mode value (deferred), and drop 'Durable Object' from the title since
'hibernation' already carries sufficient product-specific signal,
matching sibling page titles in this section (Use WebSockets, Invoke
methods, Error handling) that also omit it. Updated the 4 inbound
link texts that quoted the old title verbatim.
…link

- Update changelog title from 'Delay' to 'Defer code updates until
  active Durable Objects hibernate' to match the renamed reference
  page title.
- Link 'code update strategy' in the shared working-without-shutdown-hooks
  partial to the reference page, giving rules-of-durable-objects.mdx
  (which had no other mention of this feature) a discovery path.
Co-authored-by: Vy Ton <vy@cloudflare.com>
- Lead the intro with deferred (the actual post-launch default) instead
  of the immediate/reset behavior; drop the imprecise "inactive
  (hibernated)" phrasing in favor of the term already used elsewhere
  on the page; link to the lifecycle docs.
- Make How it works step 1 concrete (deploy a new version to 100% of
  traffic) and merge the two "active" steps into one continuous flow,
  matching the diagram's three real paths (inactive / hibernates in
  time / doesn't hibernate in time).
- Redesign the diagram with an explicit code_update_strategy fork
  (immediate vs deferred), switched to a top-down layout; rendered and
  verified via mermaid-cli.
- Clarify max_delay semantics across overlapping deploys: a later
  deploy can only shorten the remaining wait, never extend it (matches
  the SPEC's timer behavior exactly), with a concrete worked example.
  This also guarantees an immediate deploy always wins over an earlier
  still-pending deferred one.
- Merge Configure / Override (CLI) / REST API / Apply immediately into
  one "Configure a code update strategy" section with two subsections
  (Options; Set strategy for a single deployment), matching how
  --containers-rollout already works on this exact wrangler command
  (mode-only CLI flag, no CLI equivalent for the numeric tuning value).
- Tighten the CLI max_delay redirect sentence.
- Trim the Limitations bullet about unrelated restarts to just Workers
  runtime updates, dropping internal-only terms (process sandbox
  migrations, resource limits) a reader doesn't need.
- Note that code_update_strategy applies to every Durable Object class
  a Worker exports and binds to under one durable_objects config block
  (bindings is an array; code_update_strategy sits at the durable_objects
  level, not per-binding) -- verified against the Wrangler config
  schema reference. Also note the script_name exception: a binding to
  a class defined in a different Worker is governed by that Worker's
  own code_update_strategy, not this deployment's.
- Rework the multi-deploy max_delay explanation so the worked example
  explicitly names which version is applied when the deadline arrives
  (the latest deployed version, not necessarily the version whose
  max_delay set that deadline), rather than leaving that implicit.
Co-authored-by: Vy Ton <vy@cloudflare.com>
- Rename the page title to 'Durable Objects code updates', dropping
  'hibernation' as unexplained DO-specific jargon in favor of generic,
  universally understood vocabulary; verified against known-issues.mdx
  and workers/versions-and-deployments/ to avoid title collisions.
  Updated the 4 inbound link texts that quoted the old title verbatim.
- Restructure the multi-deploy max_delay explanation with an explicit
  'each deployment sets its own timer, first to expire wins' framing
  before the worked example (mathematically equivalent to the prior
  shrink-only-deadline framing, just clearer).
- Fix a real contradiction in the multi-namespace scope note (said
  'exports and binds to', which contradicted its own second sentence
  about script_name); corrected to 'exports' only, added a ctx.exports
  mention (verified against the Sep 2025 ctx.exports changelog and an
  internal engineering implementation-plan doc confirming
  code_update_strategy is deployment-scoped, independent of bindings),
  and moved it up under the parent heading so it covers all subsections.
- Restructure 'Configure a code update strategy' into four subsections
  (Options, wrangler, REST, Set strategy for a single deployment),
  folding the standalone 'What each configuration does' table into
  Options and separating wrangler/REST mechanics from the
  single-deployment motivation.
- Correct 'aliases' to 'alternatives' for wrangler deploy/rollback vs.
  their versions equivalents -- verified they hit different code paths
  and even different API endpoints, not literal aliases.
- Move the REST API 'field name not final' note to the top of that
  subsection instead of the bottom.
- Cut two redundant passages: the gradual-deployments max_delay-clocks
  aside (fully covered by the reworked timer explanation) and the last
  Limitations bullet (a general compatibility reminder already stated,
  with a link, in Gradual deployments).

Backlogged for later, not addressed in this round: a diagram for the
Configure section, converting Mermaid diagrams to Cloudflare-branded
PNGs before public launch, documenting the mixed-version
compatibility-date default rule, and documenting that named
environments do not inherit the top-level code_update_strategy.
Co-authored-by: Vy Ton <vy@cloudflare.com>
- Add a diagram illustrating the consecutive-deployments worked example
  (two overlapping max_delay timers, earlier one fires first, latest
  version still applies).
- Document the 300-second max_delay maximum in the top 'Code update
  strategy' table, not just in Wrangler config prose.
- Add a minimal Wrangler config example with no bindings entry, showing
  code_update_strategy still applies via ctx.exports alone.
- Move the CLI override flag (--durable-objects-code-update-mode) and
  its resolution order out of the Wrangler subsection and into 'Set
  strategy for a single deployment', where the flag's use case
  actually belongs; that section now leads with the code snippet
  before the motivating examples.
- Remove the REST API 'field name not yet final' reader-facing note;
  kept the equivalent internal TODO comment since the underlying
  confirmation with the API team is still unresolved.
- Reorder the REST API response section so the GET-endpoints paragraph
  precedes the JSON example it describes, instead of following it.
@cloudflare-docs-bot
cloudflare-docs-bot Bot force-pushed the durable-objects-graceful-code-updates branch from a42b669 to b2e2b88 Compare September 2, 2026 22:11
@github-actions github-actions Bot removed the stale label Sep 3, 2026

| Mode | Default `max_delay` | Behavior |
| ----------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `deferred` | 30 seconds | Cloudflare waits for an active Durable Object to hibernate before applying the update. If the object does not hibernate within `max_delay` (300 seconds maximum), Cloudflare resets it and applies the update. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find all the "Cloudflare waits for an..." odd, it's littered through the doc, I'd drop this phrasing and word it like the Durable Object. (e.g. A Durable Object waits for..." or "Code updates wait for..." is fine)

(maybe this is preferred prose in the docs, if so guess it's fine, I just find it odd)


By default, Durable Objects delay applying Worker code deployments so in-flight requests can finish. Instead of resetting an active Durable Object immediately to apply a code update, Cloudflare applies the code update once the object is inactive (is hibernated).

Deploy a Worker with `--durable-objects-code-update-mode immediate` to apply a code update right away instead of waiting. Refer to [Lifecycle of a Durable Object](/durable-objects/concepts/durable-object-lifecycle/) for more on when an object hibernates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--durable-objects-deploy-mode is better imo (shorter)


You can now set a Durable Object's code update strategy to `deferred`, which tells Cloudflare to wait for the Durable Object to hibernate before it applies the update. This lets in-flight work finish before code updates and keeps open WebSocket connections that use the [Hibernation API](/durable-objects/examples/websocket-hibernation-server/) connected.

Add `code_update_strategy` to `durable_objects` in your Wrangler configuration:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this naming differs to what's above? (e.g. durable-objects-deploy-mode above)

## How it works

1. You deploy a new version to 100% of traffic.
2. A client makes a request to a Durable Object that is not running, either an inactive object or a new object. This uses the latest version of your code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd drop either an inactive object or a new object, as it's irrelevant

Comment thread src/content/docs/durable-objects/deployments/durable-objects-code-updates.mdx Outdated
Consecutive Worker deployments have the following behavior:

- Each deployment sets its own `max_delay` timer.
- The first `max_delay` timer to expire applies the latest deployed version — not necessarily the version whose timer expired.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The first `max_delay` timer to expire applies the latest deployed version — not necessarily the version whose timer expired.
- The first `max_delay` timer to expire applies the latest deployed version to all Durable Objects with a pending code update

Maybe a bit clearer?

- Each deployment sets its own `max_delay` timer.
- The first `max_delay` timer to expire applies the latest deployed version — not necessarily the version whose timer expired.

For example: you deploy version A with `max_delay: 30`, starting a 30-second timer. Ten seconds later, you deploy version B with `max_delay: 60`, starting a separate 60-second timer. Version A's timer expires first, at the 30-second mark. When it expires, Cloudflare resets the object and applies version B — the latest deployed version — even though it was version A's timer that fired. The same is true if the object hibernates on its own before either timer expires: it always wakes up running the latest deployed version.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this less than ideal, I'm guessing it is what it is, but in extreme cases that means we could have code deployed that immediately sets a ton of objects (e.g. deploy 1 with max_delay = 100, deploy 2 with max_delay 100 finishes with 1 second left on deploy 1 -> tons of objects reset in unison)

| *(omitted)*, compatibility date before `COMPATIBILITY_DATE` | Defaults to `immediate`. |
| *(omitted)*, compatibility date on or after `COMPATIBILITY_DATE` | Defaults to `deferred` with a 30-second `max_delay`. |
| `{ "mode": "deferred" }` | Cloudflare waits up to the default `max_delay` (30 seconds) for the object to hibernate. |
| `{ "mode": "deferred", "max_delay": 0 }` | Valid, but Cloudflare waits zero seconds — behaves identically to `immediate`. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels like we should validate this is non-zero, seems odd someone would want to set this

## Limitations

- A `deferred` code update strategy is best-effort. Cloudflare does not guarantee that an object keeps running its current code for the entire `max_delay`.
- A `deferred` code update does not stop an object from accepting new requests while it waits to hibernate.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels weird as a limitation (seems good it does this, and limitation == bad usually)


- A `deferred` code update strategy is best-effort. Cloudflare does not guarantee that an object keeps running its current code for the entire `max_delay`.
- A `deferred` code update does not stop an object from accepting new requests while it waits to hibernate.
- An object that is still active when `max_delay` is reached resets the same way an `immediate` update does.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is superfluous as it's made clear through the rest of the doc

…ode-updates.mdx

Co-authored-by: Ashley Peacock <apeacock@cloudflare.com>
@cloudflare-docs-bot

Copy link
Copy Markdown
Contributor

@iglesiasbrandon This draft pull request has had no activity for 3 days. It will close after 7 days of inactivity. Transition to ready for review if ready. A codeowner can comment /draft-never-stale to keep it open.

@cloudflare-docs-bot

cloudflare-docs-bot Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ @iglesiasbrandon This pull request adds a changelog entry dated in the past:

  • src/content/changelog/durable-objects/2026-08-13-durable-objects-deferred-code-updates.mdx — dated 2026-08-13

Typically, changelog entries should be dated the day they merge. This is not blocking — if the date is unintentional, please update it.

iglesiasbrandon added a commit that referenced this pull request Sep 23, 2026
Address review feedback from @joshthoward.

Drop the websockets.mdx and durable-object-lifecycle.mdx changes. They
overlap with PR #32222 (deferred code updates) and describe code-deploy
behavior that the deferred code update work changes. Both files
conflicted with that branch.

Rescope the two error entries away from customer deploys and toward
platform events such as hardware failure. Distinguish Hibernation API
connections from Web Standard WebSocket API connections.

Drop the automatic fetch() retry claim pending confirmation that it is
a public guarantee rather than current autogated behavior.
@iglesiasbrandon

Copy link
Copy Markdown
Collaborator Author

/draft-never-stale

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

product:changelog product:durable-objects Durable Objects: https://developers.cloudflare.com/workers/learning/using-durable-objects/ size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants