Timelaketimelake
DocsBenchmarksRoadmapSpecContribute
Apache 2.0 ·
TimelaketimelakeThe open time-series lakehouse.
v0 · Apache 2.0 · Contribute · GitHubBuilt on Apache Arrow, Apache DataFusion, Apache Parquet, and Apache Iceberg.
Benchmarks

TSBS IoT

A truck fleet's location and diagnostics, streamed in and queried like a fleet dashboard.

We use TSBS's data generator, unchanged, and its 12 query types, ported to SQL every system runs. We don't use TSBS's loaders or query runners: timebench loads the data and times the queries, so the numbers don't compare with published TSBS results.

Methodology TSBS on GitHub
TSBS IoT · After maintenanceTSBS IoT · Right after ingestSingle truck · After maintenanceSingle truck · Right after ingestIngest and maintenanceWhile ingestingConcurrent dashboardsCostFailed or timed outWhat each entry meansOver time

TSBS IoT · After maintenance

After each system's maintenance, first run of each query in a fresh process. Systems maintain at different times: Timelake while it ingests, most others in a separate step after it, some not at all; the panel below says which, and how long the step after ingest took.

Tuned·Run of 2026-10-19

Maintenance before these queries

When each system maintains its tables, and how long its step after the last commit took.

  • TimelakeWhile it ingests: each append compacts what it can. The step after ingest only finishes what's left.3.5 s
  • Iceberg (PyIceberg)A separate job after ingest; until it runs, readers see every small file.102 s
  • LanceA separate job after ingest.18.9 s
  • Parquet filesA separate job after ingest.138 s
Rank by
QueryTimelakevs fastest

All queries

The geometric mean over the 12 queries. First run of every reader; lower is better.

  1. 151 ms
  2. 232 ms1.5×
  3. 341 ms2.3×
  4. 354 ms2.3×
  5. 388 ms2.6×
  6. 457 ms3.0×
  7. 511 ms3.4×

Time over runs

First-run time in each of the 4 runs on this storage; dashed: a system read by another engine.

TSBS IoT · Right after ingest

Right after the last commit, before any maintenance: the state readers see while data streams in.

Tuned·Run of 2026-10-19

Rank by
QueryTimelakevs fastest

All queries

The geometric mean over the 12 queries. First run of every reader; lower is better.

  1. 280 ms
  2. 520 ms1.9×
  3. 1.33 s4.7×
  4. 1.35 s4.8×
  5. 1.78 s6.3×
  6. 5.56 s20×
  7. 7.37 s26×

Time over runs

First-run time in each of the 4 runs on this storage; dashed: a system read by another engine.

Single truck · After maintenance

After each system's maintenance, first run of each query in a fresh process. Systems maintain at different times: Timelake while it ingests, most others in a separate step after it, some not at all; the panel below says which, and how long the step after ingest took.

Tuned·Run of 2026-10-19

Maintenance before these queries

When each system maintains its tables, and how long its step after the last commit took.

  • TimelakeWhile it ingests: each append compacts what it can. The step after ingest only finishes what's left.3.5 s
  • Iceberg (PyIceberg)A separate job after ingest; until it runs, readers see every small file.102 s
  • LanceA separate job after ingest.18.9 s
  • Parquet filesA separate job after ingest.138 s
Rank by
QueryTimelakevs fastest

All queries

The geometric mean over the 5 queries. First run of every reader; lower is better.

  1. 98 ms
  2. 118 ms1.2×
  3. 306 ms3.1×
  4. 312 ms3.2×
  5. 357 ms3.6×
  6. 428 ms4.4×
  7. 450 ms4.6×

Time over runs

First-run time in each of the 4 runs on this storage; dashed: a system read by another engine.

Single truck · Right after ingest

Right after the last commit, before any maintenance: the state readers see while data streams in.

Tuned·Run of 2026-10-19

Rank by
QueryTimelakevs fastest

All queries

