citus

Distributed PostgreSQL as an extension

Overview

PackageVersionCategoryLicenseLanguage
citus14.1.0OLAPAGPL-3.0C
IDExtensionBinLibLoadCreateTrustRelocSchema
2400citusNoYesYesYesNoNopg_catalog
2401citus_columnarNoYesNoYesNoNopg_catalog
Relatedpg_partman plproxy columnar pg_fkpart timescaledb pg_duckdb tablefunc hll
Depended Bydocumentdb_distributed

conflict with hydra

Version

TypeRepoVersionPG VerPackageDeps
EXTPIGSTY14.1.01817161514citus-
RPMPIGSTY14.1.01817161514citus_$v-
DEBPIGSTY14.1.01817161514postgresql-$v-citus-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
PGDG 13.0.0
el8.x86_64.pg14 : citus_14
citus_14-13.0.0-1PGDG.rhel8.x86_64.rpm PGDG · 13.0.0 · 814.2KiB citus_14-12.1.6-1PGDG.rhel8.x86_64.rpm PGDG · 12.1.6 · 813.6KiB citus_14-12.1.5-1PGDG.rhel8.x86_64.rpm PGDG · 12.1.5 · 812.5KiB citus_14-12.1.4-1PGDG.rhel8.x86_64.rpm PGDG · 12.1.4 · 812.5KiB citus_14-12.1.3-1PGDG.rhel8.x86_64.rpm PGDG · 12.1.3 · 812.3KiB citus_14-12.1.2-1PGDG.rhel8.x86_64.rpm PGDG · 12.1.2 · 811.1KiB citus_14-12.1.1-1PGDG.rhel8.x86_64.rpm PGDG · 12.1.1 · 811.0KiB citus_14-12.1.0-2PGDG.rhel8.x86_64.rpm PGDG · 12.1.0 · 810.5KiB citus_14-12.0.0-1PGDG.rhel8.x86_64.rpm PGDG · 12.0.0 · 813.4KiB citus_14-11.3.0-2.rhel8.x86_64.rpm PGDG · 11.3.0 · 796.7KiB citus_14-11.2.1-1.rhel8.x86_64.rpm PGDG · 11.2.1 · 776.9KiB citus_14-11.2.0-1.rhel8.x86_64.rpm PGDG · 11.2.0 · 776.0KiB citus_14-11.1.5-1.rhel8.x86_64.rpm PGDG · 11.1.5 · 765.6KiB citus_14-11.1.4-1.rhel8.x86_64.rpm PGDG · 11.1.4 · 765.3KiB citus_14-11.1.3-1.rhel8.x86_64.rpm PGDG · 11.1.3 · 765.1KiB citus_14-11.1.2-1.rhel8.x86_64.rpm PGDG · 11.1.2 · 764.4KiB citus_14-11.1.1-1.rhel8.x86_64.rpm PGDG · 11.1.1 · 762.6KiB citus_14-11.0.6-1.rhel8.x86_64.rpm PGDG · 11.0.6 · 701.4KiB citus_14-11.0.5-1.rhel8.x86_64.rpm PGDG · 11.0.5 · 700.3KiB citus_14-11.0.4-1.rhel8.x86_64.rpm PGDG · 11.0.4 · 699.6KiB citus_14-11.0.3-1.rhel8.x86_64.rpm PGDG · 11.0.3 · 699.5KiB citus_14-11.0.2-1.rhel8.x86_64.rpm PGDG · 11.0.2 · 698.6KiB citus_14-10.2.5-1.rhel8.x86_64.rpm PGDG · 10.2.5 · 618.5KiB citus_14-10.2.4-1.rhel8.x86_64.rpm PGDG · 10.2.4 · 618.6KiB citus_14-10.2.3-1.rhel8.x86_64.rpm PGDG · 10.2.3 · 618.5KiB citus_14-10.2.2-1.rhel8.x86_64.rpm PGDG · 10.2.2 · 615.3KiB citus_14-10.2.1-1.rhel8.x86_64.rpm PGDG · 10.2.1 · 614.8KiB citus_14-10.2.0-1.rhel8.x86_64.rpm PGDG · 10.2.0 · 614.0KiB
el8.aarch64
el9.x86_64
PGDG 13.0.0
el9.x86_64.pg14 : citus_14
citus_14-13.0.0-1PGDG.rhel9.x86_64.rpm PGDG · 13.0.0 · 803.4KiB citus_14-12.1.6-1PGDG.rhel9.x86_64.rpm PGDG · 12.1.6 · 802.9KiB citus_14-12.1.5-1PGDG.rhel9.x86_64.rpm PGDG · 12.1.5 · 800.4KiB citus_14-12.1.4-1PGDG.rhel9.x86_64.rpm PGDG · 12.1.4 · 800.6KiB citus_14-12.1.3-1PGDG.rhel9.x86_64.rpm PGDG · 12.1.3 · 800.1KiB citus_14-12.1.2-1PGDG.rhel9.x86_64.rpm PGDG · 12.1.2 · 798.9KiB citus_14-12.1.1-1PGDG.rhel9.x86_64.rpm PGDG · 12.1.1 · 798.9KiB citus_14-12.1.0-2PGDG.rhel9.x86_64.rpm PGDG · 12.1.0 · 798.9KiB citus_14-12.0.0-1PGDG.rhel9.x86_64.rpm PGDG · 12.0.0 · 802.0KiB citus_14-11.3.0-2.rhel9.x86_64.rpm PGDG · 11.3.0 · 787.6KiB citus_14-11.2.1-1.rhel9.x86_64.rpm PGDG · 11.2.1 · 767.2KiB citus_14-11.2.0-1.rhel9.x86_64.rpm PGDG · 11.2.0 · 766.5KiB citus_14-11.1.5-1.rhel9.x86_64.rpm PGDG · 11.1.5 · 756.8KiB citus_14-11.1.4-1.rhel9.x86_64.rpm PGDG · 11.1.4 · 755.9KiB citus_14-11.1.3-1.rhel9.x86_64.rpm PGDG · 11.1.3 · 755.8KiB citus_14-11.1.2-1.rhel9.x86_64.rpm PGDG · 11.1.2 · 755.4KiB citus_14-11.1.1-1.rhel9.x86_64.rpm PGDG · 11.1.1 · 754.1KiB citus_14-11.0.6-1.rhel9.x86_64.rpm PGDG · 11.0.6 · 691.3KiB citus_14-11.0.5-1.rhel9.x86_64.rpm PGDG · 11.0.5 · 690.5KiB citus_14-11.0.4-1.rhel9.x86_64.rpm PGDG · 11.0.4 · 690.0KiB citus_14-11.0.3-1.rhel9.x86_64.rpm PGDG · 11.0.3 · 689.8KiB citus_14-11.0.2-1.rhel9.x86_64.rpm PGDG · 11.0.2 · 689.0KiB citus_14-10.2.5-1.rhel9.x86_64.rpm PGDG · 10.2.5 · 612.1KiB citus_14-10.2.4-1.rhel9.x86_64.rpm PGDG · 10.2.4 · 613.7KiB citus_14-10.2.3-1.rhel9.x86_64.rpm PGDG · 10.2.3 · 613.7KiB
el9.aarch64
el10.x86_64PIGSTY MISS
el10.aarch64PIGSTY MISS
d12.x86_64
d12.aarch64
d13.x86_64PIGSTY MISS
d13.aarch64
PIGSTY 14.1.0
PIGSTY 14.1.0
PIGSTY 14.1.0
PIGSTY 13.2.0
PIGSTY MISS
u22.x86_64
u22.aarch64
PIGSTY 14.1.0
PIGSTY 14.1.0
PIGSTY 14.1.0
PIGSTY 13.2.0
PIGSTY 13.0.0
u24.x86_64
u24.aarch64
PIGSTY 14.1.0
PIGSTY 14.1.0
PIGSTY 14.1.0
PIGSTY 13.2.0
PIGSTY 13.0.0
u26.x86_64PIGSTY MISSPIGSTY MISS
u26.aarch64PIGSTY MISSPIGSTY MISS

