↔️Sharding and vertical split
Rows across machines vs columns across tables
Horizontal sharding places disjoint row subsets on different nodes, joins and transactions that span shards need routing, scatter/gather, or sagas. Vertical partitioning moves wide or cold columns into companion tables inside the same database, still one planner, simpler joins, narrower hot caches.
⚖️Compare the moves
Cross-shard SQL is never free.
| Approach | What moves | Cross-shard SQL? |
|---|---|---|
| Horizontal shard | Rows of the same logical table | Requires router, coordinator, or app-level fan-out, 2PC is rare in product code. |
| Vertical split | Columns into companion tables | Ordinary joins in one engine, simplest operational story. |
Vertical split example
CREATE TABLE users_core (
user_id BIGINT PRIMARY KEY,
email TEXT NOT NULL
);
CREATE TABLE users_profile (
user_id BIGINT PRIMARY KEY REFERENCES users_core(user_id),
bio TEXT,
avatar_bytes BYTEA
);| result |
|---|
| CREATE TABLE |
| CREATE TABLE |
Shard without a map
- Global reports that fan out to every shard without a warehouse escape hatch.
- Hot tenants concentrated on one physical shard.
- Assuming auto-increment integers are unique across shards.
Co-locate access paths
- Pick shard keys from real query paths (
tenant_id, not alphabetical convenience). - Use per-shard sequences, UUID ranges, or snowflake IDs; document failover routing.
- Stream facts to OLAP for cross-tenant analytics instead of hammering OLTP shards.
🎡Consistent Hashing
Adding a node shouldn't require moving every row.
The Resharding Problem
Standard modulo sharding (shard = id % N) is a disaster when you add the (N+1)-th node: almost every row changes its shard destination. Consistent Hashing maps nodes and keys onto a 360-degree circle. When a node is added, it only "steals" a portion of keys from its neighbor, minimizing data movement.
Virtual Nodes
Online Movement
🔀The Distributed Join Problem
Networking is the new bottleneck.
| Join Type | Mechanical Strategy | When to use |
|---|---|---|
| Co-located Join | Join keys share the same shard key. Stay on one node. | Fastest. Zero network overhead. |
| Broadcast Join | Send a small table (metadata) to every shard node. | Good for small dimension tables (e.g., countries). |
| Shuffle / Reshuffle | Redistribute both tables by the join key across the network. | Slow. High network I/O; avoid for large fact tables. |
Relational locality
Architecture follows data: If your app joins Order and OrderItem, you must shard both by order_id. If you shard one by order_id and the other by item_id, you've turned a local join into a distributed shuffle.
TL;DR
Vertical scaling upgrades CPU/RAM/IO on one server, simple until hardware ceilings. Horizontal scaling adds nodes: read replicas for reads, or sharding that splits rows/partitions across primaries by a shard key. Sharding trades SQL convenience (cross-shard joins, transactions) for throughput, design the shard key and locality story before traffic forces it.