Back to Skills

migrate-postgres-tables-to-hypertables

verified

Comprehensive guide for migrating PostgreSQL tables to TimescaleDB hypertables with optimal configuration and performance validation

View on GitHub

Marketplace

aiguide

timescale/pg-aiguide

Plugin

pg

database

Repository

timescale/pg-aiguide
1.4kstars

skills/migrate-postgres-tables-to-hypertables/SKILL.md

Last Verified

January 17, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/timescale/pg-aiguide/blob/main/skills/migrate-postgres-tables-to-hypertables/SKILL.md -a claude-code --skill migrate-postgres-tables-to-hypertables

Installation paths:

Claude
.claude/skills/migrate-postgres-tables-to-hypertables/
Powered by add-skill CLI

Instructions

# PostgreSQL to TimescaleDB Hypertable Migration

Migrate identified PostgreSQL tables to TimescaleDB hypertables with optimal configuration, migration planning and validation.

**Prerequisites**: Tables already identified as hypertable candidates (use companion "find-hypertable-candidates" skill if needed).

## Step 1: Optimal Configuration

### Partition Column Selection

```sql
-- Find potential partition columns
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name = 'your_table_name'
  AND data_type IN ('timestamp', 'timestamptz', 'bigint', 'integer', 'date')
ORDER BY ordinal_position;
```

**Requirements:** Time-based (TIMESTAMP/TIMESTAMPTZ/DATE) or sequential integer (INT/BIGINT)

Should represent when the event actually occurred or sequential ordering.

**Common choices:**

- `timestamp`, `created_at`, `event_time` - when event occurred
- `id`, `sequence_number` - auto-increment (for sequential data without timestamps)
- `ingested_at` - less ideal, only if primary query dimension
- `updated_at` - AVOID (records updated out of order, breaks chunk distribution) unless primary query dimension

#### Special Case: table with BOTH ID AND Timestamp

When table has sequential ID (PK) AND timestamp that correlate:

```sql
-- Partition by ID, enable minmax sparse indexes on timestamp
SELECT create_hypertable('orders', 'id', chunk_time_interval => 1000000);
ALTER TABLE orders SET (
    timescaledb.sparse_index = 'minmax(created_at),...'
);
```

Sparse indexes on time column enable skipping compressed blocks outside queried time ranges.

Use when: ID correlates with time (newer records have higher IDs), need ID-based lookups, time queries also common

### Chunk Interval Selection

```sql
-- Ensure statistics are current
ANALYZE your_table_name;

-- Estimate index size per time unit
WITH time_range AS (
    SELECT
        MIN(timestamp_column) as min_time,
        MAX(timestamp_column) as max_time,
        EXTRACT(EPOCH FROM (MAX(tim

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
13566 chars