Build

You can build the RPM / DEB packages for citus using pig build:

pig build pkg citus         # build RPM / DEB packages

Install

You can install citus directly. First, make sure the PGDG and PIGSTY repositories are added and enabled:

pig repo add pgsql -u          # Add repo and update cache

Install the extension using pig or apt/yum/dnf:

pig install citus;          # Install for current active PG version
pig ext install -y citus -v 18  # PG 18
pig ext install -y citus -v 17  # PG 17
pig ext install -y citus -v 16  # PG 16
dnf install -y citus_18       # PG 18
dnf install -y citus_17       # PG 17
dnf install -y citus_16       # PG 16
apt install -y postgresql-18-citus   # PG 18
apt install -y postgresql-17-citus   # PG 17
apt install -y postgresql-16-citus   # PG 16

Preload:

shared_preload_libraries = 'citus';

Create Extension:

CREATE EXTENSION citus;

Usage

Sources:

Citus turns PostgreSQL into a distributed database by sharding tables across worker nodes while keeping PostgreSQL SQL, indexes, extensions, transactions, and operational tooling as the user-facing surface. It is commonly used for multi-tenant SaaS databases, real-time analytics, time-series/event workloads, and distributed microservice schemas.

The local Pigsty catalog packages Citus as citus and exposes the lead extension citus; the same package also contains citus_columnar. Citus is a preload extension, so every node must load the library before CREATE EXTENSION.

