Download Latest Version 10.0.1 source code.zip (75.5 MB)
Email in envelope

Get an email when there's a new version of QuestDB

Home / 10.0.0
Name Modified Size InfoDownloads / Week
Parent folder
questdb-10.0.0-no-jre-bin.tar.gz 2026-08-06 36.3 MB
questdb-10.0.0-rt-linux-x86-64.tar.gz 2026-08-06 97.6 MB
questdb-10.0.0-rt-windows-x86-64.tar.gz 2026-08-06 88.5 MB
10.0.0 source code.tar.gz 2026-08-06 67.6 MB
10.0.0 source code.zip 2026-08-06 74.4 MB
README.md 2026-08-06 39.3 kB
Totals: 6 Items   364.5 MB 6

QuestDB 10.0.0

QuestDB 10.0.0 is a major release, bringing three key new features into general availability, alongside a host of performance upgrades, bugfixes, and ergonomic improvements, that make QuestDB 10.0.0 easier than ever to build and scale with.

This release includes QWP, the QuestDB Wire Protocol, which supercedes ILP and PG Wire. The protocol is compressed binary, columnar, and pipelined over WebSockets, and should be used for both ingress and egress going forward, though the other protocols are retained for backwards compatibility. The new clients are smart, with the ability to buffer up data locally and automatically failover between your instances, helping to ensure ~0s RPO.

Live Views allow you to incrementally maintain and cache a window-function result set, with millisecond update latency. This cements QuestDB's already stellar performance for dashboarding and charting workflows, alongside the existing Materialized Views, which cover aggregations.

Web Console 2.0 is a significant overhaul to the QuestDB Web Console, bringing new Notebooks and coding-agent integration. The Notebooks feature offers Jupyter-style notebook support, for literate text, images, code, and live charts. MCP integration with your favourite coding agent helps you build trading dashboards and analyse data directly from your console.

But outside of the headline features, we've overhauled many internal mechanisms, and brought a host of performance improvements and bugfixes, making QuestDB 10.0 the most reliable version yet.

Read the release post: QuestDB 10.0: one binary protocol, in and out

For any questions or feedback, please join us on Slack or on Discourse.

See also our prettier release notes page.

Highlights

QWP: a new protocol for ingestion and queries

QWP — the QuestDB Wire Protocol — is new in 10.0.0. It is a binary, columnar protocol over WebSocket that carries both directions of your workload on one connection: rows in, results out. It runs on the existing HTTP port, so there is no new port to open and nothing to enable server-side. ILP and PG Wire are retained for backwards compatibility, but we recommend adopting QWP going forward.

One handle serves the whole deployment, pooling connections for both roles, and managing reconnection for you:

:::java
try (QuestDB db = QuestDB.connect("ws::addr=localhost:9000;")) {
    try (Sender sender = db.borrowSender()) {
        sender.table("trades").symbol("symbol", "ETH-USD")
              .doubleColumn("price", 2615.54).atNow();
    }
    try (Query q = db.borrowQuery()) {
        q.sql("SELECT price FROM trades WHERE symbol = $1")
                .binds(b -> b.setVarchar(0, "BTC-USD"))
                .handler(handler).submit().await();
    }
}

Fast ingress

ILP is a relatively inefficient protocol, sending key=value text pairs over the wire. Though we mitigated this for some data types (doubles, arrays) by sending binary values, the protocol was limiting and inflexible.

QWP instead sends fully-typed columns, with each frame of rows compressed before sending. A typical row when sent over QWP will take 3-4x less space when compared to ILP (TSBS schema).

Additionally, the protocol pipelines requests over WebSockets, meaning it can achieve tens of millions of rows/second on a single connection.

See the latest benckmark.

Fast egress

PG Wire has been our query protocol of choice for years, and we're still keeping it for compatibility purposes. However, the protocol itself has many edge cases, and is fundamentally row-oriented. This makes sense for an OLGP database like Postgres, but not for our time-series use case, where users frequently pull very large results set from the database.

