Skip to content

0.7.0 – 2026-10-18

Latest

Choose a tag to compare

@github-actions github-actions released this 19 Oct 00:39

Release Notes

Added

  • Aggregate time_weighted_mean(time, value [, 'forward_fill' | 'linear']): the mean of irregular readings weighted
    by how long each held, over each group's first to last reading; exact, as fast as avg (hourly means of 1,000 tags
    over 30 days: 2.0 s). Rollups store its state and answer wider buckets. Setting time-weighted-mean (auto,
    segments, merge) for tables with dedup off whose files overlap.
  • Aggregate m4(time, value): a group's first, smallest, largest and last points, as a list of {time, value}.
    Rollups store it and answer wider buckets from it (hourly points of 1,000 tags over 30 days: 2.0 → 0.51 s from a
    1-minute rollup). After Apache IoTDB's M4.
  • Rollups of rollups: a table's rollups are refreshed narrowest first, and each is computed from a narrower one where
    that is up to date (a daily rollup from the minute rollup: 5.2 → 1.8 s on 30 days of IIoT readings).
  • Rollups answer coarser queries: a query whose time_bucket is a multiple of the rollup's width (daily from an
    hourly rollup), or that groups by fewer of its columns, is answered by aggregating the rollup's rows again. IIoT,
    30 days, a 1-minute rollup: daily statistics per tag 2.1 → 0.25 s, 6-hourly totals 1.1 → 0.11 s.
  • Setting newest-first (on by default): ORDER BY time DESC LIMIT k reads time partitions newest first and stops
    once older ones can't hold any of the k newest rows (#72). IIoT, 30 days: the 100 newest readings before a past
    time 298 → 38 ms; TSBS IoT on local S3: the 10 newest readings 392 → 320 ms.
  • Setting in-list-pruning (on by default): column IN (…) filters of more than 20 values skip row groups and pages
    whose range holds none of the values, which DataFusion's pruning leaves alone (#103). IIoT, compacted, local disk:
    a 100-tag list 54 → 31 ms, a 21-tag list 53 → 26 ms. On object storage it also prunes with a join's runtime
    filter: IIoT energy on local S3 (20 ms per request) 54 → 26 ms repeated, 204 → 183 ms first run.
  • Setting filter-pushdown (auto, true, false): the Timelake reader applies filters while decoding Parquet and
    decodes the other columns only for rows that pass. auto, the default, turns it on for local files (TSBS geomeans
    4–5% faster, selective group-bys up to 40%) and off on object storage, where it adds a round trip per row group.
  • Data files use the codec in Iceberg's write.parquet.compression-codec and write.parquet.compression-level
    (ZSTD 3 by default; lz4, snappy, gzip, brotli, uncompressed). Before, Timelake always wrote ZSTD 3.

Changed

  • Breaking: Timelake's scans no longer follow DataFusion's datafusion.execution.parquet.pushdown_filters; set
    timelake.filter_pushdown instead (see Added).
  • Breaking (Rust): in timelake-format, rows::PartitionRows holds a partition's rows as a list of batches
    ((Option<i32>, Vec<RecordBatch>)), and Contract has new fields for the new settings. Callers of sort_and_split
    iterate the batches; code that builds a Contract field by field uses Contract::from_properties.
  • Tables created by other engines with a codec other than ZSTD in write.parquet.compression-codec are now written with
    that codec (see Added); tables Timelake created already say ZSTD.
  • Compaction's merge (also used for appends past 1 GiB) is up to 5× faster on files that alternate series by series,
    such as 5-minute batches of every device: 10 M rows of two such inputs merge in 2.6 s instead of 13.9 s.
  • The block cache sends GETs of at most 1 MiB (storage option timelake_cache_request_bytes; 0 for no limit),
    longer runs split into parts fetched at once. With 20 ms per request and 50 MiB/s per request, TSBS IoT first
    queries 126 → 115 ms (geomean), with 47% more requests.

Fixed

  • An append whose string or binary column held more than 2 GiB failed with "offset overflow" (one hour of a 400,000-tag
    plant): the rows were concatenated into one batch to sort. Appends now sort groups of up to 1 GiB and merge them.
  • The block cache fetched the runs of blocks one read needs one after another; it fetches them at once. First
    queries on object storage with 20 ms per request: TSBS IoT geomean 162 → 125 ms, one truck's history 233 → 109 ms.
  • Tigris is recognised when its endpoint comes from AWS_ENDPOINT_URL_S3 (as Fly.io and the Tigris CLI set it), so
    readers check for new versions with a LIST there, about 245 ms faster per check than a HEAD (#102).

Install timelake-cli 0.7.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/polythings/timelake/releases/download/v0.7.0/timelake-cli-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/polythings/timelake/releases/download/v0.7.0/timelake-cli-installer.ps1 | iex"

Download timelake-cli 0.7.0

File Platform Checksum
timelake-cli-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
timelake-cli-x86_64-apple-darwin.tar.xz Intel macOS checksum
timelake-cli-x86_64-pc-windows-msvc.zip x64 Windows checksum
timelake-cli-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
timelake-cli-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

Verifying GitHub Artifact Attestations

The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:

gh attestation verify <file-path of downloaded artifact> --repo polythings/timelake

You can also download the attestation from GitHub and verify against that directly:

gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation> --repo polythings/timelake