PostgreSQL 18 Sharding Survival Guide [2026 Cheat Sheet]
Bottom Line
PostgreSQL 18 does distributed SQL natively only by composing declarative partitioning with postgres_fdw. That stack is viable when your shard key prunes aggressively, but it is not a built-in shard manager with automatic rebalancing or cross-shard two-phase commit.
Key Takeaways
- ›As of May 20, 2026, PostgreSQL 18.4 is the latest PostgreSQL 18 minor release.
- ›PostgreSQL 18 has no built-in shard manager; native-style sharding is partitioning plus postgres_fdw.
- ›Critical postgresfdw defaults are conservative: fetchsize 100, batchsize 1, asynccapable false.
- ›postgres_fdw still lacks ON CONFLICT DO UPDATE support and remote two-phase commit.
- ›Keep enablepartitionpruning on, or distributed fan-out gets expensive fast.
As of May 20, 2026, PostgreSQL 18.4 is the latest minor in the PostgreSQL 18 line. What it still does not ship is a cluster-wide shard manager. The native playbook is declarative partitioning plus foreign tables via postgres_fdw, which gives you distributed reads and writes with real tradeoffs around planning, transactions, and constraint safety. This reference compresses the commands, defaults, and failure modes you actually need.
- PostgreSQL 18.4 is the current PostgreSQL 18 minor release.
- Native sharding is still a composition of partitioning and postgres_fdw, not a single turnkey feature.
- enablepartitionpruning must stay enabled or coordinator queries fan out unnecessarily.
- postgres_fdw still does not support ON CONFLICT DO UPDATE on foreign tables.
- Remote transactions still cannot be prepared for two-phase commit.
What PostgreSQL 18 Actually Ships
Bottom Line
Use partitioned tables as the routing surface and postgres_fdw foreign partitions as the remote storage edge. That is the native distributed pattern in PostgreSQL 18, and it works only if your queries prune hard on the shard key.
What is native in PostgreSQL 18
- Declarative partitioning lets a parent table route rows to partitions with PARTITION BY.
- Partitions can be normal local tables or foreign tables, which is the core trick behind native-style sharding.
- postgres_fdw can push remote filters, fetch only needed columns, and run asynchronous scans across foreign tables when configured.
- IMPORT FOREIGN SCHEMA, CREATE SERVER, and CREATE USER MAPPING cover the metadata plumbing.
What is still missing
- No built-in cluster control plane for automatic shard placement, balancing, or resharding.
- No support in postgres_fdw for INSERT ... ON CONFLICT DO UPDATE on foreign tables.
- No support for preparing remote transactions for two-phase commit.
- No guarantee that constraints declared on foreign partitions are enforced locally; PostgreSQL assumes they are true for optimization.
Primary references: release notes, partitioning docs, postgres_fdw docs, and CREATE FOREIGN TABLE.
Command Finder and Setup
Use the filter to narrow the cheat sheet by task, object name, or option. The page shortcuts below let you jump through blocks without touching the mouse.
Try scram, fetch_size, partition, or disconnect.
Bootstrap the coordinator
CREATE EXTENSION IF NOT EXISTS postgres_fdw;
CREATE SERVER shard_east
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '10.0.0.21', port '5432', dbname 'app');
CREATE USER MAPPING FOR CURRENT_USER
SERVER shard_east
OPTIONS (user 'app_user', password 'replace_me');Model shards as partitions
CREATE TABLE orders (
tenant_id bigint NOT NULL,
region text NOT NULL,
order_id bigint NOT NULL,
created_at timestamptz NOT NULL,
total_cents bigint NOT NULL
) PARTITION BY LIST (region);
CREATE FOREIGN TABLE orders_us_east
PARTITION OF orders FOR VALUES IN ('us-east')
SERVER shard_east
OPTIONS (schema_name 'public', table_name 'orders');- Use the parent table as the stable application surface.
- Choose a shard key that appears in nearly every hot query predicate.
- Avoid parent UNIQUE indexes if you plan to create foreign-table partitions directly.
Import remote definitions fast
CREATE SCHEMA IF NOT EXISTS fdw_stage;
IMPORT FOREIGN SCHEMA public
LIMIT TO (orders, order_items)
FROM SERVER shard_east
INTO fdw_stage;- IMPORT FOREIGN SCHEMA skips partitions unless you explicitly name them with LIMIT TO.
- Prefer importing first when local and remote column definitions must stay aligned.
Run a distributed query and inspect the plan
EXPLAIN (VERBOSE, COSTS ON)
SELECT region, count(*), sum(total_cents)
FROM orders
WHERE region IN ('us-east', 'us-west')
AND created_at >= now() - interval '7 days'
GROUP BY region;- If pruning works, the coordinator should touch only the matching partitions.
- If remote pushdown works, filters and aggregates move closer to the shard.
Refresh foreign-table stats
ANALYZE orders_us_east;
ALTER FOREIGN TABLE orders_us_east
OPTIONS (ADD analyze_sampling 'auto');- ANALYZE updates local stats for remote tables.
- analyze_sampling supports off, random, system, bernoulli, and auto.
Inspect and clean up FDW connections
SELECT * FROM postgres_fdw_get_connections(true);
SELECT postgres_fdw_disconnect('shard_east');
SELECT postgres_fdw_disconnect_all();- keep_connections is on by default, so idle sessions can pin remote connections longer than expected.
- Use the connection functions during debugging and after topology changes.
Keyboard Shortcuts
| Shortcut | Action | When to use it |
|---|---|---|
/ | Focus the live search box | Jump straight to a command by keyword |
Esc | Clear the filter | Return to the full cheat sheet |
j | Next visible command block | Step through matching results |
k | Previous visible command block | Move back through results |
c | Copy the active code block | Grab the current snippet fast |
Why this matters on a sharding runbook
- Operational docs fail when they are slow to scan under pressure.
- Shortcuts turn this page into a usable incident aid instead of a passive blog post.
- Every pre block also gets a copy button on render for point-and-shoot execution.
Configuration That Matters
Keep these defaults in your head
- fetch_size default: 100.
- batch_size default: 1.
- async_capable default: false.
- useremoteestimate default: false.
- fdwstartupcost default: 100.
- fdwtuplecost default: 0.2.
- keep_connections default: on.
- parallel_commit and parallel_abort default: false.
Set options where they pay off
ALTER SERVER shard_east OPTIONS (ADD use_remote_estimate 'true');
ALTER SERVER shard_east OPTIONS (ADD parallel_commit 'true');
ALTER SERVER shard_east OPTIONS (ADD parallel_abort 'true');
ALTER SERVER shard_east OPTIONS (ADD keep_connections 'on');
ALTER SERVER shard_east OPTIONS (ADD use_scram_passthrough 'true');
ALTER FOREIGN TABLE orders_us_east OPTIONS (ADD fetch_size '1000');
ALTER FOREIGN TABLE orders_us_east OPTIONS (ADD batch_size '500');
ALTER FOREIGN TABLE orders_us_east OPTIONS (ADD async_capable 'true');- Turn on useremoteestimate when remote cardinality errors hurt join order decisions more than an extra remote EXPLAIN.
- Raise fetch_size for scan-heavy analytics, but test memory and latency tradeoffs.
- Raise batch_size for bulk inserts and COPY into foreign tables.
- Enable async_capable only when concurrent foreign scans actually reduce wall-clock time.
- Use usescrampassthrough to avoid storing plain-text passwords in system catalogs, but remember every participating host must share identical SCRAM secrets for the same user.
Do not forget local pruning
SHOW enable_partition_pruning;- If enablepartitionpruning is off, PostgreSQL will not optimize partition access as intended.
- Pruning is the difference between a shard-aware query and a coordinator-wide broadcast.
Advanced Usage and Failure Modes
Remote execution and pushdown
ALTER SERVER shard_east OPTIONS (ADD extensions 'pgcrypto');- postgres_fdw ships built-in immutable operators and functions by default.
- Use the extensions option only when the same extension version and semantics exist on both sides.
- Mismatched extension behavior can make remote execution wrong, not just slow.
Transaction behavior to remember
- Remote transactions follow the local transaction, but they are not prepared for two-phase commit.
- When the local transaction is SERIALIZABLE, the remote one is SERIALIZABLE; otherwise the remote side uses REPEATABLE READ.
- That means even a local READ COMMITTED workflow can observe snapshot-stable remote reads inside the transaction.
Foreign partition correctness
- Constraints on foreign tables are assumed for optimization, not enforced by the core server.
- If a foreign partition contains rows outside its declared bound, query results can be wrong.
- Install matching constraints on the remote shard itself, not just on the coordinator metadata.
- It is possible to move a row from a local partition to a foreign-table partition when the FDW supports tuple routing, but not from one foreign-table partition to another.
Lock-aware partition maintenance
- Prebuild and then ATTACH PARTITION when possible to reduce lock intensity on the parent.
- DETACH PARTITION ... CONCURRENTLY is useful when retiring partitions with less disruption.
- Prefer scripted partition creation and retirement; manual shard DDL is a predictable source of outages.
Deployment Checklist
- Pick a shard key that appears in every latency-sensitive query.
- Keep coordinator tables partitioned on the same key you use for remote placement.
- Verify pruning with EXPLAIN before calling a query distributed-safe.
- Run ANALYZE on foreign tables after major remote data changes.
- Benchmark fetch_size, batch_size, and useremoteestimate with your real network latency.
- Avoid workflows that require atomic cross-shard commit until you have an application-level compensation design.
- Use SCRAM consistently if you enable usescrampassthrough.
- Track remote schema drift aggressively; foreign tables with mismatched types create subtle bugs.
Frequently Asked Questions
Does PostgreSQL 18 have native sharding now? +
postgres_fdw. That gives you distributed reads and writes, but not automatic resharding, balancing, or a shard control plane.How do I run distributed queries in PostgreSQL 18 without Citus? +
EXPLAIN that partition pruning and remote pushdown are happening. If your shard key is missing from the predicate, expect expensive fan-out.Can postgres_fdw handle upserts across shards? +
postgres_fdw supports ON CONFLICT DO NOTHING in limited cases, but it does not support ON CONFLICT DO UPDATE on foreign tables. If you need cross-shard upserts, you usually have to redesign the write path or handle conflicts in application logic.Does postgres_fdw support two-phase commit for distributed transactions? +
Why is partition pruning so important for PostgreSQL sharding? +
enable_partition_pruning enabled, and your schema has to make the shard key obvious to the planner. Without that, native-style sharding behaves like an expensive broadcast layer.Get Engineering Deep-Dives in Your Inbox
Weekly breakdowns of architecture, security, and developer tooling — no fluff.
Related Deep-Dives
PostgreSQL 18 Performance Tuning Checklist
A practical tuning reference for planner costs, vacuum strategy, memory, and slow-query triage.
System Architecturepostgres_fdw vs dblink: What Changes in Production
A side-by-side guide to query pushdown, transaction behavior, and maintainability tradeoffs.
Cloud InfrastructureZero-Downtime PostgreSQL Partitioning Playbook
A lock-aware migration guide for moving large tables to declarative partitioning safely.