QWP is also an query protocol, with unparalleled egress performance, achieving in excess of 200M rows/second, with first-batch latency of a handful of milliseconds. This includes native integration with Arrow/Polars/Pandas in the Python client, allowing you to run analysis externally without introducing latency.

See the latest benchmark .

Store-and-forward

When writing rows to a QWP Sender, the data is no longer ephemeral. The new store-and-forward mechanism buffers up data locally before streaming it to QuestDB. In the event of a network disconnect, the data is retained and replayed later.

Durability is an explicit choice: the default memory mode survives process restarts but not host power loss, sf_durability=periodic checkpoints to disk on a cadence, and request_durable_ack=on waits for the server to confirm durability end-to-end.

The client also supports smart failover; you can configure multiple addr endpoints, enable automated failover, and assign a priority to preferentially reconnect to the primary or to a replica.

The combination of these features makes it easy to achieve ~0s RPO on a QuestDB Enterprise deployment.

See the docs.

Client QWP status
Java, C/C++, Rust, Python Full support
Go, .NET Beta — most features, not full compatibility
Node.js Coming in a later release

Live Views (Beta)

A Live View incrementally maintains a window function result set, with WAL-table backing for durability. This complements the existing Materialized Views, which store aggregate results, but brings a new in-memory tier, allowing for millisecond-tier update latencies.

This closes a gap for charting and dashboarding use cases, making it easier than ever to run analysis and trading indicators that scale gracefully as your dataset grows.

:::sql
CREATE LIVE VIEW trades_ma
FLUSH EVERY 1s
IN MEMORY 5s
START FROM NOW
AS
SELECT timestamp, symbol, price,
       avg(price) OVER (
           PARTITION BY symbol
           ORDER BY timestamp
           ROWS 300 PRECEDING
       ) AS moving_avg
FROM trades;

Refresh and flush are decoupled, which is what keeps reads fresh without paying for a write per row. Computed rows land in an in-memory tier immediately; FLUSH EVERY controls when they are persisted to the view's own WAL. A SELECT sees the un-flushed lead, so freshness tracks base-apply latency rather than the flush cadence. IN MEMORY sizes how much recent output stays resident.

START FROM decides what the view contains, and is mandatory because the two ends differ by orders of magnitude. NOW resolves the create-time instant and costs almost nothing; BEGINNING seeds from the base table's whole history; an explicit timestamp literal starts from a point you choose. Membership is decided by a row's designated timestamp, not by when it was committed, so the view's contents are the same whether or not a replay has happened.

Anchored windows cover the other common shape — a cumulative aggregate that resets on a boundary, which is what daily PnL, month-to-date volume, or average price since the open actually need:

:::sql
CREATE LIVE VIEW IF NOT EXISTS core_price_lv
FLUSH EVERY 5s IN MEMORY 5s START FROM NOW
AS SELECT timestamp, symbol, bid_price,
          avg(bid_price) OVER w AS moving_avg
FROM core_price
WINDOW w AS (
    PARTITION BY symbol
    ORDER BY timestamp
    ANCHOR DAILY '00:00'
);

ANCHOR DAILY '00:00' resets each partition's aggregate at midnight UTC; add an IANA time zone when the boundary should follow local civil time.

Start with the live views concept page and CREATE LIVE VIEW.

Web Console 2.0: notebooks and coding agents

The bundled Web Console moves to 2.0, and the headline addition is notebooks: a saved document of SQL cells, each rendering as a grid or a chart, that you build up and re-run instead of keeping a scratch query around.

  • Cells have a view toggle and an auto-refresh interval, so a notebook doubles as a live dashboard.
  • A coding agent can author and edit cells for you, including edits that run in the background while you keep working. QuestDB's MCP server exposes your instance to agents outside the console too.
  • Large notebooks stay responsive — charts, grids and editors are virtualized, and cells lazy-hydrate.

