If an Amazon RDS for PostgreSQL architecture depends on running CREATE EXTENSION citus, stop before estimating nodes, shards, or throughput. Citus is not in the current RDS extension matrix, and an RDS administrator cannot install the missing native package.

Situation

RetailCo’s order platform began on one PostgreSQL database. Years later, its transaction history is 40 TB, checkout writes compete with operational queries, and the largest RDS instance no longer provides comfortable peak headroom.

Most orders are tenant-local. An order, its items, payment state, and shipment belong to one tenant_id. That makes Citus attractive: distribute tenant rows across workers, colocate related tables, and let several PostgreSQL servers own different writes.

The platform team also has a firm managed-service requirement. Its first proposed architecture tries to combine both preferences:

flowchart TD
  App[RetailCo applications] --> Coordinator[RDS PostgreSQL coordinator]
  Coordinator --> WorkerA[RDS PostgreSQL worker A]
  Coordinator --> WorkerB[RDS PostgreSQL worker B]
  Coordinator --> WorkerC[RDS PostgreSQL worker C]
  Extension[Citus extension] --> Coordinator
  Extension --> WorkerA
  Extension --> WorkerB
  Extension --> WorkerC

The diagram looks plausible. Each node is PostgreSQL. RDS supports PostgreSQL extensions. The database owner receives an rds_superuser role. AWS even supports extensions such as pg_partman, pglogical, and postgres_fdw on applicable engine versions.

But the proposed architecture fails at its first prerequisite.

As of this article’s March 31, 2026 documentation cutoff, AWS’s RDS for PostgreSQL extension matrix does not list Citus. AWS instructs customers to use SHOW rds.extensions to see the extensions supported by a specific engine version. If an extension is not supplied for that engine, granting another database role does not make its files appear on the server.

The Problem

The misunderstanding begins with the word extension. PostgreSQL extensions do not all have the same deployment requirements.

Some are primarily SQL objects. Others include compiled code, server hooks, background processes, control files, and shared libraries. PostgreSQL’s own extension packaging documentation explains that CREATE EXTENSION loads objects from files already installed on the database server; extensions containing C code typically include a shared library.

Citus is in the second category. Its installation procedure installs an operating-system package and configures shared_preload_libraries = 'citus' before creating the extension. Citus then hooks into PostgreSQL’s planner and executor to coordinate distributed work: Citus 13 installation and Citus concepts.

The dependency chain is therefore:

flowchart TD
  Package[Citus operating-system package] --> Files[control files and shared library]
  Files --> Preload[Citus loaded at server start]
  Preload --> Create[CREATE EXTENSION citus]
  Create --> Metadata[distributed-table metadata]
  Metadata --> Workers[coordinator routes work to workers]

RDS controls the host operating system and the PostgreSQL installation. The customer cannot add the Citus package or place its control and library files into PostgreSQL’s installation directories.

AWS is explicit about the role boundary. The initial postgres account on RDS has NOSUPERUSER and NOREPLICATION; members of rds_superuser can install extensions supported by RDS, but cannot access the host operating system or connect as PostgreSQL’s actual superuser: Understanding the rds_superuser role.

That leads to the core question:

If standard RDS cannot supply the Citus runtime, which architecture solves RetailCo’s real problem without pretending a different extension is a distributed database?

The Answer Is an Architecture Choice, Not an Extension Workaround

There is no supported SQL command, privilege grant, parameter-group setting, or trusted-extension shortcut that turns a standard RDS for PostgreSQL instance into a Citus coordinator or worker.

The preflight check should happen before any design review:

SHOW rds.extensions;

SELECT
    name,
    default_version,
    installed_version
FROM pg_available_extensions
WHERE name IN (
    'citus',
    'pg_partman',
    'pglogical',
    'postgres_fdw'
)
ORDER BY name;

Run this on the exact RDS PostgreSQL engine and minor version under evaluation. Do not copy expected output from another version, and do not infer availability from generic PostgreSQL documentation.

