Skip to content

[DO] Document outbound connections keep Durable Objects alive#31324

Draft
iglesiasbrandon wants to merge 5 commits into
productionfrom
do/outbound-connections-keep-alive
Draft

[DO] Document outbound connections keep Durable Objects alive#31324
iglesiasbrandon wants to merge 5 commits into
productionfrom
do/outbound-connections-keep-alive

Conversation

@iglesiasbrandon

Copy link
Copy Markdown
Collaborator

Summary

Documents the behavior change shipped in May 2026 where active outbound connections (TCP connect() and outbound WebSockets) now keep a Durable Object alive and prevent eviction for the duration of the connection, up to a 15-minute per-connection cap.

Before this change, the routing supervisor would evict a DO after 70–140 seconds of inactivity even if it had an open outbound connection — causing mid-stream evictions when, for example, streaming tokens from an LLM over a long-lived TCP socket.

Changes:

File Change
concepts/durable-object-lifecycle.mdx Added outbound connections as a 5th hibernation-blocking condition; added a :::note block explaining the keepalive behavior, billing impact, 15-min cap, and that plain fetch() is excluded
best-practices/websockets.mdx Clarified that outgoing WebSockets don't hibernate but do keep the DO alive — these were previously conflated
platform/pricing.mdx Added billing caveat: an outbound connection keeps a DO in the billable non-hibernateable state even with no incoming requests
runtime-apis/tcp-sockets.mdx Added Considerations bullet noting that a connect() socket opened inside a DO pins it for up to 15 minutes
changelog/durable-objects/2026-06-19-...mdx New changelog entry

Key accuracy notes verified against the merged implementation:

  • 15-minute cap (DEFAULT_HARD_LIMIT = 15 * kj::MINUTES) is exact
  • After the cap fires, the connection continues operating — only the DO pinning ends
  • Plain fetch() is explicitly excluded (pass-through, no keepalive effect, even while streaming)
  • fetch() upgraded to WebSocket via Upgrade: websocket IS covered

Documentation checklist

@github-actions github-actions Bot added product:workers Related to Workers product product:durable-objects Durable Objects: https://developers.cloudflare.com/workers/learning/using-durable-objects/ product:changelog size/s labels Jun 8, 2026
@github-actions

github-actions Bot commented Jun 8, 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/ @cloudflare/pm-changelogs, @cloudflare/product-owners
/src/content/docs/durable-objects/ @elithrar, @rita3ko, @irvinebroque, @vy-ton, @iglesiasbrandon, @joshthoward, @danlapid, @oxyjun, @lambrospetrou, @mikenomitch, @cloudflare/product-owners
/src/content/docs/workers/ @cloudflare/workers-docs, @GregBrimble, @irvinebroque, @mikenomitch, @korinne, @WalshyDev, @cloudflare/deploy-config, @cloudflare/product-owners, @cloudflare/wrangler, @MattieTK, @cloudflare/dev-plat-leads, @vy-ton

@ask-bonk ask-bonk Bot left a comment

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.

Reviewed 5 files. 4 issues need addressing before merge.

MEDIUM — Style guide and accuracy:

  • line 9: Spell out LLM on first use per the style guide.
  • line 11: 'keepalive token' is an implementation detail; describe behavior instead.
  • line 70: 'remains in-memory' should be 'remains in memory' (hyphenate compound modifiers only before a noun).
  • line 192: Parenthetical grammar is awkward; rephrase.

Comment thread src/content/docs/durable-objects/concepts/durable-object-lifecycle.mdx Outdated
Comment thread src/content/docs/workers/runtime-apis/tcp-sockets.mdx Outdated
@ask-bonk

ask-bonk Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review posted on PR #31324.

Labels: Already correctly labeled with product:durable-objects, product:workers, product:changelog, and size/s. No changes needed.

Summary: This PR documents the May 2026 behavior change where active outbound TCP sockets (connect()) and outbound WebSockets keep a Durable Object alive and prevent eviction, up to a 15-minute cap per connection. It updates 5 files: a new changelog entry, the DO lifecycle concept page, WebSockets best practices, DO pricing, and the TCP sockets runtime API reference.

Issues flagged: 4 inline suggestions posted.

  1. changelog/durable-objects/2026-06-19-...mdx line 9 — Spell out "large language model (LLM)" on first use per the style guide.
  2. changelog/durable-objects/2026-06-19-...mdx line 11 — Remove "keepalive token" (implementation detail); describe the user-visible behavior directly.
  3. concepts/durable-object-lifecycle.mdx line 70 — Fix hyphenation: "remains in memory" (predicate), not "remains in-memory" (only hyphenate compound modifiers before a noun).
  4. runtime-apis/tcp-sockets.mdx line 192 — Fix awkward parenthetical grammar: rephrase "keeps the Durable Object in memory (and incurring duration charges)" to flow correctly.

github run

iglesiasbrandon and others added 4 commits June 8, 2026 20:08
…ections-keep-dos-alive.mdx

Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
…ections-keep-dos-alive.mdx

Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
…ycle.mdx

Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com>

@irvinebroque irvinebroque left a comment

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.

  • Can we get a diagram here that shows this — like how we did one for this? #29722 (comment)
  • can we explain/show in context of building agents on cloudflare?

date: 2026-06-19
---

Durable Objects now remain alive for the duration of active outbound connections created via [`connect()`](/workers/runtime-apis/tcp-sockets/) or an outbound WebSocket. Previously, the routing supervisor would evict a Durable Object after 70-140 seconds of no incoming traffic, even if the object had an open outbound connection — a common pattern when streaming responses from a large language model (LLM) or other long-lived upstream API.

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.

What about connections to Hyperdrive or other bindings?

date: 2026-06-19
---

Durable Objects now remain alive for the duration of active outbound connections created via [`connect()`](/workers/runtime-apis/tcp-sockets/) or an outbound WebSocket. Previously, the routing supervisor would evict a Durable Object after 70-140 seconds of no incoming traffic, even if the object had an open outbound connection — a common pattern when streaming responses from a large language model (LLM) or other long-lived upstream API.

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.

"routing supervisor"

^ very internal language


With this change, each active outbound connection prevents eviction. Once all outbound connections close, the standard 70-140 second inactivity window applies before the Durable Object is evicted.

This applies to outbound TCP sockets (`connect()`) and outbound WebSockets, including a `fetch()` request upgraded to a WebSocket via `Upgrade: websocket`. Plain `fetch()` subrequests never keep a Durable Object alive — they are pass-through and have no effect on DO lifetime, even while the response body is still streaming.

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.

Above we are talking about LLM calls - but here we are saying your DO can get terminated even if just waiting on fetch() to an LLM - which is it?


**Limits:**

- Each outbound connection pins the Durable Object for a maximum of **15 minutes**. After 15 minutes, the connection stops preventing eviction (the connection itself continues operating), and normal eviction rules resume.

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.

Define "pins" or use more precise language?

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.

"normal eviction rules" — as a customer how do I know what these are? where do i look?

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/ product:workers Related to Workers product size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.