Outside notebooks: the result grid is now a shared ResultGrid component, cancelling a running query is reliable and preserves your selection, and the console recognises the TO REMOTE storage-policy stage. #7317, #7420

Breaking changes :boom:

  • SHOW PARTITIONS gains two trailing columns, seqTxn (index 16) and isRemotelyServed (index 17). Tools that bind result columns by position need updating. #6985
  • pg_class.relkind and information_schema.tables.table_type now report per object kind. This aligns the catalogue with PostgreSQL semantics. #7461
  • circuit.breaker.buffer.size and net.test.connection.buffer.size are obsolete. A config carrying them logs an advisory at startup, or fails under config.validation.strict. #7372
  • EXPLAIN over HTTP and CSV returns plain text. /exec and /exp no longer HTML-escape the plan. Clients that un-escape the plan need updating. #7406
  • RANGE window frame bounds that overflow the designated timestamp's unit are rejected at compile time instead of silently wrapping onto a frame nobody wrote — e.g. RANGE 300000 DAY PRECEDING on a TIMESTAMP_NS column. The same guard covers WINDOW JOIN bounds. #7461
  • IS NULL row-group pruning is disabled for CHAR, FLOAT and DOUBLE Parquet columns #7461
  • Query cancellation, timeouts and client disconnect are now honoured everywhere. #7250, #7372
  • SUSPEND WAL no longer requires dev mode, and SUSPEND / RESUME WAL share one authorization. #7239
  • QWP wire: a gapped delta symbol dictionary is rejected with a new status byte, STATUS_DICTIONARY_GAP (0x0D), and deterministic ingest rejections are reported as terminal rather than retriable. The bundled client moves in lockstep. #7374, #7359
  • Parquet output changes for external readers: file-level column_orders is declared, nested-array list elements are named canonically (element), and STRING/SYMBOL/VARCHAR min/max statistics are bounded to 64 bytes and marked inexact. Bounds stay conservative supersets. #7283
  • SecurityContext gains two abstract methods (authorizeLiveViewCreate, authorizeLiveViewDrop). Implementations outside this repository must supply them. #7461

Other key changes

SHOW CREATE DATABASE

  • A schema-only logical dump, the QuestDB equivalent of pg_dump --schema-only — one round-trippable statement per row. Real pg_dump cannot run against QuestDB, since the pg_* catalogs are empty and QuestDB DDL has no Postgres equivalent.
  • Filter with INCLUDE / EXCLUDE over TABLES, VIEWS, MATERIALIZED_VIEWS, SCHEMA and ALL. Objects are emitted in an order that always replays, and re-dumps are byte-idempotent — useful for diffing schema snapshots in CI.
  • Safe against a live database: an object dropped or renamed mid-dump is skipped rather than aborting the statement. Enterprise extends the categories to ACL objects. Docs · #7232

Per-query memory limits

A runaway query, mat view refresh or WAL apply batch could previously drive the server toward OOM with only the process-wide RSS limit as a backstop, which kills whichever allocation crosses the line rather than the workload responsible.

  • Three independent caps, cairo.query.memory.limit.bytes, cairo.mat.view.refresh.memory.limit.bytes and cairo.wal.apply.memory.limit.bytes. Opt-in, default 0, and reloadable via reload_config() — so start generous and tighten.
  • Watch usage through the new memory_used / memory_limit columns on query_activity(). A breach throws with isOutOfMemory() set and a distinct query memory limit exceeded [workload=...] message.
  • It is a guard, not a guarantee. Two allocators stay on the global counter only: the vectorized (Rosti) keyed GROUP BY tables — the default plan for SELECT key, sum(x) FROM t — and COPY ... TO Parquet export. #7184

