Skip to content

docs: document request body streaming and upstream HTTP/2 - #47

Merged
slin1237 merged 2 commits into
mainfrom
docs/request-streaming-upstream-http2
Sep 24, 2026
Merged

slin1237 merged 2 commits into
mainfrom
docs/request-streaming-upstream-http2

Conversation

@slin1237

Copy link
Copy Markdown
Member

v1.10.0 reworked how the HTTP router handles request bodies and upstream connections.

  • Large request bodies stream to the worker instead of being buffered (feat(router): stream large request bodies past a size threshold smg#2198).
  • The router now decides stream-vs-buffer per request (#2286). The --stream-request-bodies-over flag from pre-release builds was removed before v1.10.0 shipped.
  • A stalled upload is aborted with 408 (#2201). Request buffers are freed at dispatch (#2232, #2237), and worker responses are capped (#2138).
  • HTTP/2 to workers is opt-in and negotiated per worker (#2155, #2407). Pooled connections expire before the backend's keep-alive, and a send that fails before any response is resent once (#2162).

None of this was documented. The retries page also had several errors:

  • It miscounted attempts. --retry-max-retries includes the first attempt.
  • It listed a backoff delay that the defaults never reach.
  • It described half-open circuits as "limited test requests".
  • It had no word on streamed bodies or on responses that are never retried.

Changes

  • New concept page, concepts/performance/request-streaming.md ("Request Streaming and Upstream Connections"):
    • Which routes and router modes can stream.
    • The ordered stream-vs-buffer rules, each with its reason metric label.
    • What changes for a streamed request: no router retries, and validation happens at the worker.
    • The 408/413/400 upload aborts.
    • Memory bounds and response relaying: backpressure, cancel on disconnect, empty h2 frames, TCP_NODELAY.
    • Connection pools and http_pool overrides, and the one-shot resend.
    • Upstream HTTP/2: negotiation, what traffic uses it, pinning, checking, and mixed-fleet rollout.
    • Configuration and metrics.
  • concepts/reliability/retries.md:
    • How a retry works: attempts include the first, and selection is re-run.
    • Where retries apply, by router and endpoint.
    • A corrected backoff table with jitter ranges.
    • A new "Never Retried" section: overload sheds, tenant denials, and admission rejections.
    • Retries and request bodies, and the pre-response resend.
    • A rewritten circuit-breaker interaction, with capacity pushback retried but not counted.
    • Metrics labels and PromQL fixes.
    • The per-worker resilience retry fields are documented as having no effect in v1.11.0. See docs(api): document the full worker spec for the worker management API #43: registration never stores them on the worker, so no per-model retry policy is created.
  • Nav and concepts index: the page is listed under Performance.

Verification

  • Checked against smg v1.11.0 (3be823a7):
    • routers/common/body_policy.rs, routers/http/{router,request_stream,request_body}.rs, routers/common/request_lease.rs
    • worker/http_client.rs, workflow/steps/local/detect_connection.rs
    • crates/external_router/src/{retry,retry_config,sse,header_utils}.rs, workflow/steps/shared/register.rs
    • main.rs and observability/metrics.rs
  • pnpm lint, pnpm check (0 errors), and pnpm build pass.
  • The link check shows only pages added by sibling PRs: sticky-sessions.md (docs(routing): document sticky sessions and routing headers #42) and overload-protection.md (docs(reliability): document worker overload protection and load monitoring #37).
  • All three pages render with status 200 under wrangler pages dev.

This is one of a series of docs PRs that bring the site up to smg v1.11.0, one per area.

🤖 Generated with Claude Code

Add concepts/performance/request-streaming.md: per-request stream-vs-buffer
decision (smg-project/smg#2198, #2286, #2202, #2355), stall and size aborts
(#2201), memory bounds and response relays (#2232, #2237, #2138, #2097,
#2136, #2488), upstream HTTP/2 and pooling (#2155, #2407, #2218, #2162).
Fix retries.md for v1.11: attempt counting, streamed and terminal exclusions,
capacity pushback (#2163), per-worker overrides, metrics and PromQL.

Signed-off-by: Simo Lin <25425177+slin1237@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 39 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available. Your 64 included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 296871ab-1a96-40f4-a963-c88e3ed1a402

📥 Commits

Reviewing files that changed from the base of the PR and between 7362b40 and a369a71.

📒 Files selected for processing (4)
  • src/lib/config/concepts-nav.ts
  • src/lib/content/concepts/index.md
  • src/lib/content/concepts/performance/request-streaming.md
  • src/lib/content/concepts/reliability/retries.md

Comment @coderabbitai help to get the list of available commands.

…ing details

- smg_worker_retry_backoff_seconds is exported as a summary (no bucket
  matcher applies), so query its quantile series instead of
  histogram_quantile over _bucket
- In regular HTTP mode an upstream timeout is a 500, not a 504; PD
  transport failures are 502
- An out-of-range --retry-jitter-factor fails validation at startup
  instead of being clamped
- Per-worker retry fields: describe why no per-model policy is created
- Use smg launch in every example
- A declared Content-Length over --max-payload-size gets a plain 413
  before routing; the worker-response cap applies in regular HTTP mode
- Client disconnects cancel the upstream request (an HTTP/2 stream is
  reset, not the shared connection)
- HTTP/2 negotiation: pinning and the flag skip only the version probe,
  and http2/smg_worker_http2 reflect the registration-time choice

Signed-off-by: Simo Lin <25425177+slin1237@users.noreply.github.com>
@slin1237
slin1237 merged commit 66b73c9 into main Sep 24, 2026
8 checks passed
@slin1237
slin1237 deleted the docs/request-streaming-upstream-http2 branch September 24, 2026 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant