docs/qwp/README.md
QuestWire Protocol is QuestDB's columnar binary protocol for high-throughput
data ingestion (/write/v4) and query result streaming (/read/v1) over
WebSocket and UDP. This directory holds the cross-language specifications that
every conformant client and server must implement to.
docs/qwp/
├── README.md this index
├── wire-ingress.md QWP1 ingest wire format (WebSocket + UDP shared core); §15.5 points at the cursor-engine reconnect loop that applies to both Memory and SF modes
├── wire-udp.md UDP-specific deviations from wire-ingress
├── wire-egress.md egress (query result streaming) wire format; §11.9 owns the per-Execute failover loop and WalkTracker
├── sf-client.md client-side cursor-engine substrate spec (Memory mode and Store-and-Forward); §13.6 owns the ingress reconnect loop
├── failover.md shared failover primitives (host-health model, backoff, role filter, error classification, cross-context defaults table)
└── design/ non-normative working notes (decision logs, backlogs)
└── egress-phase2-backlog.md
| You are writing… | Read |
|---|---|
| A new ingest client (any language), no on-disk durability | wire-ingress.md (incl. §15.5 pointing at the reconnect loop) + sf-client.md §13.6 (the loop, shared with SF mode) + failover.md §1.1 / §2 / §5 / §6 (primitives) |
| A new ingest client with durability across restarts | wire-ingress.md + sf-client.md (incl. §13.6 reconnect loop and §5–6 / §18 for the on-disk slot layout) + failover.md (primitives) |
| A UDP-only ingest client (e.g. metrics collector) | wire-ingress.md + wire-udp.md |
| A new query client (SELECT, DDL, EXEC) | wire-egress.md (incl. §11.9 failover loop + WalkTracker) + failover.md (primitives); wire-egress.md references wire-ingress.md for the shared header / type system |
| A server-side change to ingest framing | wire-ingress.md (+ wire-udp.md if UDP, + sf-client.md if it touches ACKs, durable-ack, or close-codes) |
| A server-side change to egress framing | wire-egress.md |
| A server-side change to topology / role headers | failover.md §5–6 + wire-egress.md §11.8 / §11.9 |
| Tuning the cross-context defaults (knob names, budgets) | failover.md §7 (cheat sheet) → drill into sf-client.md §4.2 or wire-egress.md §11.9.1 for the canonical knob homes |
| A bug fix that doesn't change interop | none of the above; just the code |
Layer 1 — Specs (normative). Everything in this directory's top level. Any implementation that calls itself a QWP client or server must match these byte layouts and semantics. Drift between code and spec is a bug; the fix is to update whichever is wrong, not silently diverge.
Layer 2 — Design (non-normative). Files under design/. Decision logs,
phase backlogs, evaluation notes. Useful as historical context, not as a
contract.
Layer 3 — Implementation notes. Live next to the code (Javadoc, rustdoc, inline comments). Out of scope for this directory.
The Java reference client also keeps in-flight design notes at
questdb/java-questdb-client/design/qwp-cursor-*.md. Those are decision logs
authored alongside the client implementation; for cross-language interop,
sf-client.md here is authoritative.
Each spec has a Reference Implementation footer with a commit hash. When
that hash drifts far from main, the spec is presumptively stale: re-extract
from the implementation and bump the hash. PRs that change interop semantics
(wire bytes, status codes, handshake headers, on-disk layout, ACK rules,
close-code routing) MUST update the relevant spec in the same PR.
A short checklist for spec-affecting PRs:
wire-ingress.md / wire-egress.md.sf-client.md §5–6, §18.sf-client.md §4, §8–17.initial_connect_retry semantics change? Update sf-client.md §13.6 and the §15.5 pointer in wire-ingress.md if the storage-mode framing shifts.Execute loop, WalkTracker, or OnFailoverReset contract change? Update wire-egress.md §11.9.failover.md §2 / §3 / §5 / §6 — and check that the three loop docs above still match.wire-ingress.md (incl. §15.5 pointer to the cursor-engine reconnect loop)wire-udp.mdwire-egress.md (incl. §11.9 per-Execute failover loop and WalkTracker)sf-client.mdfailover.mddesign/egress-phase2-backlog.md