The RDS parameter rds.allowed_extensions = '*' is easy to misread. AWS documents it as allowing all extensions available for the RDS engine version. It does not allow arbitrary packages from the PostgreSQL ecosystem: Restricting installation of PostgreSQL extensions.

Why pg_partman does not replace Citus

pg_partman is supported on RDS for PostgreSQL 12.5 and later. It automates the creation, retention, and maintenance of native PostgreSQL table partitions: Managing PostgreSQL partitions with pg_partman.

That can be extremely useful for a 40-TB transaction table. RetailCo could partition by month so retention, index maintenance, archival, and time-bounded queries operate on smaller physical tables.

flowchart TD
  App[application writes] --> Writer[one RDS PostgreSQL writer]
  Writer --> Parent[transactions parent table]
  Parent --> P1[January partition]
  Parent --> P2[February partition]
  Parent --> P3[March partition]
  Parent --> P4[future partitions managed by pg_partman]

Every partition still uses the same RDS DB instance’s compute, memory, WAL path, and writer. Partitioning can improve pruning and data lifecycle operations. It can reduce particular maintenance and query costs. It does not create independent PostgreSQL workers that concurrently own different tenants.

The distinction is structural:

CapabilityNative partitioning with pg_partmanCitus distributed tables
Splits one logical tableYesYes
Automates partition lifecycleYesNot its primary role
Places data on independent PostgreSQL workersNoYes
Routes by distribution column across workersNoYes
Adds independent write computeNoYes, when work is distributed and sufficiently local
Requires Citus on coordinator and workersNoYes

pg_partman is a partition-management answer. Citus is a distributed-data and distributed-compute answer. Using one name in place of the other hides the original write ceiling.

Why postgres_fdw does not recreate Citus

postgres_fdw lets PostgreSQL access tables stored on remote PostgreSQL servers. It can support federation, migrations, administrative access, and deliberately designed remote-table workflows: PostgreSQL postgres_fdw.

It does not provide Citus’s distribution metadata, shard placement model, distributed-table DDL, colocation decisions, or rebalance operations. Building application-visible foreign tables across many RDS instances transfers routing, transaction design, topology changes, and failure handling to the architects and operators. That may be a valid custom federation design, but it should not be represented as “Citus on RDS.”

Why pglogical does not add write owners

RDS supports pglogical on applicable versions, as shown in the current extension matrix. Logical replication copies selected changes between PostgreSQL systems. Replication can support migrations, data integration, and some availability patterns; it does not automatically divide authoritative ownership of a table’s write keyspace.

If two writable databases accept conflicting updates for the same logical row, the architecture now needs ownership rules, conflict behavior, sequence and identity strategy, DDL coordination, and recovery reconciliation. Installing a replication extension does not answer those questions.

Four Valid Paths for RetailCo

Once the invalid RDS-plus-Citus premise is removed, the decision becomes much clearer.

Path 1 — Stay on one RDS database and use native partitioning

Choose this when RetailCo’s main problem is table manageability, retention, vacuum scope, index maintenance, or query pruning—and when one writer still has sufficient measured headroom.

This is the lowest-migration-risk path. It preserves standard RDS operations and PostgreSQL semantics. It should not be approved as a horizontal-write solution unless the benchmark proves the original resource ceiling was caused by work that partitioning actually removes.

Path 2 — Application-shard across multiple RDS databases

If the managed-service requirement is firm and tenant_id is a stable ownership key, RetailCo can place tenant groups on independent RDS PostgreSQL databases:

flowchart TD
  Request[request with tenant identifier] --> Catalog[tenant placement catalog]
  Catalog --> RdsA[RDS shard A — tenants one]
  Catalog --> RdsB[RDS shard B — tenants two]
  Catalog --> RdsC[RDS shard C — tenants three]
  RdsA --> Pipeline[change-data pipeline]
  RdsB --> Pipeline
  RdsC --> Pipeline
  Pipeline --> Analytics[cross-tenant reporting]

