PostgreSQL

PostgreSQL Declarative Partitioning: Range, Indexes, and pg_partman Automation

Implement PostgreSQL declarative range partitioning with partition pruning, propagated indexes, instant DETACH for archival, and pg_partman for automated partition management.

JusDB Team
September 15, 2025
5 min read
182 views

PostgreSQL's declarative partitioning (introduced in PG10, significantly improved in PG11-14) enables partition pruning, partition-wise joins, and efficient bulk data management. Here is how to use it effectively.

Declarative Range Partitioning

sql
CREATE TABLE orders (
  id         BIGSERIAL,
  user_id    UUID NOT NULL,
  amount     NUMERIC(10,2),
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
) PARTITION BY RANGE (created_at);

CREATE TABLE orders_2025_q1 PARTITION OF orders
  FOR VALUES FROM ('2025-01-01') TO ('2025-04-01');

CREATE TABLE orders_2025_q2 PARTITION OF orders
  FOR VALUES FROM ('2025-04-01') TO ('2025-07-01');

-- Default partition catches out-of-range rows
CREATE TABLE orders_default PARTITION OF orders DEFAULT;

Indexes on Partitioned Tables

sql
-- Creating an index on the parent propagates to all partitions
CREATE INDEX idx_orders_user ON orders (user_id);

-- Unique constraint must include partition key
CREATE UNIQUE INDEX idx_orders_id_created ON orders (id, created_at);

Verify Partition Pruning

sql
EXPLAIN SELECT * FROM orders
WHERE created_at BETWEEN '2025-01-01' AND '2025-03-31';
-- Should show: Append -> Seq Scan on orders_2025_q1 (only 1 partition)
-- NOT: scans all partitions

Attach and Detach Partitions

sql
-- Create new partition before the month starts
CREATE TABLE orders_2025_q3 PARTITION OF orders
  FOR VALUES FROM ('2025-07-01') TO ('2025-10-01');

-- Detach old partition (instant, no data copy)
ALTER TABLE orders DETACH PARTITION orders_2025_q1;

-- Now orders_2025_q1 is a standalone table
-- Archive it to cold storage, then drop
\COPY orders_2025_q1 TO '/archive/orders_q1.csv' CSV HEADER;
DROP TABLE orders_2025_q1;

pg_partman for Automated Partition Management

sql
CREATE EXTENSION pg_partman;

-- Auto-create monthly partitions and manage retention
SELECT partman.create_parent(
  p_parent_table => 'public.orders',
  p_control      => 'created_at',
  p_type         => 'range',
  p_interval     => 'monthly',
  p_premake      => 3  -- create 3 future partitions in advance
);

-- Run maintenance (create future partitions, drop expired ones)
CALL partman.run_maintenance_proc();

Key Takeaways

  • Always include a DEFAULT partition to catch rows outside defined ranges
  • Verify partition pruning with EXPLAIN — queries must filter on the partition key
  • Use DETACH PARTITION to archive old data instantly without DELETE overhead
  • pg_partman automates partition creation and retention — use it for any time-series table

JusDB Can Help

PostgreSQL partitioning strategy depends on your query patterns and data retention requirements. JusDB can design and implement the right partitioning scheme for your workload.

Share this article

JusDB Team

Official JusDB content team