Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

System Design (High-Level Design)  Module 9 – Partitioning and sharding

Hot partitions, celebrity keys and key salting

Why one viral post or famous account can overload a partition that no hash function can fix, and how salted keys, replicas and batching spread the load.

  • Advanced
  • 20 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0 and quickjs 0.32.0
  • By MySmartCoPilot
Free intro, Pro: 4 of 20 minutes free
Free: A hash spreads keys, not the requests for one key. With a pass: the other 8 sections and 3 interview answers, about 16 minutes.

What you will learn

  • Explain why no hash function or partition count spreads the requests for a single key
  • Detect hot partitions and hot keys from per-partition and per-key measurements
  • Find the top keys of a stream in fixed memory with Space-Saving, and state how far its counts can be off
  • Size and spread a write-hot key over salted keys without double counting retries
  • Choose read or write fixes for celebrity accounts in feeds, counters and chats

Before you start

What you’ll learn · Before you start

What you will learn

  • Explain why no hash function or partition count spreads the requests for a single key
  • Detect hot partitions and hot keys from per-partition and per-key measurements
  • Find the top keys of a stream in fixed memory with Space-Saving, and state how far its counts can be off
  • Size and spread a write-hot key over salted keys without double counting retries
  • Choose read or write fixes for celebrity accounts in feeds, counters and chats

Before you start

On this page

One viral post draws 8 % of all likes. At a peak of 20,000 likes a second, the partition that owns its counter takes 2,202 likes a second against a limit of 1,000, while the average partition takes 625. Partitions like that one are hot partitions: they receive far more requests than the rest of a cluster, so they reach their limits while the other partitions are half idle.

They usually come from celebrity keys: single keys, such as one viral post or one famous account, that draw a large share of all reads or writes. Hashing spreads keys evenly, but every request for one key still goes to the one partition that owns it, so no better hash can help. Key salting splits a hot key into several keys by adding a suffix, which spreads its writes over several partitions. The fix depends on whether the heat comes from reads or from writes.

A hash spreads keys, not the requests for one key

Hashing spreads keys, not requests. If one post draws 8 % of all likes, 8 % of the like writes reach the partition that owns its counter, however many partitions there are. Each partition has a ceiling: DynamoDB designs every partition for at most 3,000 read units and 1,000 write units a second, and its A DynamoDB feature that lets a busy partition use throughput that quieter partitions of the table leave unused, and that can move frequently accessed items onto partitions of their own. can move a hot item onto a partition of its own, but no further than that ceiling. This run spreads a sample of likes over 32 partitions by hash and scales it to a peak of 20,000 likes a second:

Where a peak of likes lands on 32 partitions Python · measured/where_likes_land.py
import random
import zlib

POSTS = 100_000
LIKES = 200_000          # a sample of the day's likes
PARTITIONS = 32
PEAK = 20_000            # likes a second at the peak, spread like the sample
LIMIT = 1_000            # writes a second one partition takes (the per-partition limit DynamoDB documents)
rng = random.Random(7)   # fixed seed: the same likes on every run

# A few posts draw most likes: the post of rank r is liked in proportion to 1 / r.
weights = [1 / (rank + 1) for rank in range(POSTS)]
likes = rng.choices(range(POSTS), weights=weights, k=LIKES)


def partition(key):
    """Hash partitioning: CRC-32 of the key, modulo the partition count."""
    return zlib.crc32(key.encode()) % PARTITIONS


load = [0] * PARTITIONS
for post in likes:
    load[partition(f"post:{post}")] += 1
top_post = sum(1 for post in likes if post == 0)
busiest = max(range(PARTITIONS), key=lambda p: load[p])


def row(name, count):
    share = 100 * count / LIKES
    rate = PEAK * count / LIKES
    mark = " !" if rate > LIMIT else ""
    print(f"{name:<15}{share:>5.1f} %{rate:>11,.0f}{mark}")


print(f"{LIKES:,} likes on {POSTS:,} posts, {PARTITIONS} partitions,")
print(f"{PEAK:,} likes a second at the peak\n")
print(f"{'':<15}{'share':>7}{'a second':>11}")
row("average", LIKES / PARTITIONS)
row(f"busiest (P{busiest})", load[busiest])
row("quietest", min(load))
row(f"top post (P{partition('post:0')})", top_post)
print(f"! over the limit of {LIMIT:,} a second")

Output

