Skip to content

ADR-0002: Plain PostgreSQL partitioning for telemetry, not TimescaleDB

Status: accepted (2026-08-15)

Telemetry is append-only time-series data, device metrics every 60 seconds. TimescaleDB is the obvious tool; declarative range partitioning is the boring alternative.

Daily range-partitioned plain PostgreSQL tables, with partitions created and dropped by a dispatcher maintenance job. A non-partitioned device_status_latest hot cache serves the dashboard.

  • TimescaleDB’s compelling features (compression, continuous aggregates) sit under the Timescale License, which is awkward inside an AGPL distribution and rules out the stock postgres image self-hosters expect.
  • v1 volumes (1,000 devices is about 1.4M rows/day) are trivial for partitioned PostgreSQL.
  • Retention is DROP TABLE on old partitions, with no vacuum churn.
  • We own partition maintenance: a dispatcher scheduled job, with tests.
  • If fleets reach a scale where compression matters, revisit. The ingest path is isolated in one module, so a storage swap stays contained.

Bitemporal inventory facts are unrelated to this choice: they are regular tables with tstzrange columns. See the bitemporal concept page.