Skip to main content
pgtofu provides first-class support for TimescaleDB, enabling declarative management of hypertables, compression policies, retention policies, and continuous aggregates.

Overview

TimescaleDB extends PostgreSQL for time-series data with:
  • Hypertables - Automatic partitioning by time
  • Compression - Columnar compression for older data
  • Retention - Automatic data expiration
  • Continuous Aggregates - Pre-computed materialized views

Enabling TimescaleDB

First, ensure the extension is installed:

Hypertables

Creating Hypertables

Convert a regular table to a hypertable:

Chunk Time Interval

Specify the time interval for each chunk:
Recommended intervals:

Space Partitioning

Add an additional partitioning dimension:

Indexes on Hypertables

Compression

Enabling Compression

Configure compression settings:
Parameters:
  • compress_segmentby - Columns to segment by (for filtering)
  • compress_orderby - Column ordering within segments

Compression Policies

Automatically compress old data:

Multiple Segment Columns

Manual Compression

Retention Policies

Automatic Data Expiration

Retention Policy Management

Continuous Aggregates

Creating Continuous Aggregates

Pre-compute aggregations that update automatically:

Refresh Policies

Automatically refresh aggregates:
Parameters:
  • start_offset - How far back to look for updates
  • end_offset - Lag from real-time (prevents refreshing incomplete data)
  • schedule_interval - How often to run the refresh

Hierarchical Aggregates

Build aggregates on top of aggregates:

Querying Continuous Aggregates

Complete Example

Here’s a complete time-series schema:

pgtofu Extraction

When extracting from a TimescaleDB database, pgtofu captures:

Migration Generation

pgtofu generates proper TimescaleDB DDL:

Best Practices

  • Target 25% of available memory per chunk
  • Smaller chunks = faster compression, more overhead
  • Larger chunks = better query performance, slower compression
  • segmentby: Columns used in WHERE clauses
  • orderby: Usually the time column, descending
  • Compress after data is no longer frequently updated
  • Use for frequently-run aggregate queries
  • Consider hierarchical aggregates for different time granularities
  • Set end_offset to avoid refreshing incomplete data
  • Set retention before tables grow too large
  • Consider archiving before deletion
  • Retention only drops whole chunks

Troubleshooting

Ensure TimescaleDB is installed and the extension is created:
The table must have a time column with TIMESTAMPTZ type:
Check that segmentby columns have good cardinality and orderby column is appropriate.

See Also