The geometric mean over the 5 queries. First run of every reader; lower is better.

  1. 186 ms
  2. 432 ms2.3×
  3. 884 ms4.7×
  4. 1.89 s10×
  5. 2.15 s12×
  6. 2.77 s15×
  7. 6.88 s37×

Time over runs

First-run time in each of the 4 runs on this storage; dashed: a system read by another engine.

Ingest and maintenance

How each system took the data in and kept it in shape: load rate, commit times, maintenance, and what it stored.

Tuned·Run of 2026-10-19

Commit

median time per commit while streaming; lower is better

  1. 85 ms
  2. 171 ms2.0×
  3. 212 ms2.5×
  4. 943 ms11×

Latest position of 945 trucks

Timelake5 requests · 0.44 s
Lance + DuckDB3,458 requests · 1.77 s
Iceberg (PyIceberg) + DuckDB1,733 requests · 7.34 s
Parquet files + DuckDB1,731 requests · 6.69 s

Requests each system makes for one query, right after ingest, and the time it takes; each dot is a request.

Per system

Committing is the time spent in all commits together. Storage is all files after maintenance, counting replaced files still waiting for cleanup.

SystemCommittingCommit p50Commit p95MaintenanceFilesStorage
Timelake274 s85 ms864 ms3.5 s223369 MB
Iceberg (PyIceberg)28 min943 ms1180 ms102 s1,7351.1 GB
Lance396 s212 ms352 ms18.9 s23452 MB
Parquet files300 s171 ms207 ms138 s7257 MB

Scroll the table sideways for every column.

While ingesting

Fresh readers during ingest: whether they saw every finished commit, and how fast dashboard queries ran under writes.

Tuned·Run of 2026-10-19

Per system

Every 15 s during ingest, a fresh reader ran the dashboard queries and checked the newest row it could see. Behind: probes that missed a commit that had already finished.

SystemProbes behindMost behindDashboard query, median
Timelake0 of 52—164 ms
Iceberg (PyIceberg)0 of 27—1.27 s
Lance0 of 34—1.13 s
Parquet files0 of 24—2.17 s

Scroll the table sideways for every column.

Concurrent dashboards

Several clients at once after maintenance, each with its own reader, running the dashboard queries in turn.

Tuned·Run of 2026-10-19

Per system

After maintenance, 1, 4, 16 clients at once, each with its own reader open, running the dashboard queries in turn for 30 s. Queries per second over all clients, and the 95th percentile latency.

System1 client4 clients16 clients
Timelake121.4 q/sp95 15 ms347.6 q/sp95 23 ms423.4 q/sp95 93 ms
Iceberg (PyIceberg)16.1 q/sp95 106 ms36.9 q/sp95 205 ms40.7 q/sp95 854 ms
Lance3.8 q/sp95 398 ms7.3 q/sp95 916 ms8.8 q/sp95 3.02 s
Parquet files31.0 q/sp95 39 ms128.1 q/sp95 39 ms267.6 q/sp95 83 ms

Scroll the table sideways for every column.

Cost

Requests and storage at the store's list prices; machines are not included.

AWS S3·Tuned·Run of 2026-10-19

On AWS S3

Ingest is scaled to a month of data arriving at this rate.

SystemIngest, per monthStorage, per monthPer query
Timelake$0.80$0.0079$0.000017
Iceberg (PyIceberg)$2.30$0.024$0.000011
Lance$2.77$0.0097$0.000047
Parquet files$1.10$0.0055$0.000017

Scroll the table sideways for every column.

Failed or timed out

Left out of the rankings above; each query's list says which readers it lost.

Tiger Cloud·Tuned·Run of 2026-10-12

Per reader

  • TimescaleDB2low-fuel (right after ingest), high-load (right after ingest)

What each entry means

Each system is written, maintained, and read the way its own docs suggest, on the same data. An entry in a ranking is a system, or a system and the reader that queried it, such as Lance + DuckDB.

Every system runs in two tunings. Tuned: each system as its docs recommend, precomputation included. Default: each system as installed. Results are tuned unless a section's switch says otherwise.

Timelake

