Time-series database
A time-series database,
built into Postgres.Store metrics, events, and IoT data and query them by time with TimescaleDB, the open-source time-series extension for PostgreSQL. Run it on a managed Postgres instance, with the same backups, pooling, and scaling as the rest of your data. No separate time-series database to run, sync, or pay for.
The basics
What is a time-series database?
A time-series database is built to store data that arrives in time order, metrics, events, logs, and sensor readings, and to answer questions about it over time: rates, rollups, and trends across seconds, days, or years. It is optimised for heavy inserts and time-range queries rather than one-row-at-a-time lookups.
Ordinary tables slow down once a firehose of timestamped rows piles up: indexes bloat, and "average this metric per 5 minutes over the last month" turns into a full scan. Time-series databases fix this with time-based partitioning, compression, and functions built for time buckets.
The catch is that most teams already keep their real data, users, orders, devices, in PostgreSQL. With TimescaleDB, you do not need a second database for the time-series. Postgres becomes your time-series database too.
TimescaleDB is an extension, not a fork. It adds hypertables, native compression, and continuous aggregates to standard Postgres, so the metrics sit right next to the rows they describe.
How it works
How time-series on Postgres works,
in four steps.
Metrics, events, logs, and IoT readings all share one shape: a timestamp, some tags, and values. TimescaleDB is built to store and query exactly this, at scale, inside PostgreSQL.
Turn an ordinary Postgres table into a hypertable and TimescaleDB partitions it into chunks by time behind the scenes, so inserts and time-range queries stay fast as the table grows into billions of rows.
Native columnar compression shrinks historical chunks by an order of magnitude, so you keep months or years of history at a fraction of the storage, without moving it to another system.
Roll up with time_bucket() and continuous aggregates, and query it all in standard SQL, joined against the relational data already in your database.
What people build
What you would use
a time-series database for.
Store application and infrastructure metrics and query them by time range for dashboards and alerting, with no separate metrics store to run.
Ingest high-frequency readings from devices and sensors, then downsample and roll them up with continuous aggregates.
Keep a long, compressed history of user events and query trends over time in SQL, next to the users and orders they belong to.
Store ticks and trades and compute time-bucketed OHLC candles and rollups for charts and reporting.
Land structured logs in Postgres and slice them by time and tags, alongside the app that produced them.
Serve live, time-bucketed rollups from continuous aggregates that refresh as new data lands.
One database, not two
You probably do not need
a separate time-series database.
A standalone time-series system means a second thing to provision, secure, scale, and keep in sync with your source of truth. For most products that is more moving parts than the problem deserves.
With TimescaleDB, your metrics live next to the rows they describe. You can filter by a real column and bucket by time in the same query, wrap writes in a transaction, and trust one backup to cover all of it.
- ✓ Time-series and rows in one place, joined in plain SQL
- ✓ Real transactions, so metrics never drift from your data
- ✓ One thing to back up, scale, and pay for
-- 5-minute average temperature per device,
-- over the last day, newest first
SELECT time_bucket('5 minutes', ts) AS bucket,
device_id,
avg(temperature) AS avg_temp
FROM readings
WHERE ts > now() - interval '1 day'
GROUP BY bucket, device_id
ORDER BY bucket DESC; time_bucket() rolls rows into fixed intervals. Add a continuous aggregate to keep this rollup materialised and fresh.
Time-series on Selfhost.dev
A production time-series database.
Without the extra database.
Turn TimescaleDB on when you create a managed PostgreSQL instance, or enable it on an existing one. We set shared_preload_libraries, restart Postgres, and run CREATE EXTENSION, so it is ready to use.
Hypertables live in the same Postgres as your users, orders, and documents. Join time-series against relational data in plain SQL, inside real transactions.
TimescaleDB is open source and standard PostgreSQL. Your schema and queries stay portable with pg_dump and logical replication, with no proprietary API to get stuck behind.
Point-in-time recovery, automated backups, encryption at rest, and forking cover your time-series exactly like the rest of your Postgres data.
PgBouncer pooling, resizing, and Multi-AZ failover are all included, so ingest-heavy time-series workloads get the same production treatment as everything else.
Watch hypertable count, chunks, and the live compression ratio per instance, with alerts, from the console or from your AI editor with 150+ MCP tools.
How to choose
TimescaleDB, or a dedicated
time-series database?
InfluxDB, Prometheus, and other systems are purpose-built for time-series. They are good at it, and they are also a second system. Here is an honest way to decide.
Choose this when
- ✓ You already run Postgres and want one database, not two
- ✓ You need time-series and relational data joined in the same SQL
- ✓ You are storing metrics, events, IoT, or logs into the billions of rows
- ✓ You want compression, continuous aggregates, and real backups on your history
- ✓ You would rather not run, sync, and pay for a separate time-series system
Consider one when
- • You need a purpose-built ingest pipeline at extreme write rates
- • Your workload is pure metrics with no relational data beside it
- • You need very large-scale analytical scans over the full history
For very large-scale analytical scans, a columnar OLAP engine can pull ahead. Selfhost.dev also runs managed ClickHouse for exactly that, on the same account and bill.
TimescaleDB vs a dedicated time-series database, at a glance
| Factor | Postgres + TimescaleDB | Dedicated time-series DB (InfluxDB, Prometheus) |
|---|---|---|
| Architecture | An extension on the Postgres you already run | A separate system to provision and operate |
| Data model | SQL tables and hypertables, joined with your relational data | A custom model, separate from your relational data |
| Querying | Standard SQL with time_bucket() and continuous aggregates | A custom query language (PromQL, Flux) |
| Scale sweet spot | Metrics, events, IoT, and logs into the billions of rows | Very high ingest, pure-metrics workloads |
| Backups & recovery | Same PITR, backups, and forking as Postgres | A separate backup and recovery story |
| Cost | One database bill, from $5/mo | An extra service on top of your database |
Getting started
Turn it on in one click.
We handle the rest.
Turn on TimescaleDB when you create a managed PostgreSQL instance, or enable it on an existing Postgres instance from its settings. We set shared_preload_libraries, restart Postgres, and run CREATE EXTENSION timescaledb, so it is ready the moment the database is.