Column type conversion on Parquet partitions

  • ALTER TABLE ... ALTER COLUMN ... TYPE now works on Parquet-partitioned tables. It previously either failed or silently left the data unconverted, so reads returned the old type — or NULL after an O3 merge.
  • The ALTER is fast; the cost moves to reads. Partitions are not rewritten, and conversion happens lazily with a one-time decode per row group. Conversions involving SYMBOL are the exception and eagerly convert affected partitions to native first. Results match the native path exactly. #7024

WAL suspension controls and REBASE WAL

  • Hard-suspend a table out of circulation with cairo.wal.apply.suspended.tables and cairo.wal.apply.suspended.write.denied — both reloadable. WAL transactions are never applied and writes are rejected rather than queued, giving you a quiescent table.
  • Non-structural ALTERs and FORCE DROP PARTITION still apply, through the WAL-bypass path. These bypass the sequencer, so they are not propagated to replicas.
  • ALTER TABLE ... REBASE WAL rebuilds a table under a fresh sequencer, keeping all applied data, for a transaction log that has grown enormous or gone corrupt. It requires hard suspension first, discards pending unapplied WAL, mints a new tableId, and invalidates dependent materialized views (recover with REFRESH ... FULL). #7239

Parquet interoperability with Iceberg, Spark, DuckDB and Trino

Fourteen fixes to how QuestDB's Parquet output reads in external tooling. Files written by older versions keep their old metadata until next rewritten, so re-export anything you want these to apply to. #7283

  • Predicate pushdown starts working — QuestDB wrote per-row-group min/max but omitted the file-level column_orders declaration, without which the spec leaves min/max undefined, so readers skipped pushdown and PyIceberg add_files dropped the file into a null partition.
  • PyIceberg stops raising KeyError on nested arrays, which named the outer LIST element list rather than the canonical element; and columns stop being mis-mapped in Iceberg tables, where QuestDB's field_id collided with Iceberg's own.
  • arrow-rs with_page_index(true) stops failing the read — O3 merge-rewrite and append emitted no page index, leaving partitions partially indexed, which fails with missing offset index. Timestamp boundary_order is now declared too, so readers can binary-search it. See the Parquet concept page.

New SQL

  • kurtosis() and skewness(), with _samp and _pop variants. One-pass Pébay algorithm over running central moments, so they merge across partials and run on the parallel GROUP BY path. #7221
  • Scalar sub-queries in comparison predicatesWHERE price > (SELECT avg(price) FROM trades WHERE timestamp IN today()). <, > and = are implemented directly and the rest derived, including the swapped form. The sub-query runs once per query execution, and integers compare at 64 bits rather than through double. #7377
  • wait_wal_table() and sleep() are production functions. wait_wal_table('trades') blocks until the WAL writer has applied up to a target seq_txn — what you want before a read that depends on a prior write. Neither holds a worker thread while parked. #7031

Performance

  • Sorting by text, UUID or LONG256 columns is much faster. The radix-based encoded sort used to engage only for fixed-width keys fitting 32 bytes; everything else fell back to a red-black tree. It now covers VARCHAR, STRING, SYMBOL, UUID, LONG256, LONG128 and wide multi-column keys, across full sorts and both serial and parallel top-K. On ClickBench hits, ORDER BY SearchPhrase LIMIT 10 goes 52 ms → 37 ms. #7242
  • Filters that wrap the timestamp in a function now prune partitions. WHERE date_trunc('day', ts) >= '...' or WHERE dateadd('h', 1, ts) < now() used to read the whole table; they now narrow the scan the way a plain timestamp filter does, by inverting the monotonic function back onto the timestamp axis. Where the inverse is exact the row filter is dropped entirely; where it is a sound superset it prunes and keeps a residual. #7305
  • Expressions that are the same for every row are computed once per query instead of once per row — anything like dateadd('d', -30, to_timezone(now(), 'Asia/Kolkata')) inside a CASE or a filter. EXPLAIN output is unchanged. #7280
  • wait_wal_table() and sleep() no longer hold a worker thread while they wait, so far more can run at once than the worker pool size. #7031
  • Cached parallel aggregations and joins use less memory. Per-worker row-id lists under a JIT filter were pre-sized to the full page frame — up to 8 MB each — and held at peak until cache eviction. Teardown now returns them to initial capacity. #7267
  • Checkpoint and snapshot restore is faster for tables with many Parquet partitions, verifying each _pm sidecar once instead of up to three times and validating partitions in parallel. Native index rebuild also parallelizes across (partition, column) pairs. #7255

