
QuestDB
A columnar time-series database in Java, C++ and Rust that ingests millions of rows a second and answers time-series SQL, with old partitions kept as Parquet.
- What it is
- Time-series databases
- Type
- Open source
- Made by
- QuestDB Inc.
- License
- Apache 2.0 (open source; AGPLv3 from 2016 to 2019); QuestDB Enterprise is proprietary
- Facts checked
- 6 October 2026
What it is
QuestDB is one server process, written in garbage-free Java with C++ and Rust on the hot paths. Each table is a set of column files split into time partitions and physically sorted by one designated timestamp column. Clients write rows over QuestDB’s own binary protocol (QWP), the InfluxDB Line Protocol (ILP) or SQL over the PostgreSQL wire protocol. Rows land first in a write-ahead log (WAL) and are acknowledged; a background job then merges them into the partitions, sorting late rows into place and, if the table asks for it, replacing rows with the same keys. Queries run SQL with time-series extensions on a vectorized engine with JIT-compiled filters over memory-mapped files. Port 9000 also serves a REST API and a web console.
Storage has three tiers: the WAL, native column partitions, and Apache Parquet. In the open-source build you convert old partitions to Parquet with ALTER TABLE, or create a table in Parquet from the start. The open-source edition is Apache 2.0 and runs as a single instance with basic authentication. QuestDB Enterprise adds replication with read replicas and failover, role-based access control, TLS, SSO and automated backups, and converts cold partitions on a schedule and moves them to S3, Azure Blob or Google Cloud Storage, where they stay queryable. You run it yourself, or QuestDB operates it inside your AWS or Azure account (Bring Your Own Cloud). Enterprise prices aren’t published. Version 10.0 shipped in August 2026, alongside Enterprise 4.0.
Why teams pick it
- Time-series SQL:
SAMPLE BYtime buckets,LATEST ONfor the newest row per key, andASOF JOINorWINDOW JOINto line up trades with the quotes in force at the time - Built for heavy, messy ingest: out-of-order rows and deduplication are handled on write, and many clients can write to one table at once through the WAL
- Existing tools work: Telegraf and other ILP senders write unchanged, and PostgreSQL drivers, Grafana and BI tools query over port 8812
- Open formats: partitions can become Parquet files, and the Python client receives query results as Apache Arrow
- Permissive Apache 2.0 licence, with finance-friendly types such as n-dimensional arrays,
DECIMALand nanosecond timestamps
Watch out for
- The open-source build is a single instance: replication, failover, TLS, RBAC and SSO are Enterprise only, and Enterprise prices are by quote
- The designated timestamp and the partitioning scheme can’t be changed after a table is created; changing either means rebuilding the table
- Writes are acknowledged once they are in the WAL and applied in the background, so freshly committed rows can take a moment to show up in queries
- Parquet partitions can’t be updated, and late rows landing on one rewrite the whole partition; moving cold partitions to object storage automatically needs Enterprise
- Headline numbers in the README (19 million rows a second, a TSBS table where QuestDB wins) come from QuestDB’s own benchmarks on hardware it chose
Alternatives
What all time-series databases have in common →
Amazon TimestreamAWSAWS’s time-series databases: a serverless engine now closed to new customers, and managed InfluxDB 2 and 3.Apache IoTDBOpen sourceAn Apache time-series database for industrial IoT that stores everything in its own open file format, TsFile, and lets you model devices as a tree of paths or as SQL tables.+1 TimechoDBArcOpen sourceA young single-binary time-series database in Go that writes incoming data as Parquet files and queries them with DuckDB SQL.
TDengineOpen sourceA clustered time-series database for IoT and industrial data that gives every device its own table, grouped under “supertables” with tags.How it fits with other technologies
What QuestDB uses
- QuestDBtakes metrics via line protocol fromTelegraf
- QuestDBingests topics, via a connector, fromApache Kafka
- QuestDBreceives streams, via a sink connector, fromApache Flink
- QuestDBis queried, through a plugin, byGrafana
- QuestDBis read and written over JDBC byApache Spark
- QuestDBcan store old partitions asApache Parquet
- QuestDBstreams query results asApache Arrow
- QuestDBtiers cold partitions (Enterprise) toAmazon S3
- QuestDBruns, with a Helm chart, onKubernetes
A deduplicated trades table, OHLC bars, and Parquet for old data · sql
-- partitioned by day, written through the WAL; same timestamp + symbol = upsert
CREATE TABLE trades (
timestamp TIMESTAMP,
symbol SYMBOL,
price DOUBLE,
amount DOUBLE
) TIMESTAMP(timestamp)
PARTITION BY DAY WAL
TTL 90 DAYS
DEDUP UPSERT KEYS (timestamp, symbol);
-- 15-minute OHLC bars for today
SELECT timestamp, symbol,
first(price) AS open, max(price) AS high,
min(price) AS low, last(price) AS close,
sum(amount) AS volume
FROM trades
WHERE symbol = 'EURUSD' AND timestamp IN '$today'
SAMPLE BY 15m;
-- the newest row for every symbol
SELECT * FROM trades LATEST ON timestamp PARTITION BY symbol;
-- keep partitions older than a week as Parquet files
ALTER TABLE trades CONVERT PARTITION TO PARQUET
WHERE timestamp < dateadd('d', -7, now());Open source or Enterprise#
The same engine in both columns. Enterprise adds what a production deployment needs around it, under a commercial licence. Checked 2026-10-06; QuestDB doesn’t publish Enterprise prices.
| Feature | Open source | Enterprise |
|---|---|---|
| Who runs it | You: binaries, containers or source | You, or QuestDB inside your AWS or Azure account (BYOC) |
| Price | Free, Apache 2.0 | By quote; free trial available |
| Instances | One instance, no high availability | Replication, read replicas, primary failover |
| Users and security | Admin plus an optional read-only user; basic auth over unencrypted connections | Unlimited users, groups and service accounts; RBAC down to columns; TLS; SSO via OAuth, OIDC or Entra ID |
| Storage | Local disk; convert partitions to Parquet by hand | Automatic Parquet conversion and tiering to S3, Azure Blob or GCS, queryable in place |
| Backups | Manual full backups to local storage | Automated incremental snapshots to object storage, point-in-time recovery |
| Support | Community | QuestDB engineers with response-time SLAs |
Ways in and out#
One server speaks several protocols, so you can keep the clients you have and move to the native one where speed matters.
QuestDB Wire Protocol (QWP)
port 9000Binary and columnar, over WebSocket. One connection writes rows and streams query results back as columns; the Python client returns Apache Arrow. New in 10.0 and the recommended path for QuestDB’s own clients, which QuestDB measured at about 3.6 times faster than ILP for network ingestion.
InfluxDB Line Protocol (ILP)
port 9000The text format Telegraf and InfluxDB clients already send. Still fully supported in 10.0, so existing collectors can write without changes.
PostgreSQL wire protocol
port 8812Run queries from psycopg, JDBC, pgx, Grafana and BI tools. Inserts work too, but slower than QWP.
REST API and web console
port 9000HTTP queries for scripts and cURL, CSV import and export, and a browser console with a SQL editor, charts and notebooks.
See it in a real stack
No architecture uses QuestDB yet. Drop it into the playground and wire it up yourself.Open playground →Benchmarks
Where it came from2014–2026
Vlad Ilyushchenko spent years building low-latency trading systems. In 2012 an energy trading company hired him to rebuild its vessel-tracking system; the proposed database needed a week of downtime to load the data, and options such as OpenTSDB didn’t fit the data model. Peter Lawrey’s Java Chronicle library loaded the same data in two minutes using memory-mapped files, which showed him how fast garbage-free Java could be.
He started QuestDB as a side project in 2014, first released as NFSdb, and built it on nights and weekends while contracting for six years, rewriting the engine when the first design couldn’t keep readers and writers apart. The core code moved to AGPLv3 in 2016 and to Apache 2.0 in November 2019, the year he and Nicolas Hourcard founded the company.
A $2 million seed round in March 2020 and Y Combinator’s Summer 2020 batch followed, then a $12.5 million Series A in 2021. Version 6.0 began accepting out-of-order rows, 7.0 put a write-ahead log in front of the column store, and Enterprise added replication and tiering to object storage.
Why it’s built this way
- Garbage-free Java over memory-mapped column files
- The Chronicle experience showed memory-mapped files could load in minutes what a database took a week to ingest. Managing memory off-heap, instead of relying on libraries that create garbage, keeps the garbage collector from pausing queries and writes.
- One designated timestamp that orders every table
- Time-series questions ask for time ranges. Storing rows physically sorted by one timestamp lets queries binary-search into a range and makes partitions, retention and deduplication cheap; the price is that it can’t be changed later.
- Speak protocols people already use
- The PostgreSQL wire protocol arrived in 4.0 (2019) so existing drivers and BI tools could query it, and ILP lets collectors built for InfluxDB, such as Telegraf, write to it unchanged.
- A write-ahead log in front of the column store
- Heavy out-of-order data slowed ingestion when rows went straight into sorted partitions. The WAL in 7.0 made ingest speed consistent, allowed concurrent writers, and became the basis for replication.
Timeline
- 2014
First release, under the name NFSdb
- 2016
Core code relicensed under AGPLv3
- 2019
Company founded; 4.0 switches the licence to Apache 2.0
- 2020
$2 million seed and Y Combinator’s Summer 2020 batch
- 2021
6.0 accepts out-of-order rows; $12.5 million Series A
- 2023
7.0 adds the write-ahead log, in beta
- 2026
10.0 adds the QuestDB Wire Protocol and live views
- QuestDB blog: My journey writing QuestDB, Vlad Ilyushchenko (Aug 2020)
- QuestDB: About us (founders, side project from 2014, founded 2019)
- QuestDB blog: Our two-year journey raising $15m of venture capital (Jan 2022)
- GitHub: QuestDB 1.0, first release of NFSdb (May 2014)
- GitHub: commit changing the licence to Apache 2.0 (Nov 2019)
- GitHub: QuestDB 7.0.0 release notes, WAL beta (Feb 2023)
Sources22 · facts checked 6 October 2026
- QuestDB README (architecture, protocols, ports, Enterprise, TSBS table)
- QuestDB LICENSE.txt (Apache 2.0)
- GitHub: commit moving core code to AGPLv3 (Apr 2016)
- QuestDB docs: Architecture
- QuestDB docs: Write-ahead log
- QuestDB docs: Designated timestamp
- QuestDB docs: CREATE TABLE (WAL, TTL, DEDUP UPSERT KEYS)
- QuestDB docs: Parquet (conversion, limitations, Enterprise storage policies)
- QuestDB docs: InfluxDB Line Protocol overview
- QuestDB: Enterprise (feature comparison with open source)
- QuestDB: Bring Your Own Cloud
- QuestDB blog: QuestDB 10.0 release (QWP, live views, Parquet, Enterprise 4.0)
- GitHub: QuestDB 10.0.0 release (Aug 2026)
- QuestDB blog: 2025 year in review (arrays, TIMESTAMP_NS, DECIMAL, materialized views)
- GitHub: QuestDB 6.0.0 release notes (out-of-order ingestion)
- GitHub: QuestDB 4.0.0 release notes (PostgreSQL wire protocol, beta)
- QuestDB docs: Kafka
- QuestDB docs: Apache Flink sink connector
- QuestDB docs: Telegraf
- QuestDB docs: Grafana plugin
- QuestDB docs: Apache Spark (JDBC over PostgreSQL wire protocol)
- QuestDB docs: Kubernetes (Helm chart, Enterprise operator)