Name | Modified | Size | Downloads / Week |
---|---|---|---|
Parent folder | |||
questdb-9.0.0-no-jre-bin.tar.gz | 2025-07-11 | 26.3 MB | |
questdb-9.0.0-rt-linux-x86-64.tar.gz | 2025-07-11 | 66.3 MB | |
questdb-9.0.0-rt-windows-x86-64.tar.gz | 2025-07-11 | 62.4 MB | |
9.0.0 source code.tar.gz | 2025-07-11 | 55.9 MB | |
9.0.0 source code.zip | 2025-07-11 | 60.6 MB | |
README.md | 2025-07-11 | 17.6 kB | |
Totals: 6 Items | 271.6 MB | 4 |
Major release - QuestDB 9.0!
We've acted on key feedback from leading firms, and open source users alike, and channelled this into the most featureful and robust version of QuestDB yet!
If you are a long-term user, we hope you will enjoy some of the great additions we're bringing in this release, and if you are a new user, there's never been a better time to get started!
Multidimensional Arrays
This milestone release brings the much-anticipated first beta
release for our new Multidimensional Arrays
(NDArrays). These are true shaped-and-strided, NumPy-like arrays, perfect for storing tick and order book data, signals from sensor arrays, ML weights, and much more. This initial release supports the DOUBLE[]
type, of n-dimensions, and we will expand this to other types soon!
Common array operations (e.g. slicing, transposing) are handled with zero copying. Instead, the underlying buffer is shared between different operators, whether the arrays are stored on-disk or in-memory. The data is contiguous, and stored as a true tensor rather than nested lists.
A number of common array operations are included, and we will be rapidly releasing more, so get your feedback in early!
Binary line protocol
Another kicker - this release brings the first part of our new binary line protocol. In order to support writing arrays with maximum performance, we've extended the ILP text protocol with new binary types, including the binary double[]
and binary double
. This increases throughput and lowers message size, versus sending arrays in a textual format. This has been introduced as a new protocol version, maintaining backwards compatibility with existing clients.
Here's an example that demonstrates sending double[]
to QuestDB from a Pandas DataFrame:
:::python
import pandas as pd
from questdb.ingress import Sender
df = pd.DataFrame({
'symbol': pd.Categorical(['ETH-USD', 'BTC-USD']),
'side': pd.Categorical(['sell', 'sell']),
'price': [2615.54, 39269.98],
'amount': [0.00044, 0.001],
'ord_book_bids': [
np.array([2615.54, 2618.63]),
np.array([39269.98, 39270.00])
],
'timestamp': pd.to_datetime(['2021-01-01', '2021-01-02'])})
conf = f'http::addr=localhost:9000;'
with Sender.from_conf(conf) as sender:
sender.dataframe(df, table_name='trades', at='timestamp')
This is a key turning point for QuestDB's ingestion clients. Introducing this new binary protocol opens the door for us to make clients smarter, and enable native integration with key QuestDB features such as data deduplication, schema evolution, and replication failover.
Materialized Views
Materialized Views have received major upgrades - efficient writes with the new replace commit
mechanism, support for self-UNION queries, the ability to delay or defer a refresh, and three new view refresh modes:
TIMER
refreshes (now stabilised), allowing you to refresh the view after a regular time interval.MANUAL
refreshes, which are entirely user-controlled.PERIOD
refreshes, with more explanation below!
PERIOD
refresh is the most featureful mode to date, bringing time-zone aware, calendar-scheduled refreshes, only including complete buckets of data. This has great potential, especially for users with globally-distributed use cases.
For example, let's say you want to summarise trading data at the end of each trading day, but you work with exchanges in different timezones. You can create a PERIOD
view for NYSE data tuned to update at the end of the New York trading day. Then you can have a separate view specifically for Tosho data, wich updates at the end of the Tokyo trading day - and all with easy-to-use syntax.
:::sql
CREATE MATERIALIZED VIEW trades_latest_1d
REFRESH PERIOD (LENGTH 1d TIME ZONE 'America/New_York' DELAY 2h) AS
SELECT
timestamp,
symbol,
side,
last(price) AS price,
last(amount) AS amount,
last(timestamp) AS latest
FROM trades
SAMPLE BY 1d;
We won't stop to iterating on killer features like Materialized Views
, and Multidimensional Arrays
!
Web Console
Our web console has had a fresh coat of paint, and with it comes some long sought-after features.
Firstly, each query is now marked by its own individual run arrow and selection, making it easy to see at a glance where your semi-colon delineated boundaries lie. Also, you can now easily obtain query plans by right clicking on the run arrows, to help you better understand and debug troublesome queries - no more typing out the EXPLAIN
keyword, only to delete it straight afterwards!
Additionally, the QuestDB web console now supports running multiple queries at once, through drag selection and the Run All
button.
The results from Run All
are stored in a new Query Log, which is particularly handy when running database migration scripts, and you can configure the run to stop automatically if any of the queries fail.
We've refreshed our Web Console documentation, and invite you to take a tour of our new features.
Roundup
This is a big one, but we're just getting started! We're grateful to our customers and users, and thank you for your ongoing support and constructive feedback - we can't do it without you.
We'll end it here so you can get busy upgrading to QuestDB 9.0.0, but don't forget to check out all the other performance upgrades, new functions, and (of course) bug fixes that come with this milestone release.
For any questions or feedback, please join us on Slack or on Discourse.
See also our prettier release notes page.
Breaking changes 💥
- Materialized Views
REFRESH LIMIT
andREFRESH EVERY
settings have been reset, due to a change in storage format.REFRESH EVERY
(TIMER
views) must be dropped and recreated.REFRESH LIMIT
can be re-added with an alterALTER MATERIALIZED VIEW trades_latest_1d SET REFRESH LIMIT 1 WEEK;
TIMER
refresh syntax has been inverted from what is was originally:- Instead of
REFRESH START <timestamp> EVERY <interval>
- It is now
REFRESH EVERY <interval> START <timestamp>
- Instead of
REFRESH INCREMENTAL
has been changed toREFRESH IMMEDIATE
(but older syntax is still accepted).
- Column Aliasing
- The aliasing rules for expressions without explicit aliases have now been changed.
- Previously:
SELECT spread(bid, ask)
would give an output column ofspread
.- Repeated functions would have a number appended
- Plain expressions such as
5 + 2
would be namedcolumn
.
- Going forward:
- The expression itself will be used as the column name:
floor(avg(price*amount))
now outputsfloor(avg(price * amount))
as the column name.- Repeated expressions (which are unlikely), will have numbers appended.
- The max length of the output column alias is configurable:
cairo.sql.column.alias.generated.max.size
- This change can be reverted (for now) using
cairo.sql.column.alias.expression.enabled=false
.
- The expression itself will be used as the column name:
- PG Wire
- Users who opted out of the new faster and less buggy PG Wire implementation have been opted back in.
- The new PG Wire driver was initially released in September 2024, and we consider it robust and stable.
- If users need to opt back out, they can do so by changing
pg.legacy.mode=!true
, but should adopt the new modernPG Wire
server as soon as possible, as we will remove this option soon.
- JOIN
TOLERANCE
is now a keyword, so if you were using it in implicit aliasing, it will need to be quoted i.e. "TOLERANCE".
Highlights
- Multidimensional arrays
- New
double[]
type, which is a shaped-and-strided n-dimensional array. - Addition of new binary protocol to ILP clients to efficiently send
double
anddouble[]
types.- Literals:
SELECT ARRAY[1.0, 2.0, 3.0]
- 2D:
SELECT ARRAY[[a], [b]] FROM tango
- Indexing:
SELECT arr[1][2] FROM samba
orSELECT arr[1,2] FROM samba
- Slicing:
SELECT arr[2:], arr[1:100] FROM samba
- ND Slicing:
SELECT arr[2:3, 3:4], arr[1:, 2] FROM samba
- Math:
SELECT a * b FROM samba
- Functions:
SELECT matmum(arr, transpose(arr)) FROM samba
- Literals:
- New
- Materialized Views
- View updates are much faster due to new timestamp range-replace commits.
TIMER
views have been stabilised, and now offer a newTIME ZONE
clause, to make your refresh timezone-aware.MANUAL
refresh mode has been added, for fully manual (but incremental) view refreshing.CREATE MATERIALIZED VIEW
now accepts aDEFERRED
clause, to delay or prevent the initial eager refresh upon view creation.REFRESH LIMIT
is now respected during a full view refresh.PERIOD
refresh mode has been added, which supports calendar-scheduled, timezone-aware refreshes, for only whole sample by buckets.- Self-
UNION
queries are now supported. possibly be found.
- SQL
- JOIN
CROSS JOIN
queries have been sped up significantly, after identifying an issue with cursor resets.ASOF
andLT
joins now support aTOLERANCE
clause, which specifies a maximum bound for the timestamp matchingSELECT ... FROM table1 ASOF JOIN table2 ON <key> TOLERANCE interval_literal [WHERE ...]
- Time-based joins on
SYMBOL
columns have been sped up through early-exits when it is known that noSYMBOL
match can
- SELECT
- Columns within in a
SELECT
statement are now self-referenceable and memoised.- This is convenient and also improves the efficiency of functions such as
json_extract
. - For example,
SELECT x + 10 y, y - 5 FROM test
.
- This is convenient and also improves the efficiency of functions such as
- Columns within in a
- A new
generate_series()
function has been added.- This is a pseudo-table allowing for timestamp, double and long range generation.
SELECT * FROM generate_series('2025-06-13T09:00:00', '2025-06-13T10:00:00', '1m');
- Negative steps can be used, to produce values in descending order.
- JOIN
- DEDUP
- Data deduplication performance has been dramatically improved when inserting completely identical data en-masse.
Changelist
- fix(sql): potential memory leak in plain INSERTs by @puzpuzpuz in https://github.com/questdb/questdb/pull/5706
- fix(sql): unreliable out-of-memory error propagation in parallel SQL by @puzpuzpuz in https://github.com/questdb/questdb/pull/5711
- fix(sql): invalidate dependent materialized views on base table rename by @puzpuzpuz in https://github.com/questdb/questdb/pull/5693
- feat(core): N-dimensional array support by @amunra in https://github.com/questdb/questdb/pull/5243
- fix(sql): failing OOM recovery due to too strict RSS limit checks by @puzpuzpuz in https://github.com/questdb/questdb/pull/5717
- feat(core): use timestamp range replace updates to update mat views by @ideoma in https://github.com/questdb/questdb/pull/5679
- fix(core): fix issue when running in directory path that includes characters unsupported in URLs by @nwoolmer in https://github.com/questdb/questdb/pull/5736
- fix(ilp): buffer management with varchar columns by @jerrinot in https://github.com/questdb/questdb/pull/5738
- fix(core): fix degradation into 1 by 1 wal transaction application when queue is big by @ideoma in https://github.com/questdb/questdb/pull/5725
- feat(sql): allow self-UNION queries in materialized views by @puzpuzpuz in https://github.com/questdb/questdb/pull/5730
- fix(sql): fix unexpected columns being added to the SQL projection from
order by
expression by @bluestreak01 in https://github.com/questdb/questdb/pull/5748 - fix(sql): fix an issue where a query declared under WITH, using TIMESTAMP(ts), would result in parsing error by @mtopolnik in https://github.com/questdb/questdb/pull/5746
- fix(sql): correct error position for syntax errors in CREATE AS SELECT by @jerrinot in https://github.com/questdb/questdb/pull/5756
- fix(pgwire): resolve intermittent NullPointerException during INSERTs by @jerrinot in https://github.com/questdb/questdb/pull/5788
- feat(sql): add generate_series() functions by @nwoolmer in https://github.com/questdb/questdb/pull/5761
- fix(sql): make
sample by week
align to natural calendar. by @kafka1991 in https://github.com/questdb/questdb/pull/5785 - feat(sql): breaking change 💥 - period refresh for materialized views by @puzpuzpuz in https://github.com/questdb/questdb/pull/5723
- feat(sql): ASOF and LT JOIN TOLERANCE support by @jerrinot in https://github.com/questdb/questdb/pull/5713
- fix(sql): internal error during implicit timestamp propagation by @jerrinot in https://github.com/questdb/questdb/pull/5777
- feat(core): prevent unnecessary partition rewrites when inserting duplicate data by @ideoma in https://github.com/questdb/questdb/pull/5764
- fix(sql): support
order by desc
with negative limit on Jit-filtered interval queries by @RaphDal in https://github.com/questdb/questdb/pull/5798 - feat(sql): introduce more array functions by @kafka1991 in https://github.com/questdb/questdb/pull/5771
- fix(sql): exception thrown when same DECLARE variable used in 2-params function by @RaphDal in https://github.com/questdb/questdb/pull/5806
- perf(sql): improve performance of cross joins by @bluestreak01 in https://github.com/questdb/questdb/pull/5741
- feat(sql): breaking change :boom: - use expression as column aliases by @RaphDal in https://github.com/questdb/questdb/pull/5802
- feat(sql): enable SQL projection columns to reference preceding columns on the same projection by @bluestreak01 in https://github.com/questdb/questdb/pull/5778
- fix(sql): cache WAL txn intervals to avoid out-of-disk-space errors in case of manual and timer materialized views by @puzpuzpuz in https://github.com/questdb/questdb/pull/5797
- feat(pgwire): forcing anyone using old (and buggy) pgwire protocol implementation to use new and much more resilient one by @bluestreak01 in https://github.com/questdb/questdb/pull/5816
- fix(sql): fix crash when inserting varchar column as timestamp with implicit type conversion by @ideoma in https://github.com/questdb/questdb/pull/5899
- perf(sql): speed up initial refresh of materialized views with high cardinality symbols by @puzpuzpuz in https://github.com/questdb/questdb/pull/5906
- fix(sql): fix rendering empty untyped array by @mtopolnik in https://github.com/questdb/questdb/pull/5907
- fix(sql): expression alias for array don't use the correct syntax by @RaphDal in https://github.com/questdb/questdb/pull/5922
- fix(http): fix exception thrown when using escaped column names by @RaphDal in https://github.com/questdb/questdb/pull/5927
- fix(http): HttpHeaderParser improperly handled quoted parameter values by @RaphDal in https://github.com/questdb/questdb/pull/5897
- feat(sql): ALTER MATERIALIZED VIEW SET REFRESH support by @puzpuzpuz in https://github.com/questdb/questdb/pull/5896
- fix(sql): validate column aliases in CREATE TABLE statements by @RaphDal in https://github.com/questdb/questdb/pull/5929
- fix(sql): fix
ClassCastException
ininsert as select
query with concurrent schema changes by @kafka1991 in https://github.com/questdb/questdb/pull/5796 - fix(core): fix split partitions not being automatically squashed by @ideoma in https://github.com/questdb/questdb/pull/5924
- fix(web-console): do not refresh settings on focus when auto-refresh is disabled by @emrberk in https://github.com/questdb/ui/pull/442
- fix(ui): do not persist OAuth2 tokens by @glasstiger in https://github.com/questdb/ui/pull/438
- fix(web-console): use correct query for resuming WAL for a materialized view by @emrberk in https://github.com/questdb/ui/pull/445
- feat(web-console): show table icon description in the tooltip by @emrberk in https://github.com/questdb/ui/pull/443
- feat(web-console): dynamic query status indicators, run button per query, run all queries in tab by @emrberk in https://github.com/questdb/ui/pull/437
- fix(web-console): array truncation in grid & bug fixes by @emrberk in https://github.com/questdb/ui/pull/448
- fix(web-console): declare variable highlighting in editor & query parameter parsing in chart request by @emrberk in https://github.com/questdb/ui/pull/452
New Contributors
- @CTingy made their first contribution in https://github.com/questdb/questdb/pull/5766
- @RaphDal made their first contribution in https://github.com/questdb/questdb/pull/5798
- @akashadsare made their first contribution in https://github.com/questdb/questdb/pull/5854
Full Changelog: https://github.com/questdb/questdb/compare/8.3.3...9.0.0