Sharding is the database version of splitting one giant restaurant line into several smaller counters: faster, but only if the host knows who goes where.
Question: What is sharding in SQL databases?
Answer: Sharding means splitting one large table or dataset across multiple database nodes so each node stores only a slice of the rows. The shard key decides which rows go where, and a router or the application uses that key to find the right shard. This is a form of horizontal scaling, because you add more machines instead of making one machine bigger.
Interview-Ready Answer: I’d say sharding is horizontal scaling for data: instead of one database holding every row, I split rows across multiple shards using a shard key such as customer_id or tenant_id. A router, or the app itself, computes the target shard and sends reads and writes there. The big win is that each shard has less data and less load, but the trade-off is that joins, transactions, and resharding get more complex.
Sharding is horizontal partitioning across independent databases. Horizontal means you split by rows, not by columns. Each shard is a smaller database that can have its own indexes, memory cache, connection pool, backups, and failure mode. The key idea is simple: every row belongs to exactly one shard by rule, usually based on a shard key (also called a partition key), such as tenant_id, user_id, or order_id.
| Approach | Where data lives | Main win | Main cost |
|---|---|---|---|
| Sharding | Many servers | Scale writes and storage | Cross-shard complexity |
| Partitioning | One server or cluster | Manageability, pruning | Still one system boundary |
| Replication | Copies of same data | Read scaling, failover | Writes still go to leader |
Why interviewers care: sharding is where performance stops being just about indexes and starts being about data placement. A perfect index on the wrong shard still won’t save you if every query has to fan out.
A single-shard lookup is usually fast because the router does O(1) work to pick the shard, then the shard uses its own local index, often an O(log n) lookup in a B-tree. The real cost is network and coordination: a same-region database round trip can easily be around 0.5–3 ms, while a scatter-gather query across 16 or 32 shards multiplies that cost because you wait for the slowest shard plus the merge step. In practice, a query that was 5 ms on one node can become 20–100 ms when it fans out and has to aggregate results.
Sharding is best when one node cannot handle the data volume, write throughput, or working set size. It is less attractive for small systems, ad hoc analytics, or workloads that constantly join across unrelated entities, because those queries become expensive distributed operations.
Memory hint: a shard is not a faster index; it is a smaller universe. You are shrinking the problem before the index ever runs.
Imagine a checkout service for an e-commerce platform with millions of customers and a fast-growing orders table. The team shards orders by customer_id so that every customer's history stays on one shard, making common reads like WHERE customer_id = ? fast and local. This also keeps the customer's order timeline easy to fetch without scanning every database.
At first, everything looks great: p95 checkout latency drops, and each shard stays under a comfortable CPU level. Then one large enterprise customer starts generating a huge number of small orders, and their traffic lands on a single shard. That shard's CPU climbs to 95%, the connection pool starts queuing, and logs begin showing timeout retries to one specific database host.
What goes wrong: the team assumed sharding automatically balances load. In reality, a bad key choice or a skewed tenant can create a hot shard, which shows up as one shard with slow queries, growing lock waits, and user-visible checkout delays. Users see spinning payment pages, the app logs timeouts like read timeout on shard-07, and support hears complaints that some customers can place orders while others cannot.
-- Two-shard demo: rows are placed by customer_id MOD 2.
-- This shows the core idea of sharding: each shard holds only part of the data.
CREATE TABLE orders_shard_0 (
order_id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL,
amount DECIMAL(10,2) NOT NULL
);
CREATE TABLE orders_shard_1 (
order_id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL,
amount DECIMAL(10,2) NOT NULL
);
-- Correct routing: even customer IDs go to shard 0, odd IDs go to shard 1.
INSERT INTO orders_shard_0 (order_id, customer_id, amount) VALUES (1001, 2, 49.99);
INSERT INTO orders_shard_0 (order_id, customer_id, amount) VALUES (1003, 4, 19.50);
INSERT INTO orders_shard_1 (order_id, customer_id, amount) VALUES (1002, 1, 25.00);
INSERT INTO orders_shard_1 (order_id, customer_id, amount) VALUES (1004, 3, 78.10);
-- Edge case: a bad write lands on the wrong shard.
-- This is the kind of bug that makes reads silently miss data.
INSERT INTO orders_shard_0 (order_id, customer_id, amount) VALUES (1005, 5, 12.00);
-- A simple view that combines all shards for cross-shard reporting.
CREATE VIEW orders_all AS
SELECT 0 AS shard_id, order_id, customer_id, amount FROM orders_shard_0
UNION ALL
SELECT 1 AS shard_id, order_id, customer_id, amount FROM orders_shard_1;
-- Router-style lookup: this is what the app would do before sending SQL.
-- Because customer_id = 5 belongs on shard 1, this query returns no rows,
-- proving that the misplaced row is effectively invisible to the router.
SELECT *
FROM orders_all
WHERE shard_id = MOD(5, 2)
AND customer_id = 5;
-- Failure-path detection: find rows stored on the wrong shard.
-- In a real system, this could be part of a repair job or consistency check.
SELECT shard_id, order_id, customer_id, amount
FROM orders_all
WHERE shard_id <> MOD(customer_id, 2)
ORDER BY order_id;
-- Cross-shard reporting: total counts require reading every shard.
-- This is why sharding helps single-key lookups more than ad hoc analytics.
SELECT COUNT(*) AS total_orders, SUM(amount) AS total_amount
FROM orders_all;Follow-up & Tricky Questions:
Tricky / gotcha questions:
Memory Hook: Sharding is like dividing one giant library into several branch libraries by zip code. Finding one book is faster because each branch has fewer books, but asking for every book on a topic now means visiting multiple branches.