This creates real independent write capacity because each database owns different tenants. When every shard is configured with the required backup and Multi-AZ policies, RDS manages the database hosts, storage, backups, and instance failover inside each shard.

RetailCo must own the distributed control plane:

  • authoritative tenant placement and request routing;
  • tenant movement, validation, cutover, and rollback;
  • schema rollout across every database;
  • hot-tenant isolation and capacity forecasting;
  • fleet-wide PITR and disaster-recovery procedures;
  • cross-shard reporting and any exceptional cross-shard transaction.

This is not Citus, but it is an honest managed PostgreSQL sharding architecture.

Path 3 — Run Citus on infrastructure RetailCo controls

If Citus behavior is the requirement, the PostgreSQL hosts must permit Citus packages and configuration. On AWS, that usually means EC2 instances or another supported Citus platform rather than standard RDS for PostgreSQL.

flowchart TD
  App[RetailCo applications] --> Pool[connection pool]
  Pool --> Coordinator[Citus coordinator on EC2]
  Coordinator --> WorkerA[worker A on EC2]
  Coordinator --> WorkerB[worker B on EC2]
  Coordinator --> WorkerC[worker C on EC2]
  Orders[orders distributed by tenant identifier] --> WorkerA
  Orders --> WorkerB
  Orders --> WorkerC
  Reference[small reference tables] --> WorkerA
  Reference --> WorkerB
  Reference --> WorkerC

Citus uses a coordinator to hold distributed metadata and plan work across workers. Distributed tables are divided into shards according to a distribution column; reference tables are copied across workers; related tables can be colocated so equal distribution-key values reach the same worker: Citus concepts and create_distributed_table.

For RetailCo, tenant_id is a stronger candidate than four-value brand_id. A high-cardinality tenant key spreads ownership more evenly and makes checkout transactions local when every related table carries that key. The decision still requires measurements for tenant skew, cross-tenant queries, global constraints, and large tenants.

The operational exchange is substantial. RetailCo now owns operating-system patching, PostgreSQL and Citus upgrades, coordinator availability, worker replication, backups, point-in-time recovery, node replacement, shard movement, monitoring, and failure testing. Citus documentation describes worker high availability using PostgreSQL streaming replication and notes that the coordinator contains essential metadata: Citus cluster management.

Path 3b — If managed Citus is the actual requirement, the offering is not on AWS

The question in this article’s title has a narrow answer for RDS, but architects should know the complete one. Managed Citus does exist: Microsoft acquired Citus Data and operates the extension as a first-party service, currently branded Azure Cosmos DB for PostgreSQL. It provides coordinator and worker nodes, create_distributed_table(), colocation, reference tables, and the rebalancer as a managed control plane rather than as packages RetailCo installs on EC2.

That reframes the decision honestly. “We want Citus without operating Citus” is not an impossible requirement — it is a requirement that selects a different cloud. For RetailCo, whose constraint is a firm AWS-managed-service preference, the relevant conclusion is that the managed-Citus option and the AWS option are mutually exclusive, and the team must decide which of the two preferences is actually binding: the extension, or the provider.

Two clarifications prevent the common follow-up mistakes:

  • Aurora PostgreSQL does not change the answer. Aurora is a different storage architecture, not a more permissive extension host. Citus is absent from its supported extension list for the same reason it is absent from RDS: AWS does not ship the server-side package. “Try Aurora instead” is not a workaround.
  • Aurora Limitless is not managed Citus. It solves an adjacent problem with a different implementation, table model, and compatibility surface, as the next path describes. Shared vocabulary — shards, distribution keys, colocation — does not imply a portable design.

Path 4 — Evaluate an AWS-managed distributed PostgreSQL architecture

Aurora PostgreSQL Limitless Database provides database-managed routers and shards, but it is not “Citus delivered through RDS.” It has its own table types, shard-key rules, PostgreSQL compatibility boundaries, version track, backup model, and unsupported integrations.