Changelog

Features

  • feat(sql): add live views by @ideoma in #7461
  • feat(qwp): stop resending the full symbol dictionary on every message by @glasstiger in #7374
  • feat(qwp): add a connect timeout and tolerant client startup by @bluestreak01 in #7341
  • feat(qwp): add per-query SYMBOL dict reset flag by @kafka1991 in #7321
  • feat(core): add per-query memory limits by @puzpuzpuz in #7184
  • feat(wal): add WAL-apply suspension controls and ALTER TABLE REBASE WAL by @ideoma in #7239
  • feat(core): support column type conversions with parquet partitions by @ideoma in #7024
  • feat(sql): parallel covered-index decode for aggregation and filter by @nwoolmer in #7284
  • feat(sql): fast-lag append for covering-indexed WAL block-apply by @nwoolmer in #7414
  • feat(sql): add SHOW CREATE DATABASE for schema-only dumps by @nwoolmer in #7232
  • feat(sql): compare a numeric column with a scalar sub-query in predicates by @bluestreak01 in #7377
  • feat(sql): add kurtosis and skewness aggregates by @brunocalza in #7221

Performance

  • perf(sql): speed up ORDER BY on varchar, UUIDs and wide multi-column keys by @kafka1991 in #7242
  • perf(sql): speed up filters that wrap the designated timestamp in a function by @kafka1991 in #7305
  • perf(sql): evaluate runtime-constant subexpressions once per query instead of per row by @puzpuzpuz in #7280
  • perf(sql): reduce memory footprint of cached parallel aggregations and joins by @puzpuzpuz in #7267
  • perf(core): speed up checkpoint/snapshot restore for tables with many parquet partitions by @bluestreak01 in #7255
  • perf(core): make wait_wal_table(), sleep() functions lightweight and not block IO threads by @ideoma in #7031