Timelake's own writer: Iceberg tables of sorted Parquet, compacted as it appends.

Written
Table.append per commit, with inline maintenance (compaction, dedup, retention).
Maintenance
timelake maintain: each partition rewritten into one sorted file, rollups refreshed.
When
While it ingests: each append compacts what it can. The step after ingest only finishes what's left.
Tuned
The workload's rollups, and its queries in Timelake's own functions where the docs write them that way.
Read by
Timelake: Timelake's own reader (the CLI, on DataFusion), with dedup on read, its indexes and its cache.DuckDB: Timelake's tables read by plain DuckDB, with no Timelake software: it sees rows that arrived twice until compaction removes them.

Iceberg (PyIceberg)

Plain Iceberg tables written by PyIceberg appends: what a Firehose stream into S3 Tables writes.

Written
PyIceberg append per commit, tables partitioned by day.
Maintenance
A bin-pack rewrite of small files, S3 Tables' default compaction.
When
A separate job after ingest; until it runs, readers see every small file.
Tuned
A sort order on the series key and time, and compaction that sorts each day by it.
Read by
DuckDB: DuckDB reading the files directly with its Iceberg, Lance or Parquet support: no Timelake software.

Lance

Lance datasets, appended commit by commit.

Written
write_dataset in append mode per commit.
Maintenance
compact_files, then cleanup_old_versions.
When
A separate job after ingest.
Tuned
Its maintenance, then a B-tree index on the series key and a zone map on time. Default: no maintenance.
Read by
DuckDB: DuckDB reading the files directly with its Iceberg, Lance or Parquet support: no Timelake software.DataFusion: Apache DataFusion reading the files directly, from Python.

Parquet files

Parquet files without a table format: a new file per commit, as an S3 sink writes them.

Written
A Parquet file per commit in a folder per day.
Maintenance
Each day rewritten into one sorted file.
When
A separate job after ingest.
Tuned
Its maintenance. Default: the files as written, no maintenance.
Read by
DuckDB: DuckDB reading the files directly with its Iceberg, Lance or Parquet support: no Timelake software.DataFusion: Apache DataFusion reading the files directly, from Python.

TimescaleDB

TimescaleDB, a PostgreSQL database for time series, on its server's own disk.

Written
COPY per commit into hypertables; rows that arrive twice are skipped.
Maintenance
Every chunk converted to its columnstore.
When
A separate step after ingest (in production, a background policy on older chunks).
Tuned
An index on (series, time), the columnstore, and continuous aggregates its tuned queries read. Default: the hypertable as created, row store.
Read by
PostgreSQL: SQL over PostgreSQL's protocol.

Over time

Each system's own reader after maintenance: the geometric mean of first runs over the queries it completed in each run. The weekly run adds a point each week.

AWS S3

4 runs

Local disk

5 runs

Tiger Cloud

1 run

All runs

Hover or tap ⓘ for the machine, the commit and every version.

  • 2026-10-19AWS S3Timelake, Iceberg (PyIceberg), Lance, Parquet filesweekly
  • 2026-10-19Local diskTimelake, Iceberg (PyIceberg), Lance, Parquet files, TimescaleDBweekly
  • 2026-10-19Local diskTimelakejsonl
  • 2026-10-16AWS S3Timelake, Iceberg (PyIceberg), Lance, Parquet filesweekly
  • 2026-10-16Local diskTimelake, Iceberg (PyIceberg), Lance, Parquet files, TimescaleDBweekly
  • 2026-10-15AWS S3Timelake, Iceberg (PyIceberg), Lance, Parquet filesweekly
  • 2026-10-15Local diskTimelake, Iceberg (PyIceberg), Lance, Parquet files, TimescaleDBweekly
  • 2026-10-13AWS S3Iceberg (PyIceberg), Lance, Timelake, S3 Tables (PyIceberg)jsonl
  • 2026-10-13Local diskIceberg (PyIceberg), Lance, Timelakejsonl
  • 2026-10-12Tiger CloudTimescaleDBjsonl