200,000 likes on 100,000 posts, 32 partitions,
20,000 likes a second at the peak

                 share   a second
average          3.1 %        625
busiest (P21)   11.0 %      2,202 !
quietest         1.9 %        387
top post (P21)   8.3 %      1,651 !
! over the limit of 1,000 a second

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 where_likes_land.py

The figure follows the top post’s likes to its partition, then through seven salted keys:

Every like of one post goes to partition P21, which takes 2,202 a second against a limit of 1,000; seven salted keys spread them.One keyKey saltingLikes of post:01,651 a secondPartition P212,202 a secondlimit 1,000(the average partition: 625)Likes of post:01,651 a secondpost:0#0 … post:0#6about 236 a second eachUp to seven partitionsone hash per keyhash mod 32 = 21suffix fromthe like's idsplit the hot key

One hot key, before and after key salting

Text description of the diagram

The diagram has two panels, one above the other.

  1. One key: the likes of post:0 arrive at 1,651 a second. The hash of post:0 modulo 32 is 21, so all of them go to partition P21, which takes 2,202 likes a second in all against a limit of 1,000. The average partition takes 625.
  2. Key salting: the same 1,651 likes a second go to seven keys, post:0#0 to post:0#6, chosen by a suffix calculated from each like's id, so each key takes about 236 a second. Each key is hashed on its own, so the seven keys land on up to seven different partitions.

An arrow from the first panel to the second is labelled "split the hot key".

The average partition takes 625 likes a second, well inside a limit of 1,000, so hot partitions do not show in averages. The busiest partition takes 2,202, more than twice the limit, because the top post alone sends it 1,651. That post would be throttled even on a partition of its own, so its counter has to become at least 2 keys (1,651 ÷ 1,000, rounded up), or 7 keys if each key may use only a quarter of a partition.

Hot keys get different fixes for reads and for writes:

  • Key salting adds a suffix such as #0 to #6, so one hot key becomes several keys on different partitions.
  • Replicas and small local caches serve a read-hot key from many copies instead of one partition. Replicas fit data that is read far more often than it is written.
  • Request coalescing turns many concurrent reads of one key into a single read of the store.
  • Batching adds increments up in memory and writes one sum per interval. Batching fits a count that may lag by a moment, such as the likes under a post.
  • Fan-out on read handles celebrity keys in feeds: a famous account’s post is stored once and fetched by each follower, instead of being copied into millions of feeds.

Checkpoint

Check: Why one key overloads one partition

  1. Question 1 of 2 The top post's counter takes 1,651 likes a second, and a partition takes at most 1,000 writes a second. Into how many keys must the counter be split, at the very least?

    Type a number.

    Show the answer: Question 1 of 2

    Answer: 2 keys

    1,651 ÷ 1,000 is about 1.7, and a key count is a whole number, so at least 2 keys, on 2 partitions. If each key may use only a quarter of a partition, 250 a second, it takes 7.

  2. Question 2 of 2 The cluster grows from 32 partitions to 64. What happens to the 1,651 likes a second of the top post?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: They still all reach one partition, the one that owns the post's counter

    Hashing spreads keys, not requests. Doubling the partitions halves the average load and leaves the one hot key where it is, so the key itself has to be split, copied or batched.

Hot keys show in the busiest partition, not in averages Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • Space-Saving: a top-k list in fixed memory, and its guarantee
  • Salting a write-hot key, measured
    • How many keys a hot key needs, worked
  • A suffix from the request id survives retries
  • Celebrity accounts in feeds, counters and chats
  • What salting breaks, and how to keep it safe
  • Practise: split a hot counter
    • Split a hot counter into enough keys
  • Interview questions
    • What is the difference between a hot key and a hot partition?
    • A celebrity's post receives 40,000 likes a second at its peak, and the partition holding its like counter throttles at 1,000 writes a second. Design the counter so that writes succeed, retries are not counted twice and the number shown stays close to the truth.
    • Your news feed copies every post into each follower's feed when it is posted. An account with 30 million followers posts, and feed writes back up for minutes. What happens on the write path, and how would you change the design for such accounts?
    • Throttling alarms fire on one partition of a sharded table, but the table's average utilisation is 20 %. How do you find the key responsible, what do you do in the next ten minutes, and what do you change in the next ten days?
  • Key takeaways

3 diagrams · 5 runnable examples (JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 52 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Read a complete sample first: Design a unique ID generator

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.