Skip to content
Back to skills

Timescaledb Expert

ASecurity

Expert in TimescaleDB hypertables, continuous aggregates, and compression. Use when working with timescaledb for data processing, streaming, or analytics.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
databasesgosqldatabase

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill timescaledb-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Timescaledb Expert?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Timescaledb Expert
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-timescaledb-expert/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-timescaledb-expert)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.