For AI agents: the complete documentation index is at llms.txt. Every page is also available as markdown by appending .md to its URL, or by sending an Accept: text/markdown request header.

QuestDB Wire Protocol (QWP)

QWP is QuestDB's columnar binary protocol for high-throughput data ingestion (/write/v4) and streaming query results (/read/v1) over WebSocket and UDP. These properties control protocol limits, browser connections, and the UDP receiver. WebSocket ingestion and egress share the HTTP server's network settings (port, TLS, worker threads); see HTTP server configuration for those.

Protocol limits​

qwp.max.rows.per.table​

  • Default: 1000000
  • Reloadable: no

Maximum number of rows per table block in a single QWP message. The server rejects batches that exceed this limit with a parse error.

qwp.max.tables.per.connection​

  • Default: 10000
  • Reloadable: no

Maximum number of distinct tables a single connection may write to. The server rejects messages referencing additional tables once this limit is reached.

qwp.max.uncommitted.rows​

  • Default: 1000000
  • Reloadable: no

Maximum number of rows that may sit uncommitted in WAL writers across FLAG_DEFER_COMMIT frames before the server forces a commit. This is the server-side bound on the batch-splitting mechanism described in the QWP ingress protocol.

Browser connections​

A browser sends an Origin header with every WebSocket upgrade. QuestDB accepts browser upgrades on the QWP routes when the page has the same origin as QuestDB, and rejects other origins unless they are listed here. These settings are used by web applications built on the browser client. Clients that send no Origin header, such as the Node.js client, are not affected.

qwp.browser.allowed.origins​

  • Default: empty
  • Reloadable: yes

Comma-separated list of browser origins, besides QuestDB's own, that may open QWP WebSockets on /write/v4 and /read/v1, for example https://app.example.com,https://desk.example.com:8443. Write each origin exactly as browsers send it: scheme and lowercase host, a port only when it is not the default for the scheme, and no path, trailing slash, or wildcard. An entry in any other form stops the server from starting. A change applied with reload_config() that contains such an entry is ignored, the previous list stays in force, and the error appears only in the server log.

With authentication enabled, an upgrade from a listed origin must carry its credential in the WebSocket subprotocol, which the browser client sends when configured with auth. QuestDB accepts that credential only from a listed origin, so a page served from QuestDB's own origin that uses auth must list that origin too. QuestDB ignores session cookies on cross-origin upgrades. List only trusted applications: a listed origin can open authenticated connections to the server. The setting does not enable CORS on the REST API.

qwp.browser.tls.termination.enabled​

  • Default: false
  • Reloadable: no

Treats plain HTTP connections as secure when checking whether a browser upgrade is same-origin. Enable it when a reverse proxy terminates TLS and forwards to QuestDB over plain HTTP: otherwise the page's https:// origin does not match the plain connection, and browser upgrades fail. The proxy must forward the browser's original Host header, port included, because QuestDB compares it with the Origin header. Enable this setting only when QuestDB's HTTP port is reachable through the proxy alone.

Egress​

qwp.egress.compression.force.level​

  • Default: 0 (off)
  • Reloadable: yes

Forces a server-side zstd compression level for query result batches, overriding the level the client requests via X-QWP-Accept-Encoding. 0 disables the override and honours the client's request. Any other value must be in the range 1-9; the server refuses to start otherwise.

UDP receiver​

note

The QWP UDP receiver is a fire-and-forget ingestion path for metrics workloads where occasional message loss is acceptable. It is disabled by default. For reliable ingestion, use the WebSocket transport.

qwp.udp.bind.to​

  • Default: 0.0.0.0:9007
  • Reloadable: no

IP address and port the UDP receiver binds to. The default listens on all network interfaces on port 9007.

qwp.udp.commit.interval​

  • Default: 2000 (milliseconds)
  • Reloadable: no

Time interval between commits for data received over UDP. Lower values reduce the window of uncommitted data at the cost of more frequent I/O.

qwp.udp.enabled​

  • Default: false
  • Reloadable: no

Enable or disable the QWP UDP receiver.

qwp.udp.join​

  • Default: 224.1.1.1
  • Reloadable: no

Multicast group address the UDP receiver joins. Only relevant when qwp.udp.unicast is false.

qwp.udp.max.uncommitted.datagrams​

  • Default: 1048576
  • Reloadable: no

Maximum number of uncommitted datagrams before the receiver forces a commit, regardless of the time-based commit interval.

qwp.udp.msg.buffer.size​

  • Default: 65536 (bytes)
  • Reloadable: no

Size of each message buffer allocated for the UDP receiver.

qwp.udp.msg.count​

  • Default: 10000
  • Reloadable: no

Number of message buffers to pre-allocate. Higher values absorb larger bursts at the cost of more memory.

qwp.udp.own.thread​

  • Default: true
  • Reloadable: no

When true, the UDP receiver runs in a dedicated thread with a busy-spin loop for lowest latency. When false, the receiver uses the shared worker pool.

qwp.udp.own.thread.affinity​

  • Default: -1 (no affinity)
  • Reloadable: no

CPU core affinity for the dedicated UDP receiver thread. A value of -1 lets the OS schedule the thread. Only applies when qwp.udp.own.thread is true.

qwp.udp.receive.buffer.size​

  • Default: -1 (OS default)
  • Reloadable: no

OS-level socket receive buffer size in bytes. A value of -1 uses the operating system's default. Increase this if you observe datagram drops under high throughput.

qwp.udp.unicast​

  • Default: true
  • Reloadable: no

When true, the UDP receiver operates in unicast mode. When false, it joins the multicast group specified by qwp.udp.join.