Citus
A Postgres extension that distributes tables across a cluster for horizontal scale-out.
What it is
Citus is a Postgres extension that turns a Postgres cluster into a distributed
database. You install it with CREATE EXTENSION citus; on a coordinator node,
register worker nodes, and then run SELECT create_distributed_table(...) to
shard a table across the cluster. Queries against distributed tables fan out to
the workers in parallel.
Citus Data was acquired by Microsoft in 2019. The extension stayed open source (AGPLv3) and Microsoft offers a managed version as Azure Cosmos DB for PostgreSQL (formerly “Hyperscale (Citus)”).
Why people use it
- Horizontal write scale-out. Single-node Postgres maxes out somewhere between 50K and 200K writes/sec depending on hardware. Citus shards by a tenant or hash key and lets you add nodes to scale writes roughly linearly.
- Multi-tenant SaaS. Sharding by
tenant_idkeeps each tenant’s data colocated on one node. Most queries hit a single shard, so latency stays low. - Real-time analytics. Distributed JOINs and aggregations run in parallel across workers. Citus is positioned as the answer to “I want a data warehouse, but my data is already in Postgres.”
- Postgres-native. Same SQL, same wire protocol, same client libraries. Apps that already speak Postgres don’t need to be rewritten.
When to use Citus
- Multi-tenant SaaS that outgrew a single-node Postgres.
- High-throughput write workloads (>50K writes/sec sustained) where you don’t want to leave Postgres.
- Real-time analytics on Postgres data where you want SQL parallelism without going to a separate warehouse.
- You’re already on Azure and want a managed version.
When not to use Citus
- Single-node Postgres is enough. Most applications never outgrow a properly tuned single node. If you’re under 10K writes/sec sustained, vanilla Postgres is simpler and cheaper.
- You need full cross-shard distributed transactions. Citus supports two-phase commit, but at a meaningful latency cost. If most of your writes touch multiple shards, you’re fighting the architecture.
- You need a geo-distributed database. Citus is a single-region distributed system. CockroachDB, YugabyteDB, or Spanner handle geo-distribution.
- Your workload doesn’t shard cleanly. If you can’t pick a good distribution column, Citus won’t save you — you’ll get a lot of cross-shard joins, which are slow.
Notable trade-offs
- AGPL license. This affects any organization that doesn’t want copyleft contamination. For self-hosting inside a closed-source product, you must comply with AGPL terms. The managed Azure offering avoids this for users.
- Distribution column is a one-way decision. Picking the wrong key means a
lot of cross-shard work later. Multi-tenant SaaS usually picks
tenant_id. - Coordinator is a bottleneck and SPOF. Connections, query planning, and certain operations route through the coordinator. Citus 11+ added query-from-any-node, which helps but doesn’t eliminate the coordinator’s special role.
- Microsoft owns the roadmap. Open source, but Microsoft sets priorities. Features that don’t align with the Azure managed offering have been deprioritized in the past.
Managed offering
Azure Cosmos DB for PostgreSQL is the only fully managed Citus. AWS RDS and Google Cloud SQL do not support it. Self-hosting on Kubernetes via the Citus Operator is feasible but operationally non-trivial.