For RetailCo’s tenant-local workload, it is the primary AWS-managed proof-of-concept candidate. The compatibility inventory and design tradeoffs are covered in Scaling Writes in Amazon Aurora: What Actually Works?.

If neither Citus nor Limitless fits, domain decomposition remains a valid fifth direction: separate orders, payments, inventory, and history when their transaction and recovery contracts do not need one database commit.

In Practice

Context: AWS publishes an extension matrix per RDS PostgreSQL engine version and tells administrators to inspect rds.extensions. Citus is absent from the current matrix, while pg_partman, pglogical, and postgres_fdw are listed for applicable versions.

Action: Make extension availability a deployment gate. Run SHOW rds.extensions and query pg_available_extensions on the exact target version before approving any extension-dependent architecture.

Result: The design either proceeds with a supported prerequisite or fails before migration code, performance projections, and operating procedures are built on an impossible topology.

Learning: An extension name on the public internet is not evidence that a managed PostgreSQL service has installed its server-side files.

Context: AWS documents that rds_superuser is not PostgreSQL superuser and has no host operating-system access. PostgreSQL documents that native extensions require server-installed control, script, and often shared-library files.

Action: Classify every required extension by installation mechanism: SQL-only or native package, preload requirement, background workers, engine-version compatibility, and upgrade coupling.

Result: The compatibility review exposes which capabilities depend on the managed provider’s build rather than on a database grant.

Learning: Privilege and software availability are different controls.

Context: AWS describes pg_partman as automation for PostgreSQL’s native child partitions. Citus describes workers that store distributed shards and a coordinator that routes or parallelizes queries.

Action: State the resource boundary for every proposed “partitioning” solution: one writer with many child tables, or multiple workers with separate compute and ownership.

Result: The architecture review can determine whether the proposal improves lifecycle management or actually distributes write work.

Learning: Partition count is not a write-scalability metric.

Proposed verification lab — no empirical result yet

This article makes no throughput claim. A useful lab should compare the architectures using the same RetailCo schema, data distribution, durability, and transaction semantics.

TestOne partitioned RDS databaseApplication-sharded RDSCitus on EC2
Tenant-local checkoutOne writer, route to native partitionRoute tenant to owning databaseRoute tenant to owning shard placement
Hot tenantObserve local lock and CPU concentrationIsolate or move tenantObserve worker and shard skew
Cross-tenant reportScan relevant local partitionsFan out or use analytics pipelineDistributed query through coordinator
Cross-tenant transactionLocal database transactionApplication coordination requiredDistributed transaction path
Add write capacityScale writer verticallyAdd database and move tenantsAdd worker and rebalance shards
RecoveryRDS snapshot and PITRRestore one shard and reconcile catalogRestore coordinator metadata and worker state consistently

Record TPS, P50, P95, P99, aborts, retries, lock waits, WAL generation, CPU, storage latency, network traffic, connection count, tenant skew, rebalance time, and recovery time. Mark every result with the exact PostgreSQL, extension, instance, storage, and configuration versions.

For the 40-TB table, do not begin by copying all data. Start with a representative but explicitly labeled dataset, validate query and transaction locality, then test a staged migration with change capture, per-tenant reconciliation, cutover, and rollback. A proposed test is not a measured result.

Where It Breaks

ArchitectureGood fitWhere it breaksComplexity owner
RDS with native partitioningOne writer still fits; lifecycle and pruning are the main problemsWriter CPU, WAL, locks, and storage path remain sharedAWS plus database team
Application-sharded RDSStable tenant key and strong managed-service requirementRouting drift, hot tenants, fleet schema changes, cross-shard workApplication and platform teams
Citus on EC2Need Citus semantics and operational controlCoordinator and worker HA, upgrades, backups, rebalance, operational staffingDatabase and infrastructure teams
Aurora PostgreSQL LimitlessAWS-managed horizontal writes and compatible tenant-local schemaUnsupported PostgreSQL features or integrations, poor shard key, distributed transactionsAWS plus database architecture team
Domain decompositionClear business ownership and different recovery contractsEvent delivery, reconciliation, partial workflows, duplicated dataApplication and platform teams

