Home Posts PostgreSQL 18 Sharding Survival Guide [2026 Cheat Sheet]
Developer Reference

PostgreSQL 18 Sharding Survival Guide [2026 Cheat Sheet]

PostgreSQL 18 Sharding Survival Guide [2026 Cheat Sheet]
Dillip Chowdary
Dillip Chowdary
Tech Entrepreneur & Innovator · May 20, 2026 · 13 min read

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.
Watch out: Native sharding in PostgreSQL 18 is not a single feature flag. It is an architecture pattern built from partitioning, foreign tables, and careful query design.

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

ShortcutActionWhen to use it
/Focus the live search boxJump straight to a command by keyword
EscClear the filterReturn to the full cheat sheet
jNext visible command blockStep through matching results
kPrevious visible command blockMove back through results
cCopy the active code blockGrab 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.
Pro tip: When you need production-like data on a staging shard, sanitize exports before import with the Data Masking Tool. It is faster than hand-rolling ad hoc SQL scrubbing and reduces the chance of leaking sensitive rows across environments.

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? +
Not as a single built-in cluster feature. In PostgreSQL 18, the native pattern is still declarative partitioning plus foreign tables through 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? +
Use a partitioned parent table on the coordinator and attach local or foreign partitions that point at remote shards. Query the parent table, then verify with 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? +
Not fully. 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? +
No. The official PostgreSQL 18 docs state that preparing the remote transaction for two-phase commit is not supported. If your workflow spans multiple shards and must be atomic, you need an external transaction design such as compensation, idempotency, or a different platform choice.
Why is partition pruning so important for PostgreSQL sharding? +
Because pruning is what stops the coordinator from touching every shard on every query. The docs explicitly warn to keep 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.

Found this useful? Share it.