Interested in QuestDB use cases?

Learn more

QuestDB 9.3.2: TICK, arg_max, and Exponential Moving Averages

Tags:
RedditHackerNewsX
QuestDB is the open-source time-series database for demanding workloads—from trading floors to mission control. It delivers ultra-low latency, high ingestion throughput, and a multi-tier storage engine. Native support for Parquet and SQL keeps your data portable, AI-ready—no vendor lock-in.

QuestDB 9.3.2 is here - and TICK is the headline. It is a new temporal interval syntax that turns complex time-range filters into one-liners. If you have ever wrestled with timezone-aware schedules, business day logic, or multi-session windows in SQL, this is for you.

Alongside TICK, we are shipping new aggregate and window functions for time-series analytics, a 6x speedup on Parquet queries, and improved LLM integration.


TICK: Temporal Interval Calendar Kit

TICK is a compact DSL for expressing complex time intervals directly in your WHERE clause. It replaces the UNION ALL chains, application-side date generation, and tangled BETWEEN logic that time-range queries typically require.

Here is the pitch in one example. Say you want a month of NYSE data - trading hours only, workdays only, in New York time:

TICK expression for NYSE trading hoursDemo this query
SELECT * FROM trades
WHERE timestamp IN '2026-01-[01..31]T09:30@America/New_York#workday;6h30m';

That single string expands into 22 optimised interval scans, one per trading day, each using binary search on the designated timestamp. No unions. No subqueries. No client-side calendar math.

TICK syntax features

TICK supports a rich set of composable features:

  • Bracket expansion: [01..31], [09,14]:30
  • Date variables: $today, $yesterday, $tomorrow, $now
  • Business day arithmetic: $today - 5bd
  • Timezone-aware DST handling: @America/New_York
  • Day-of-week filters: #workday, #Mon,Wed,Fri
  • Duration suffixes: ;6h30m

These are all composable in a single expression. A few more patterns to give you the flavour:

More TICK examplesDemo this query
-- Last 5 business days
SELECT * FROM trades WHERE timestamp IN '$today - 5bd..$today - 1bd';
-- Today's data (full day)
SELECT * FROM fx_trades WHERE timestamp IN '$today';
-- Last hour of data
SELECT * FROM fx_trades WHERE timestamp IN '$now - 1h..$now';
-- Last 30 minutes
SELECT * FROM fx_trades WHERE timestamp IN '$now - 30m..$now';

No other SQL database does this in a WHERE clause. We are excited to see what you build with it.

Read the TICK documentation


arg_min, arg_max, and geomean

You can already get the max price in a window. But which row produced it, and when? arg_max gives you correlated values from that row directly:

Using arg_max to get correlated valuesDemo this query
SELECT timestamp, symbol, max(price), arg_max(timestamp, price)
FROM trades
WHERE timestamp IN '$today'
SAMPLE BY 1h;
timestampsymbolmax(price)arg_max(timestamp, price)
2026-02-04T00:00:00.000000ZETH-USDT2256.942026-02-04T00:35:50.648999Z
2026-02-04T00:00:00.000000ZBTC-USDT76270.12026-02-04T00:42:29.675000Z
2026-02-04T00:00:00.000000ZSOL-USDT98.82026-02-04T00:42:20.482000Z
2026-02-04T00:00:00.000000ZADA-USDT0.29572026-02-04T00:42:28.301000Z
2026-02-04T00:00:00.000000ZLTC-USDT60.12026-02-04T00:39:59.533999Z

Now you get both the max price and the exact timestamp of the trade that hit it. No self-joins, no subqueries.

arg_min works the same way for minimums. geomean returns the geometric mean - better suited than arithmetic averages for compounding growth rates and datasets with large outliers.


EMA, VWEMA, and percent_rank window functions

EMA and VWEMA are now native window functions. EMA applies exponential smoothing over a time period; VWEMA does the same but weights by volume, so high-activity periods carry more influence in the result.

Exponential Moving Average as a window functionDemo this query
SELECT
symbol,
price,
timestamp,
avg(price, 'period', 10) OVER (
PARTITION BY symbol
ORDER BY timestamp
) AS ema_10
FROM trades
WHERE timestamp IN '[$today]';

This query calculates a 10-period EMA for each symbol. The avg function with 'period', 10 applies exponential smoothing where recent prices have more weight than older ones. Results are partitioned by symbol so each trading pair gets its own independent EMA calculation, ordered chronologically.

percent_rank returns the relative rank of a row within its partition. These execute inside the query engine. No exporting data to Python or a spreadsheet for smoothing calculations.


Performance highlights

Alongside new SQL features, QuestDB 9.3.2 delivers significant performance improvements:

  • Parquet queries up to 6x faster through optimised row-group decoding
  • Smarter interval scan pushdown: dateadd predicates, OR clauses over timestamps, and nested query offsets now all resolve to efficient interval scans
  • Reduced file mapping contention for high-concurrency query workloads
  • Faster scans when first/last/min/max(timestamp) appear inside other function calls

AI Assistant improvements

The AI assistant in the Web Console gets a significant upgrade in this release. Responses now stream in real-time, so you see answers as they are generated.

More importantly, the assistant can now investigate your table schemas automatically, looking up column types, indexes, and metadata to produce more accurate SQL suggestions.

You can also retry failed requests or cancel in-progress ones with a single click.

Learn more about AI-assisted workflows


Also in this release


QuestDB Enterprise 3.2.1: Scheduled Incremental Backups

QuestDB Enterprise 3.2.1 ships alongside this release, adding incremental backups to object storage with built-in scheduling.

Initiate a backup with BACKUP DATABASE, or configure a cron schedule and retention policy, and backups run automatically. Only changed data uploads, keeping them fast and bandwidth-efficient.

Monitor progress with backups(), or stop a running backup with BACKUP ABORT.

Read the Backups documentation


Overhauled documentation

We have given our documentation a significant refresh. Whether you are getting started or diving deep into TICK syntax, the docs are cleaner, more comprehensive, and easier to navigate.

Explore the new docs


That is QuestDB 9.3.2. TICK changes how you express time-range filters, while new aggregation and window functions expand your analytics toolkit. The engine keeps getting faster underneath.

Read the full 9.3.2 release notes

Ready to try it?

docker pull questdb/questdb
docker run -p 9000:9000 -p 8812:8812 questdb/questdb

Try a TICK query first. We think you will be hooked.

Download QuestDB 9.3.2

Join our Slack or Discourse communities to share feedback and results. We are excited to see what you build with TICK.

Subscribe to our newsletters for the latest. Secure and never shared or sold.