Time To Live (TTL)

TTL (Time To Live) automatically drops old partitions based on data age. Set a retention period, and QuestDB removes partitions that fall entirely outside that window - no cron jobs or manual cleanup required.

Timeline showing how TTL drops partitions when their entire time range falls outside the retention window

Requirements

TTL requires:

These are standard for time-series tables in QuestDB.

Setting TTL

At table creation

CREATE TABLE trades (
ts TIMESTAMP,
symbol SYMBOL,
price DOUBLE
) TIMESTAMP(ts) PARTITION BY DAY TTL 7 DAYS;

On existing tables

ALTER TABLE trades SET TTL 7 DAYS;

Supported units: HOUR/H, DAY/D, WEEK/W, MONTH/M, YEAR/Y.

-- These are equivalent
ALTER TABLE trades SET TTL 2 WEEKS;
ALTER TABLE trades SET TTL 2w;

For full syntax, see ALTER TABLE SET TTL.

How TTL works

TTL drops partitions based on the partition's time range, not individual row timestamps. A partition is dropped only when its entire period falls outside the TTL window.

Key rule: A partition is dropped when partition_end_time < reference_time - TTL.

Reference time

By default, TTL uses wall-clock time as the reference, not the maximum timestamp in the table. This protects against accidental data loss if a row with a far-future timestamp is inserted (which would otherwise cause all existing data to appear "expired").

The reference time is: min(max_timestamp_in_table, wall_clock_time)

To restore legacy behavior (using only max timestamp), set in server.conf:

cairo.ttl.use.wall.clock=false
caution

Disabling wall-clock protection means inserting a row with a future timestamp (e.g., year 2100) will immediately drop all partitions that fall outside the TTL window relative to that future time.

Example

Table partitioned by HOUR with TTL 1 HOUR:

Wall-clock timeActionPartitions remaining
08:00Insert row at 08:0008:00-09:00
09:00Insert row at 09:0008:00-09:00, 09:00-10:00
09:59Insert row at 09:5908:00-09:00, 09:00-10:00
10:00Insert row at 10:0009:00-10:00, 10:00-11:00

The 08:00-09:00 partition survives until 10:00 because its end time (09:00) must be more than 1 hour behind the reference time. At 10:00, the partition end (09:00) is exactly 1 hour old, so it's dropped.

Checking TTL settings

SELECT table_name, ttlValue, ttlUnit FROM tables();
table_namettlValuettlUnit
trades7DAY
metrics0null

A ttlValue of 0 means TTL is not configured.

Removing TTL

To disable automatic retention and keep all data:

ALTER TABLE trades SET TTL 0;

Guidelines

Data typeTypical TTLRationale
Real-time metrics1-7 daysHigh volume, recent data most valuable
Trading data30-90 daysCompliance requirements vary
Aggregated data1-2 yearsLower volume, longer analysis windows
Audit logsPer complianceOften legally mandated retention

Tips:

  • Match TTL to your longest typical query range plus a buffer
  • TTL should be significantly larger than your partition interval
  • For manual control instead of automatic TTL, see Data Retention