Skip to content

docs(deploy): document JetStream SyncAlways durability vs throughput - #338

Merged
EricAndrechek merged 3 commits into
mainfrom
nats-durability-docs
Jun 11, 2026
Merged

EricAndrechek merged 3 commits into
mainfrom
nats-durability-docs

Conversation

@EricAndrechek

Copy link
Copy Markdown
Member

What

Adds a Durability & Storage operations page (docs/src/content/docs/durability.md) that makes the embedded-JetStream durability contract explicit, and wires it into the nav + cross-links.

The core fact this documents: WaveHouse starts embedded NATS with SyncAlways: true (internal/mq/embedded.go), so every event is fsync'd to disk before POST /v1/ingest returns 200. That makes the storage substrate's fsync tail the ingest latency floor — a deliberate, strong guarantee that was previously implicit and undocumented.

Why

Per #84, the durability/throughput tradeoff is a product decision worth documenting independently of the infra mitigation in support-infra#1. The issue author flagged this as the docs-site-publish-gating "item" (comment): operators need to know what a 200 ack guarantees and how to tell whether their storage can sustain it before they go live.

The new page covers

  • The contract — 200 = fsync'd to local disk, and how that differs from JetStream's default (ack from OS page cache, periodic background flush).
  • Why the fsync tail is the ingest floor — and why a slow substrate surfaces as create stream: ... context deadline exceeded at boot and 503 backpressure under load.
  • Where SyncAlways is cheap vs. expensive — managed cloud block storage / PLP NVMe / local ext4 vs. ZFS-without-SLOG / qcow2-on-ext4 / spinning disks.
  • Measure your own storage — an fio recipe + verdict bands (calibrated to the SyncAlways default), with the macOS F_FULLFSYNC honesty caveat.
  • Symptom checklist — what bad storage looks like in practice.

