Aleksander Roszig
May 29, 2026 | 12 min Read
TimescaleDB can achieve compression of up to 98% for typical time-series data. Compressing time-series data requires a fundamentally different approach than the general-purpose algorithms used in OLTP databases. In TimescaleDB this is handled by the hypercore engine — a hybrid row-columnar engine that uses specialized algorithms: delta encoding, delta-of-delta, Gorilla XOR and run-length encoding. This article explains how it works and how to configure compression so that you actually achieve that ratio.
TimescaleDB compression - how it differs from PostgreSQL TOAST
PostgreSQL has a built-in mechanism called TOAST (The Oversized-Attribute Storage Technique), but TimescaleDB compression solves a fundamentally different problem. TOAST deals with individual large values (long strings, jsonb, bytea), whereas TimescaleDB compression optimizes cross-row patterns in time-series data. The two mechanisms are complementary, not competing — TimescaleDB even uses TOAST internally as a fallback for certain data types. PostgreSQL uses a fixed “page size”, typically 8 kB, and does not allow tuples to span multiple pages. For that reason, when field values are very large, the data must be compressed and/or split across multiple physical rows.
Feature TOAST (vanilla PostgreSQL) TimescaleDB hypercore Design goal Individual values > 2 KB Cross-row patterns in time-series Trigger Row exceeds TOAST_TUPLE_THRESHOLD (~2 KB) Per-chunk policy (e.g. older than 7 days) Supported types Variable-length only ( text , jsonb , bytea , numeric ) All data types Algorithms pglz (default), lz4 (since PG14, opt-in) Combination: delta encoding, delta-of-delta, simple-8b, run-length encoding, XOR-based, dictionary compression Compression granularity Per value (1 value = 1 byte stream) Per batch (~1000 rows together) Exploiting data structure No - treats values as opaque bytes Yes - exploits numeric structure, monotonicity, repetition Typical ratio for sensor floats ~1.0× (no compression) 10-20× Typical ratio for timestamps ~1.0× (no compression - fixed-length type) 50-100× (delta-of-delta for regular intervals) Typical ratio for text 2-3× (general-purpose LZ) 5-10× (dictionary + RLE if repetitive)
The table shows the scale of the difference. For a typical IoT workload with floats and timestamps — i.e. the columns TOAST does not compress at all — TimescaleDB reaches a ratio of 10-100×, because it is built for this type of data.
The Hypercore engine and columnar compression
In TimescaleDB, compression is handled by an engine called hypercore — a hybrid row-columnar engine in which new data lands in Postgres row-based chunks (fast INSERTs and UPDATEs), while older chunks are automatically converted to a columnar, compressed format. Analytical queries that read this compressed data read fewer bytes and run faster. This conversion enables compression of up to 98%, which significantly lowers storage costs in projects with long data retention. Unlike traditional row-based storage, where data is stored sequentially by row, columnar storage organizes and compresses data by column. As a result, queries can fetch only the necessary fields in batches instead of scanning entire rows.
What happens to the rows
... continue reading