Enable Citus

shared_preload_libraries = 'citus'

Restart PostgreSQL on the coordinator and workers, then create the extension in the database:

CREATE EXTENSION IF NOT EXISTS citus;
SELECT citus_version();

On a multi-node cluster, register the coordinator and workers from the coordinator:

SELECT citus_set_coordinator_host('coord-1', 5432);
SELECT * FROM citus_add_node('worker-1', 5432);
SELECT * FROM citus_add_node('worker-2', 5432);

SELECT * FROM citus_get_active_worker_nodes();

Distributed Tables

Distribute a table by a shard key. Rows with the same shard-key value are colocated on the same shard, so tenant-scoped joins and point lookups stay local.

CREATE TABLE events (
  tenant_id  bigint,
  event_id   bigserial,
  event_at   timestamptz DEFAULT now(),
  kind       text,
  payload    jsonb,
  PRIMARY KEY (tenant_id, event_id)
);

SELECT create_distributed_table('events', 'tenant_id');

You can tune the shard count and colocation explicitly:

SELECT create_distributed_table(
  'events',
  'tenant_id',
  shard_count  := 64,
  colocate_with := 'default'
);

Queries that filter on the distribution column can route to a single shard:

SELECT *
FROM events
WHERE tenant_id = 42
ORDER BY event_at DESC
LIMIT 50;

Cross-shard queries are planned as distributed tasks and run in parallel on the workers:

SELECT kind, count(*)
FROM events
WHERE event_at >= now() - interval '1 hour'
GROUP BY kind
ORDER BY count DESC;

Reference Tables

Reference tables are fully replicated to all workers. They are useful for small lookup tables that must join with many distributed tables.

CREATE TABLE countries (
  code text PRIMARY KEY,
  name text NOT NULL
);

SELECT create_reference_table('countries');

Schema-Based Sharding

Schema-based sharding is useful when each tenant or service owns its own schema. In v14.1.0, Citus adds support for running several schema-sharding DDLs from any node, including CREATE SCHEMA, DROP SCHEMA, ALTER SCHEMA RENAME, ALTER SCHEMA OWNER, and table-level DDL on distributed schemas.

CREATE SCHEMA tenant_42;
SELECT citus_schema_distribute('tenant_42');

CREATE TABLE tenant_42.orders (
  id bigserial PRIMARY KEY,
  amount numeric,
  created_at timestamptz DEFAULT now()
);

Use row-based distribution for shared tables and schema-based sharding for per-tenant schema layouts; do not mix the two models casually without checking colocation and SQL-support implications.

Node and Shard Operations

-- Add or disable nodes.
SELECT * FROM citus_add_node('worker-3', 5432);
SELECT * FROM citus_disable_node('worker-2', 5432);
SELECT * FROM citus_activate_node('worker-2', 5432);

-- Drain and remove a node.
SELECT * FROM citus_drain_node('worker-1', 5432);
SELECT * FROM citus_remove_node('worker-1', 5432);

-- Rebalance shards.
SELECT citus_rebalance_start();
SELECT * FROM citus_rebalance_status();
SELECT rebalance_table_shards('events');

-- Inspect tables and shards.
SELECT * FROM citus_tables;
SELECT * FROM citus_shards;

Backup Coordination

Citus v14.1.0 adds UDFs for blocking distributed 2PC commit decisions and schema/topology changes while taking coordinated disk snapshots. Use them only inside a controlled backup workflow, and always unblock the cluster after the snapshot step.

SELECT citus_cluster_changes_block();
SELECT * FROM citus_cluster_changes_block_status();

-- Take coordinated filesystem or volume snapshots here.

SELECT citus_cluster_changes_unblock();

Pair these functions with regular PostgreSQL backup discipline: consistent checkpoints, WAL archiving, snapshot ordering across nodes, and a tested restore procedure.

Caveats

  • Pigsty local metadata currently tracks Citus 14.x for PostgreSQL 16-18; Citus 14 dropped PostgreSQL 15 support.
  • shared_preload_libraries = 'citus' must be set before extension creation. A plain CREATE EXTENSION citus is not enough on a fresh server.
  • Choose the distribution column carefully. Primary keys and unique constraints on distributed tables generally need to include the distribution column.
  • Cross-shard joins, repartition joins, distributed DDL, and multi-shard writes are powerful but have different planning and locking behavior from single-node PostgreSQL.
  • Citus includes its own columnar storage surface through citus_columnar; Pigsty metadata marks it as conflicting with Hydra columnar.
  • The cluster-change blocking functions are operational tools for backups. Do not leave a cluster blocked after a failed backup script.

Last Modified 2026-07-02: extension update 2026-07-02 (f9f0d13)