Cross-links / wiring

  • Registered in docs/src/config/sidebar.ts under Operations (between Deployment and Behind a reverse proxy; reverse-proxy's sidebar.order bumped 11→12).
  • Cross-linked from Configuration → Message Queue (NATS), Deployment → Persistent Storage, and Ingest Pipeline → Backpressure and durability knobs (which already documents the worker-side ack cost — this page owns the producer-side contract, no duplication).
  • CHANGELOG.md [Unreleased] → Added.

Scope (and what's intentionally out of it)

This PR is the documentation deliverable of #84. It does not:

I used "Documents #84" rather than "Closes #84" so the issue stays open to track those two remaining deliverables. Suggest splitting the storage-check CLI into its own issue and closing #84 once the docs land, or keeping it open until the CLI ships — reviewer's call.

Testing

  • make build-docs ✅ — 21 pages built, starlight-links-validator clean (all new cross-link anchors resolve), astro check passes.
  • make verify ✅ (pre-commit) — markdownlint, misspell, astro content-schema check.
  • Docs-only change (scripts/classify-paths.sh → code=false), so no Go/SDK suites apply.

🤖 Generated with Claude Code

WaveHouse runs embedded NATS JetStream with SyncAlways=true
(internal/mq/embedded.go), so every event is fsync'd to disk before
POST /v1/ingest returns 200 — making the storage substrate's fsync tail
the ingest latency floor. That contract was implicit and undocumented.

Add an Operations guide (docs/src/content/docs/durability.md) covering:
- what a 200 ack guarantees vs JetStream's default page-cache mode
- why a slow fsync tail surfaces as `create stream: context deadline
  exceeded` and 503 backpressure
- where SyncAlways is cheap vs expensive (cloud block storage / PLP NVMe
  vs ZFS-without-SLOG / qcow2-on-ext4 / spinning disks)
- an fio recipe + verdict bands to measure your own storage, with the
  macOS F_FULLFSYNC honesty caveat
- symptom checklist

Forward-references the configurable group-commit interval
(mq.sync_interval, #139) and the planned `wavehouse storage-check`
preflight (#84) without claiming either exists yet. Register the page in
the sidebar and cross-link from Configuration, Deployment, and the Ingest
Pipeline's worker-side ack section.

Documents #84.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 11, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8270544f-7014-417e-88b9-6a155ebe4813

📥 Commits

Reviewing files that changed from the base of the PR and between 3d0f4aa and 309a691.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • docs/src/content/docs/configuration.mdx
  • docs/src/content/docs/deployment.md
📜 Recent review details
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Docs build
  • GitHub Check: Lint
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🧰 Additional context used
📓 Path-based instructions (1)
docs/src/content/docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

docs/src/content/docs/**/*.{md,mdx}: Author Mermaid diagrams vertically (flowchart TB/TD) to fit page column width (~46–58rem); reserve LR for genuinely short chains (≤3–4 nodes)
Keep Mermaid node labels short; use
for a second line rather than one long line; lean on semantic node classes (wh, win, pain, fail, infra, neutral, store, client)
Never sit two large diagrams side-by-side; wrap comparisons in

…
to stack them vertically

Files:

  • docs/src/content/docs/deployment.md
  • docs/src/content/docs/configuration.mdx
🧠 Learnings (1)
📚 Learning: 2026-06-10T15:01:09.027Z
Learnt from: EricAndrechek
Repo: Wave-RF/WaveHouse PR: 312
File: docs/src/content/docs/development.md:0-0
Timestamp: 2026-06-10T15:01:09.027Z
Learning: In this repo’s Markdown review (all .md files), do not flag capitalization/style issues for literal paths starting with ".github/" (or any substring that is a path beginning with ".github/"). Treat ".github" as the correct lowercase dotfile directory name, even when it appears inside prose or code spans; automated checks such as LanguageTool’s "(GITHUB)" rule commonly produce false positives for this literal filesystem path.

Applied to files:

  • CHANGELOG.md
  • docs/src/content/docs/deployment.md
🪛 LanguageTool
docs/src/content/docs/configuration.mdx

[typographical] ~128-~128: The word ‘When’ starts a question. Add a question mark (“?”) at the end of the sentence.
Context: ...ized regardless of the sub-toggles below. The OTLP endpoint, TLS, custom CA, mutu...

(WRB_QUESTION_MARK)

🔇 Additional comments (6)
docs/src/content/docs/configuration.mdx (3)

67-67: LGTM!


124-128: LGTM!


207-209: LGTM!

docs/src/content/docs/deployment.md (2)

174-174: LGTM!


358-433: LGTM!

CHANGELOG.md (1)

93-93: LGTM!

Also applies to: 207-207


📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Added comprehensive "Durability & Storage" operations guide explaining embedded JetStream ingest durability, fsync latency’s impact on ingest performance and backpressure, common failure symptoms, and storage assessment/benchmark guidance
    • Added brief durability guidance to configuration and deployment docs and cross-linked related pages
    • Added the new "Durability & Storage" entry to the docs sidebar and updated sidebar ordering for the reverse-proxy page

Walkthrough

This PR adds comprehensive documentation of WaveHouse durability guarantees under embedded JetStream with SyncAlways: true, including a new Durability & Storage operations guide, storage latency impact analysis, benchmarking procedures, and cross-references integrated into configuration and deployment documentation.

Changes

Durability & Storage Operations Documentation

Layer / File(s) Summary
Durability page and sidebar registration
docs/src/content/docs/durability.md, docs/src/config/sidebar.ts
New durability.md page (103 lines) explains JetStream SyncAlways semantics, how fsync latency becomes the ingest-latency floor, storage substrate guidance, fio benchmarking procedure with latency-band interpretation, macOS fsync() vs F_FULLFSYNC caveat, and symptom checklist for insufficient storage. sidebar.ts registers the page under Operations with slug durability.
Cross-linking from existing documentation
docs/src/content/docs/configuration.mdx, docs/src/content/docs/deployment.md, docs/src/content/docs/reverse-proxy.mdx
configuration.mdx adds a durability block describing JetStream SyncAlways and ingest-latency floor (references issue #139). deployment.md documents that JetStream fsyncs to <data_dir>/nats before ingest returns and links to Durability & Storage. reverse-proxy.mdx increments sidebar.order from 11 to 12.
Changelog entry
CHANGELOG.md
Unreleased changelog documents the Durability & Storage guide, durability contract, storage-latency effects, measurement guidance, cross-references, and notes there are no code changes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

  • #139: Documentation aligns with and cross-references the JetStream SyncAlways durability behavior tracked in issue #139; this PR documents the current embedded behavior without code changes.
  • #84: This PR provides the documentation component of the broader durability/storage strategy; issue #84 tracks future enhancements including configurable sync modes, storage benchmarking tooling, and platform-specific fsync guidance.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'docs(deploy): document JetStream SyncAlways durability vs throughput' directly summarizes the main change—adding documentation for JetStream durability guarantees and their throughput implications.
Description check ✅ Passed The description thoroughly explains the purpose, scope, and implementation of the new documentation page, including cross-links and intentional exclusions of future work items.
Linked Issues check ✅ Passed The PR delivers the documentation portion of #84 as specified, covering durability contract, storage assessment guidance, and symptom checklist. However, it intentionally omits the config knob (#139) and CLI tool, which are tracked as separate deliverables.
Out of Scope Changes check ✅ Passed All changes are strictly documentation and sidebar configuration updates in scope. The PR explicitly excludes the mq.sync_interval config knob and wavehouse storage-check CLI as separate tracked issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nats-durability-docs
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch nats-durability-docs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added documentation Improvements or additions to documentation area/docs Documentation, site/, README labels Jun 11, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e9b01932-286f-4f62-8e6e-215c3604c34d

📥 Commits

Reviewing files that changed from the base of the PR and between 46d92e7 and 3d0f4aa.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • docs/src/config/sidebar.ts
  • docs/src/content/docs/configuration.mdx
  • docs/src/content/docs/deployment.md
  • docs/src/content/docs/durability.md
  • docs/src/content/docs/reverse-proxy.mdx
📜 Review details
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Docs build
  • GitHub Check: Lint
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Markdown files must pass markdownlint style checks (enforce via make lint)

Files:

  • docs/src/content/docs/durability.md
  • docs/src/content/docs/deployment.md
  • CHANGELOG.md
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

Markdown documentation files must pass docs-prose review (accuracy vs. code, examples, clarity, completeness); scope is canonical set from scripts/docs-prose.sh excluding .claude/**, .github/**, CHANGELOG.md, AGENTS.md, CLAUDE.md, *.draft.md, *.old.md

Files:

  • docs/src/content/docs/durability.md
  • docs/src/content/docs/deployment.md
  • CHANGELOG.md
  • docs/src/content/docs/reverse-proxy.mdx
  • docs/src/content/docs/configuration.mdx
docs/src/content/**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

When authoring Mermaid diagrams in Markdown: author vertically (top-down default, flowchart TB/TD) to fit page column (~46–58rem); keep node labels short with <br/> for multi-line; use semantic node classes (wh, win, pain, fail, infra, neutral, store, client); never sit two large diagrams side-by-side without <div class="diagram-pair"> wrapper

Files:

  • docs/src/content/docs/durability.md
  • docs/src/content/docs/deployment.md
  • docs/src/content/docs/reverse-proxy.mdx
  • docs/src/content/docs/configuration.mdx
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

TypeScript/JavaScript code must use strict formatting enforced by Biome (markdownlint for Markdown style, misspell for spelling)

Files:

  • docs/src/config/sidebar.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

TypeScript code must pass type checking via tsc (TypeScript compiler)

Files:

  • docs/src/config/sidebar.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

TypeScript/JavaScript import statements must follow ESM (ECMAScript modules) conventions; use import not require unless Node.js tooling requires it

Files:

  • docs/src/config/sidebar.ts
🧠 Learnings (1)
📚 Learning: 2026-06-10T15:01:09.027Z
Learnt from: EricAndrechek
Repo: Wave-RF/WaveHouse PR: 312
File: docs/src/content/docs/development.md:0-0
Timestamp: 2026-06-10T15:01:09.027Z
Learning: In this repo’s Markdown review (all .md files), do not flag capitalization/style issues for literal paths starting with ".github/" (or any substring that is a path beginning with ".github/"). Treat ".github" as the correct lowercase dotfile directory name, even when it appears inside prose or code spans; automated checks such as LanguageTool’s "(GITHUB)" rule commonly produce false positives for this literal filesystem path.

Applied to files:

  • docs/src/content/docs/durability.md
  • docs/src/content/docs/deployment.md
  • CHANGELOG.md
🪛 LanguageTool
docs/src/content/docs/durability.md

[style] ~34-~34: Consider using the typographical ellipsis character here instead.
Context: ...hem exceed it. The boot-time symptom is create stream: ... context deadline exceeded. - If the wo...

(ELLIPSIS)

🔇 Additional comments (12)
docs/src/content/docs/durability.md (8)

1-6: LGTM!


8-10: LGTM!


12-27: LGTM!


29-35: LGTM!


37-57: LGTM!


59-88: LGTM!


90-97: LGTM!


99-103: LGTM!

docs/src/config/sidebar.ts (1)

49-49: LGTM!

docs/src/content/docs/configuration.mdx (1)

67-67: LGTM!

docs/src/content/docs/deployment.md (1)

174-174: LGTM!

docs/src/content/docs/reverse-proxy.mdx (1)

5-5: LGTM!

Comment thread CHANGELOG.md
@github-project-automation github-project-automation Bot moved this from Backlog to In review in WaveHouse Task Board Jun 11, 2026
@github-actions

github-actions Bot commented Jun 11, 2026 •

Copy link
Copy Markdown

📚 Docs preview is live → https://b3c4ad11-wavehouse-docs.wave-rf.workers.dev

  • Commit — 309a691: Merge branch 'main' into nats-durability-docs
  • Author — @EricAndrechek
  • Committed — 2026-06-11 08:50 (UTC-04:00)
  • Deployed — 2026-06-11 08:53 EDT

@EricAndrechek
EricAndrechek marked this pull request as ready for review June 11, 2026 12:51
@EricAndrechek
EricAndrechek requested review from a team and taitelee June 11, 2026 12:51
@EricAndrechek
EricAndrechek merged commit 26b9866 into main Jun 11, 2026
28 of 34 checks passed
@EricAndrechek
EricAndrechek deleted the nats-durability-docs branch June 11, 2026 12:56
@github-project-automation github-project-automation Bot moved this from In review to Done in WaveHouse Task Board Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docs Documentation, site/, README documentation Improvements or additions to documentation

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

docs(deploy): JetStream SyncAlways=true durability vs throughput on commodity storage

1 participant