The schedule is out 🗓️ for POSETTE: An Event for Postgres 2026!
The schedule is out 🗓️ for POSETTE: An Event for Postgres 2026!
Welcome to the combined release notes for Citus 14.1 and Citus 13.3. These are two paired minor releases that ship the same set of features—14.1 on the 14.x line (PostgreSQL 16, 17, and 18) and 13.3 on the 13.x line (PostgreSQL 14, 15, 16, and 17).
Starting with this release, Citus is moving to a PostgreSQL-style Major.Minor cadence. Minor releases now include non-breaking, backwards-compatible features in addition to bug fixes and security updates. Every supported major version (beginning with 13.x) gets a parallel minor release carrying the same content, so you don’t have to jump majors to pick up a new feature. Citus 14.1 and 13.3 are the first example of this new model.
As a practical consequence: to get the latest features for the major version you’re on, always run the latest minor of that major.
This page covers everything that’s new in both versions:
citus_cluster_changes_block, _unblock, _block_status) that pauses distributed transactions and topology changes so disk-snapshot backups across coordinator and workers can be taken consistently.GRANTED BY, plus a fix for a self-deadlock involving long named constraints on partitioned tables.Schema-based sharding (introduced in Citus 12) lets you isolate tenants by giving each tenant its own schema and distributing that schema across the cluster. Until now, the DDL that defines and evolves those schemas had to be run on the coordinator. Citus 14.1 / 13.3 closes that gap: schema-level and table-level DDLs for distributed-schema objects are now propagated from any node in the cluster (coordinator or worker), exactly like Citus already does for plain distributed tables.
What this covers:
CREATE SCHEMA, DROP SCHEMA, ALTER SCHEMA … RENAME TO …, and ALTER SCHEMA … OWNER TO … on distributed schemas.CREATE TABLE, ALTER TABLE, DROP TABLE, plus CREATE INDEX / ALTER INDEX / DROP INDEX, CREATE TRIGGER, and CREATE VIEW / materialized views.DROP TABLE on a distributed-schema table from any worker now correctly cleans up metadata cluster-wide.Why it matters: tenant-onboarding and tenant-maintenance workflows that run against a worker (for example, an application server connected to a worker via Citus' MX mode) no longer have to be rerouted to the coordinator just to issue a CREATE SCHEMA or ALTER TABLE against a distributed-schema table.
Quick example, run on any node:
-- Create and distribute a tenant schema from any node
CREATE SCHEMA tenant_42;
SELECT citus_schema_distribute('tenant_42');
-- Define a table inside the distributed schema from any node
CREATE TABLE tenant_42.orders (
id bigserial PRIMARY KEY,
customer_id bigint NOT NULL,
total_cents bigint NOT NULL,
created_at timestamptz DEFAULT now()
);
-- Evolve it from any node
ALTER TABLE tenant_42.orders ADD COLUMN status text NOT NULL DEFAULT 'new';
CREATE INDEX ON tenant_42.orders (customer_id);
-- And drop it from any node
DROP TABLE tenant_42.orders;
Tracked as Citus issue #8541.
Disk-snapshot backups of a Citus cluster have always had a coordination problem: the coordinator and each worker run on independent storage, but a Citus transaction commits via 2PC across them. If you snapshot the nodes at slightly different points in time, you can end up with a backup where a 2PC transaction is committed on some nodes and prepared-but-not-committed on others—an inconsistent restore.
Citus 14.1 / 13.3 introduces a small UDF family that lets your backup tooling tell the cluster “hold all multi-node state changes for a moment” while it takes snapshots, then release:
| Function | Purpose |
|---|---|
citus_cluster_changes_block() | Block new distributed (2PC) commits and topology / schema changes cluster-wide. Existing in-flight 2PC commits are allowed to finish so the cluster lands in a quiescent state. Returns once the cluster is blocked. |
citus_cluster_changes_unblock() | Release the block and resume normal operation. Always run after the snapshot completes (including on failure paths). |
citus_cluster_changes_block_status() | Inspect whether the cluster is currently in the blocked state, who initiated it, and when. Useful for monitoring and for safety checks in backup scripts. |
While the block is in effect, reads and single-shard writes continue to run—the block only pauses distributed transactions that would commit across multiple nodes and operations that change cluster metadata (node add/remove, shard moves, distributed DDL). New multi-node writes wait for citus_cluster_changes_unblock() to be called.
Minimal usage pattern from a backup script:
-- 1. Quiesce distributed commits and topology changes
SELECT citus_cluster_changes_block();
-- 2. (Outside SQL) take coordinated disk snapshots of every node
-- 3. Release
SELECT citus_cluster_changes_unblock();
For the full reference—arguments, return values, the underlying state machine, and timeout / safety semantics—see the Citus UDF reference in the Citus documentation.
Tracked as Citus issues #8543 and #8571.
GRANT … GRANTED BY is now propagated correctly to workers. Previously, when a role grant was issued with an explicit GRANTED BY grantor, Citus could fail to replay that grantor on the worker nodes, leaving the worker-side pg_auth_members rows inconsistent with the coordinator. Fixed in #8466.
No more self-deadlock from long named constraints on partitioned tables. When a CONSTRAINT name on a partitioned table would, after Citus’ internal name mangling, exceed PostgreSQL’s NAMEDATALEN limit, Citus could deadlock against itself trying to acquire locks on the truncated and untruncated forms of the same object. The truncation rule has been tightened so it stays within NAMEDATALEN and the redundant locking path is removed. Fixed in #8540 and #8560.