Several warning signs should stop the design review:

  1. “We have rds_superuser, so we can install it.” The role cannot install a native package that AWS has not supplied.
  2. rds.allowed_extensions is *, so all extensions are allowed.” The wildcard covers extensions available for that RDS engine version.
  3. pg_partman distributes our partitions.” It manages native partitions inside the same PostgreSQL database and writer boundary.
  4. postgres_fdw gives us transparent sharding.” It provides remote-table access; the architecture still owns placement, routing, transactions, and failure semantics.
  5. “Logical replication gives every node write capacity.” Replication does not define conflict-free ownership of the same rows.
  6. “Citus will scale any workload linearly.” Cross-shard joins, multi-shard transactions, hot tenants, coordinator work, network, storage, and rebalance behavior must be measured.

The migration boundary is equally important. A live 40-TB table is not moved safely through one maintenance-window command. Regardless of target, RetailCo needs an inventory of tables and dependencies, a shard-key and transaction-locality analysis, a staged copy, ongoing change capture, reconciliation, controlled routing changes, and a rollback path.

What to Do Next

For RetailCo, do not pursue Citus on standard Amazon RDS for PostgreSQL. The prerequisite is unsupported, and pg_partman, pglogical, postgres_fdw, or extra privileges do not recreate Citus.

Because RetailCo prefers AWS-managed operations and its checkout path is predominantly tenant-local, the recommended order is:

  1. Verify that the current ceiling is write compute, WAL, lock contention, or storage latency—not avoidable reads or poor SQL.
  2. Use native partitioning and pg_partman for the 40-TB table’s lifecycle and pruning needs, but do not claim that work adds independent writers.
  3. Build an Aurora PostgreSQL Limitless compatibility proof of concept using the exact supported engine patch and tenant_id as the candidate shard key.
  4. Keep application-sharded RDS databases as the managed-PostgreSQL fallback when Limitless compatibility fails.
  5. Choose Citus on EC2 only when Citus-specific behavior is worth owning the full coordinator, worker, HA, backup, upgrade, and rebalance lifecycle.
  6. Move cross-tenant reporting away from the checkout commit path regardless of the selected OLTP architecture.
  7. Publish no scaling claim until tenant-local, hot-tenant, cross-shard, capacity-addition, and recovery tests have measured results.

Good fit: application-sharded RDS or Aurora Limitless when tenant_id is stable, high-cardinality, and present in most transactions; Citus on EC2 when operational control and Citus semantics are explicit requirements.

Poor fit: any design labeled “Citus on standard RDS PostgreSQL,” or any sharding proposal whose critical transactions do not carry a stable ownership key.

Main advantage of the recommendation: it preserves the managed-service preference without building on an unavailable extension.

Main limitation: managed horizontal write scale still requires schema, routing, transaction, migration, and recovery redesign; AWS does not remove those architectural decisions.

Operational complexity: medium for application-sharded RDS or Limitless; high for self-managed Citus.

Migration complexity: high for a live 40-TB system. Execute by tenant or another verifiable ownership slice, not as an undifferentiated table copy.

  • Problem: RetailCo needs more write ownership domains, but the proposed Citus runtime is not available on standard RDS for PostgreSQL.
  • Solution: separate table-management needs from distributed-compute needs, then choose native RDS partitioning, application-sharded RDS, Aurora Limitless, or self-managed Citus according to the actual boundary.
  • Proof: AWS’s current extension matrix omits Citus and its role documentation denies host access; Citus’s own installation and architecture documentation requires server packages, preload configuration, a coordinator, and workers.
  • Action: run the extension preflight and transaction-locality review before the next architecture meeting. If either the required runtime or a stable ownership key is missing, reject that option before benchmarking it.