Fixes

  • fix(core): regenerate _pm when restored data.parquet exceeds the committed size by @bluestreak01 in #7269
  • fix(qwp-ws): fix flushAndGetSequence() returning a stale FSN after an empty flush by @adi1719 in #7257
  • fix(core): prevent posting index out-of-memory during seal and rollback on skewed symbols by @nwoolmer in #7236
  • chore(core): prevent a JVM crash when an async writer command races a writer close by @RaphDal in #7266
  • fix(sql): fix crash on incomplete expression after CASE ... END by @mtopolnik in #7290
  • chore(core): allow ADD INDEX over a parquet partition where the column is absent by @RaphDal in #7291
  • fix(core): fix table corruption when a range-replace commit adds partitions above the last one by @puzpuzpuz in #7289
  • fix(sql): fix wrong SAMPLE BY first()/last() results when the time column is not selected by @ideoma in #7282
  • fix(sql): add cursor self-consistency checks and fault injection to query fuzzer and harden query engine by @puzpuzpuz in #7217
  • fix(core): fix out-of-order rows after a lag commit crosses a partition boundary by @brunocalza in #7285
  • fix(sql): concurrent NPE in CoveringIndexRecordCursorFactory.getCursor (#7294) by @bluestreak01 in #7298
  • fix(sql): fix internal error when subtracting a literal from a timestamp by @puzpuzpuz in #7304
  • fix(core): fix O3 lag commit recording maxTimestamp below the committed max across partitions by @bluestreak01 in #7297
  • chore(core): stop truncating the _pm sidecar on a rolled-back partition update by @RaphDal in #7268
  • chore(core): fix native memory leak when a sharded parallel GROUP BY trips the per-query memory limit by @RaphDal in #7309
  • fix(sql): fix wrong results from queries on renamed Parquet columns by @bluestreak01 in #7318
  • fix(sql): honor query cancellation and timeouts in all query types by @bluestreak01 in #7250
  • fix(core): RSS pre-flight the covered-sidecar snapshot in incremental posting seal by @nwoolmer in #7308
  • chore(core): prevent table suspension on out-of-order inserts into parquet partitions by @RaphDal in #7310
  • fix(core): fix spurious table metadata reload failures by @kafka1991 in #7312
  • chore(sql): keep the per-query memory tracker balanced across aggregate re-execution by @RaphDal in #7319
  • chore(core): refresh materialized views correctly after a base-table truncate and on read-only nodes by @jovfer in #7315
  • fix(core): retry mat view refresh on transient errors instead of invalidating by @bluestreak01 in #7275
  • chore(core): fix file-descriptor leak when the server shuts down with a query parked by @RaphDal in #7324
  • fix(sql): avoid intermediate overflow in corr() denominator by @jovfer in #7313
  • fix(http): prevent HTTP context reuse crashes and tighten multipart upload parsing by @jerrinot in #7327
  • fix(sql): fix view reads failing due to incomplete dependency tracking by @glasstiger in #7322
  • fix(core): fix query cancellation being lost when it races query startup by @jovfer in #7329
  • fix(core): fix POSTING-indexed tables suspending WAL apply after out-of-order writes by @RaphDal in #7332
  • fix(core): make DataID publication thread-safe by @bluestreak01 in #7344
  • fix(core): prevent posting index corruption when .pk stat fails during column rename by @bluestreak01 in #7347
  • fix(sql): fix crash joining or grouping on empty VARCHAR values by @sklarsa in #7346
  • chore(core): improve Parquet interoperability with external readers and Iceberg tooling by @RaphDal in #7283
  • fix(sql): fix LATEST ON returning the wrong row with an indexed key and residual filter by @nwoolmer in #7334
  • fix(qwp): fail fast on deterministic ingest rejections instead of retrying them by @kafka1991 in #7359
  • fix(qwp): prevent stale egress plans from leaking to clients by @jerrinot in #7350
  • chore(core): fix catalogue queries omitting tables after a concurrent metadata cache clear by @RaphDal in #7360
  • fix(sql): fix PIVOT and expression column names that embed double quotes by @glasstiger in #7353
  • chore(core): fix socket leaks on shutdown when queries are parked or retrying by @RaphDal in #7368
  • chore(core): resolve column files by writer index when converting a partition to Parquet by @RaphDal in #7363
  • fix(core): fix POSTING index covering scans failing when queries migrate across worker threads by @nwoolmer in #7349
  • chore(core): fix adding a covering index over parquet after a column type change by @kafka1991 in #7370
  • fix(sql): clarify materialized view error when timestamp lacks a sampling interval by @Socialpranker in #7376
  • fix(sql): fix cancel_query() spuriously cancelling the wrong query by @jerrinot in #7238
  • fix(sql): fix dot_product returning wrong result for transposed arrays by @raphaelroshan in #7392
  • fix(SQL): fix SAMPLE BY w to accept the week unit without a leading digit by @nabeel001 in #7391
  • fix(http): return EXPLAIN plans as plain text by @emrberk in #7406
  • fix(core): fix POSTING-indexed WAL table suspending after a partition squash by @ideoma in #7386
  • fix(core): stop a query when its client disconnects by @kafka1991 in #7372
  • fix(sql): fix NULL array handling, IPv4 aggregates, and parallel OOM handling by @puzpuzpuz in #7371
  • chore(qwp): carry crash-safe SF cleanup and pool-capacity recovery by @bluestreak01 in #7387
  • fix(core): fix covering index reading NULL after converting a parquet partition back to native by @nwoolmer in #7415
  • fix(qwp): fix duplicate writes and store-and-forward recovery during failover by @bluestreak01 in #7366
  • fix(sql): prevent JIT STRING null checks from crashing the server by @jerrinot in #7454
  • chore(qwp): bump symbol dictionary limit to 2m by @ideoma in #7468

Build, CI and internals

  • build: 9.4.3 by @bluestreak01 in #7265
  • build(deps): bump js-yaml from 4.1.0 to 4.2.0 in /compat/src/test/nodejs-pg by @dependabot[bot] in #7271
  • build(deps): bump js-yaml from 4.1.0 to 4.2.0 in /compat/src/test/nodejs-postgres by @dependabot[bot] in #7272
  • ci(build): auto-detect SNAPSHOT client and enable local-client profile in release builds by @bluestreak01 in #7274
  • chore(build): migrate GitHub Actions workflows off the deprecated Node 20 runtime by @RaphDal in #7277
  • chore(core): format code with IDEA 2026.1.3 by @RaphDal in #7281
  • ci(build): route Maven builds through the self-hosted Reposilite cache by @sklarsa in #7286
  • ci(build): retry Maven wagon transfers on cache connect failure by @sklarsa in #7287
  • test(core): de-flake HTTP export file-descriptor leak checks by @RaphDal in #7292
  • test(core): stop posting-index fuzz from mixing replace commits with Parquet by @bluestreak01 in #7299
  • test(core): stabilize flaky QWP credit-flow and worker-pool CI tests by @puzpuzpuz in #7306
  • chore(qwp): exercise e2e test on the client changes by @bluestreak01 in #7307
  • ci(build): bound cache connect timeout and retry connect failures by @sklarsa in #7311
  • test(qwp): adapt facade E2E tests to the WebSocket-only client by @mtopolnik in #7314
  • chore(ui): upgrade web console to 2.0.0 by @emrberk in #7317
  • test(core): stop ServerMainForeignTableTest SAMPLE BY assertions flaking on the RSS check by @jovfer in #7323
  • test(core): stop SampleByConfigTest flaking on the post-close RSS check by @RaphDal in #7325
  • test(qwp): speed up sender coercion-error tests by @RaphDal in #7364
  • ci(build): re-add docker image vulnerability scanning to release pipeline by @sklarsa in #7365
  • chore(build): bump gosu to 1.19-go1.25.11 by @sklarsa in #7367
  • test(core): fix seed-dependent crash in checkpoint fuzz test by @jovfer in #7381
  • test(core): stop query_activity churn test hanging and cascading on constrained CI by @kafka1991 in #7395
  • test(core): stop fuzz tests spuriously failing when logging non-ASCII index values by @RaphDal in #7396
  • chore(build): bump gosu to 1.19-go1.25.12 by @questdb-maven-release-app[bot] in #7398
  • ci(build): reduce Ubuntu package download failures by @bluestreak01 in #7405
  • refactor(qwp): rename sf_max_bytes to sf_max_segment_bytes in e2e fuzz test by @mtopolnik in #7413
  • chore(ui): upgrade web console to 2.0.1 by @emrberk in #7420
  • test(sql): extend ASOF/LT JOIN fuzz coverage to multi-column ON clauses by @jerrinot in #6638
  • test(qwp): assert proper treatment of empty and NULL arrays on egress by @mtopolnik in #7276
  • chore(core): add new ent config key to server.conf template by @glasstiger in #7270
  • chore(core): fix wrong symbol values on replicas after a column type conversion - fuzz test fix by @glasstiger in #7179
  • chore(core): engine seams for hot in-place primary/replica role switch by @jovfer in #7261
  • chore(core): pluggable WAL event types and partition flag bit by @RaphDal in #6985

New Contributors

Full Changelog: 9.4.3...10.0.0

Source: README.md, updated 2026-08-06