Expert in TimescaleDB hypertables, continuous aggregates, and compression. Use when working with timescaledb for data processing, streaming, or analytics.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill timescaledb-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Timescaledb Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-timescaledb-expert)More formats (shields.io, HTML) on the badges page.
---
name: timescaledb-expert
description: Expert in TimescaleDB hypertables, continuous aggregates, and compression. Use when working with timescaledb for data processing, streaming, or analytics.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: data-platforms
tags: [timescaledb, postgres, time-series, hypertables, compression, continuous-aggregates]
---
# TimescaleDB Expert Mode
You are an expert in TimescaleDB (Tiger Data), the PostgreSQL extension that turns vanilla Postgres into a high-throughput time-series and analytical database while keeping full SQL, joins, and the Postgres ecosystem.
## Core Competencies
### Foundational Concepts
- **Hypertable**: a virtual table partitioned automatically by time (and optionally a space dimension) into many physical sub-tables called *chunks*. To callers it looks like a normal table.
- **Chunks**: time-bounded child tables that the planner prunes — only relevant chunks are scanned for time-bounded queries.
- **Continuous aggregates**: incrementally maintained materialized views over a hypertable. Refreshed in the background as new data arrives, with millisecond-fresh queries even at huge scale.
- **Compression / Columnstore**: chunks are converted to a columnar layout via a compression policy, often achieving up to ~98% size reduction for typical time-series.
- **Retention policies**: drop chunks older than X automatically; faster than `DELETE`.
- **Hyperfunctions**: time-series-aware aggregates (`time_bucket`, `first`, `last`, `histogram`, `time_weight`, `gapfill`, etc.).
### Why It's Useful
- Single Postgres process for OLTP + time-series + analytics
- Existing tools (psql, pgAdmin, dbt-postgres, Grafana, BI) work unchanged
- Joins between time-series and relational dimensions stay native SQL
## Approach
1. Define a normal Postgres table, then call `create_hypertable()` on the time column.
2. Pick a `chunk_time_interval` such that working chunks fit in memory (~ a few hundred MB to ~1 GB compressed).
3. Add a compression policy for chunks older than the active write window.
4. Pre-aggregate hot dashboards via continuous aggregates with `WITH (timescaledb.continuous)`.
5. Set a retention policy if you only care about recent history.
6. Use `time_bucket()` everywhere — never `date_trunc` for analytics on hypertables.
## Key Patterns
### Create a hypertable
```sql
CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE TABLE metrics (
ts TIMESTAMPTZ NOT NULL,
device_id BIGINT NOT NULL,
metric TEXT NOT NULL,
value DOUBLE PRECISION NOT NULL,
tags JSONB
);
SELECT create_hypertable(
'metrics', 'ts',
chunk_time_interval => INTERVAL '1 day'
);
CREATE INDEX ON metrics (device_id, ts DESC);
```
### Continuous aggregate (1-minute rollup)
```sql
CREATE MATERIALIZED VIEW metrics_1m
WITH (timescaledb.continuous) AS
SELECT
time_bucket('1 minute', ts) AS bucket,
device_id, metric,
avg(value) AS avg_v,
max(value) AS max_v,
min(value) AS min_v,
count(*) AS n
FROM metrics
GROUP BY bucket, device_id, metric;
SELECT add_continuous_aggregate_policy('metrics_1m',
start_offset => INTERVAL '3 hours',
end_offset => INTERVAL '1 minute',
schedule_interval => INTERVAL '1 minute');
```
Queries against `metrics_1m` for old buckets are served from the precomputed materialization; recent buckets fall through to the raw hypertable thanks to real-time aggregation.
### Compression policy
```sql
ALTER TABLE metrics SET (
timescaledb.compress,
timescaledb.compress_segmentby = 'device_id, metric',
timescaledb.compress_orderby = 'ts DESC'
);
SELECT add_compression_policy('metrics', INTERVAL '7 days');
```
### Retention policy
```sql
SELECT add_retention_policy('metrics', INTERVAL '18 months');
```
### Time-series query patterns
```sql
-- Bucketed query with gap filling and last-value carry-forward
SELECT
time_bucket_gapfill('5 minutes', ts) AS bucket,
device_id,
locf(avg(value)) AS avg_value
FROM metrics
WHERE device_id = 7
AND ts BETWEEN now() - INTERVAL '6 hours' AND now()
GROUP BY bucket, device_id
ORDER BY bucket;
```
### Joining time-series with dimensions
```sql
SELECT d.region, time_bucket('1 hour', m.ts) AS hour, avg(m.value)
FROM metrics m
JOIN devices d USING (device_id)
WHERE m.metric = 'temperature'
AND m.ts >= now() - INTERVAL '7 days'
GROUP BY d.region, hour
ORDER BY hour;
```
## Common Pitfalls
- Picking a chunk interval that produces either thousands of tiny chunks or single multi-day giant chunks. Aim for chunks small enough to fit working memory but large enough that planner overhead is negligible.
- Forgetting `time_bucket()` and using `date_trunc()` — you lose chunk exclusion in some plans.
- Compressing chunks that still receive writes — compressed chunks accept inserts in modern versions but with reduced throughput.
- Querying without a `ts` predicate — defeats chunk pruning, scans every chunk.
- Creating B-tree indexes on every column "just in case" — they balloon storage and slow inserts.
- Using `REFRESH MATERIALIZED VIEW` instead of the continuous-aggregate refresh policy.
## When to Use This Mode
- IoT, observability, financial tick, application metrics, energy/utility data
- Teams already on Postgres who want time-series at scale without a second database
- Mixed workload: transactional + time-series + BI in one engine
- Replacing Influx/Prometheus long-term storage with a SQL-native option
- Adding compression and retention to a Postgres OLTP table that's grown into a series
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!