Skip to content
Quest 01Beginner12 min

Understanding Partition Keys

In DynamoDB, every item (row) must have a primary key — it uniquely identifies that item in a table. The Partition Key (also called Hash Key) decides where the item is stored inside DynamoDB's internal partitions.

What you'll learn

  • Primary keys uniquely identify each item in a table.
  • Partition keys determine the physical placement of data.
  • Items sharing a partition key form an item collection; this logical group can span physical partitions.

Section 01

What Is a Partition Key?

In DynamoDB, every item (row) must have a primary key — it uniquely identifies that item in a table.

The Partition Key (also called Hash Key) decides where the item is stored inside DynamoDB's internal partitions.

Section 02

How DynamoDB Uses It

When you insert or fetch data:

  • DynamoDB uses the Partition Key value to compute a hash.
  • That hash decides which internal partition the item lives in.
  • Items with the same partition key form an item collection. On a table without a local secondary index (LSI, covered later), DynamoDB can split that collection across physical partitions as it scales.
Partition key
Your appAWS SDK v3DynamoDBtableP0P1P2P3CONSUMED0

Writes per partition

  • P00
  • P10
  • P20
  • P30

Each partition handles up to 1,000 write units and 3,000 read units per second.

Ready · 120 steps · Bloop

Partition key: Name. Press Play to send 24 PutItem requests.

All steps as text
  1. Your app sends PutItem to the Pokemon table with Name = "Squirtle".
  2. DynamoDB hashes "Squirtle" to 852d76de, which routes the request to partition P2.
  3. P2 stores Squirtle.
  4. This call consumed 1 WCU.
  5. DynamoDB responds with success.
  6. Your app sends PutItem to the Pokemon table with Name = "Charmander".
  7. DynamoDB hashes "Charmander" to 556efe94, which routes the request to partition P0.
  8. P0 stores Charmander.
  9. This call consumed 1 WCU.
  10. DynamoDB responds with success.
  11. Your app sends PutItem to the Pokemon table with Name = "Bulbasaur".
  12. DynamoDB hashes "Bulbasaur" to 95ae6fe8, which routes the request to partition P0.
  13. P0 stores Bulbasaur.
  14. This call consumed 1 WCU.
  15. DynamoDB responds with success.
  16. Your app sends PutItem to the Pokemon table with Name = "Pikachu".
  17. DynamoDB hashes "Pikachu" to a6bb8b2f, which routes the request to partition P3.
  18. P3 stores Pikachu.
  19. This call consumed 1 WCU.
  20. DynamoDB responds with success.
  21. Your app sends PutItem to the Pokemon table with Name = "Meowth".
  22. DynamoDB hashes "Meowth" to 300417a2, which routes the request to partition P2.
  23. P2 stores Meowth.
  24. This call consumed 1 WCU.
  25. DynamoDB responds with success.
  26. Your app sends PutItem to the Pokemon table with Name = "Mew".
  27. DynamoDB hashes "Mew" to 416a585c, which routes the request to partition P0.
  28. P0 stores Mew.
  29. This call consumed 1 WCU.
  30. DynamoDB responds with success.
  31. Your app sends PutItem to the Pokemon table with Name = "Totodile".
  32. DynamoDB hashes "Totodile" to e49e153a, which routes the request to partition P2.
  33. P2 stores Totodile.
  34. This call consumed 1 WCU.
  35. DynamoDB responds with success.
  36. Your app sends PutItem to the Pokemon table with Name = "Cyndaquil".
  37. DynamoDB hashes "Cyndaquil" to 6203cc87, which routes the request to partition P3.
  38. P3 stores Cyndaquil.
  39. This call consumed 1 WCU.
  40. DynamoDB responds with success.
  41. Your app sends PutItem to the Pokemon table with Name = "Oddish".
  42. DynamoDB hashes "Oddish" to 17306a82, which routes the request to partition P2.
  43. P2 stores Oddish.
  44. This call consumed 1 WCU.
  45. DynamoDB responds with success.
  46. Your app sends PutItem to the Pokemon table with Name = "Pichu".
  47. DynamoDB hashes "Pichu" to 8aec63e0, which routes the request to partition P0.
  48. P0 stores Pichu.
  49. This call consumed 1 WCU.
  50. DynamoDB responds with success.
  51. Your app sends PutItem to the Pokemon table with Name = "Psyduck".
  52. DynamoDB hashes "Psyduck" to 56201ecd, which routes the request to partition P1.
  53. P1 stores Psyduck.
  54. This call consumed 1 WCU.
  55. DynamoDB responds with success.
  56. Your app sends PutItem to the Pokemon table with Name = "Jigglypuff".
  57. DynamoDB hashes "Jigglypuff" to 6d9fe221, which routes the request to partition P1.
  58. P1 stores Jigglypuff.
  59. This call consumed 1 WCU.
  60. DynamoDB responds with success.
  61. Your app sends PutItem to the Pokemon table with Name = "Lugia".
  62. DynamoDB hashes "Lugia" to 96f9f356, which routes the request to partition P2.
  63. P2 stores Lugia.
  64. This call consumed 1 WCU.
  65. DynamoDB responds with success.
  66. Your app sends PutItem to the Pokemon table with Name = "Feraligatr".
  67. DynamoDB hashes "Feraligatr" to c7710d25, which routes the request to partition P1.
  68. P1 stores Feraligatr.
  69. This call consumed 1 WCU.
  70. DynamoDB responds with success.
  71. Your app sends PutItem to the Pokemon table with Name = "Typhlosion".
  72. DynamoDB hashes "Typhlosion" to f50a9811, which routes the request to partition P1.
  73. P1 stores Typhlosion.
  74. This call consumed 1 WCU.
  75. DynamoDB responds with success.
  76. Your app sends PutItem to the Pokemon table with Name = "Chikorita".
  77. DynamoDB hashes "Chikorita" to df9e8fa1, which routes the request to partition P1.
  78. P1 stores Chikorita.
  79. This call consumed 1 WCU.
  80. DynamoDB responds with success.
  81. Your app sends PutItem to the Pokemon table with Name = "Magikarp".
  82. DynamoDB hashes "Magikarp" to 6c84dce0, which routes the request to partition P0.
  83. P0 stores Magikarp.
  84. This call consumed 1 WCU.
  85. DynamoDB responds with success.
  86. Your app sends PutItem to the Pokemon table with Name = "Mareep".
  87. DynamoDB hashes "Mareep" to a542bc96, which routes the request to partition P2.
  88. P2 stores Mareep.
  89. This call consumed 1 WCU.
  90. DynamoDB responds with success.
  91. Your app sends PutItem to the Pokemon table with Name = "Snorlax".
  92. DynamoDB hashes "Snorlax" to c43f9cf3, which routes the request to partition P3.
  93. P3 stores Snorlax.
  94. This call consumed 1 WCU.
  95. DynamoDB responds with success.
  96. Your app sends PutItem to the Pokemon table with Name = "Quagsire".
  97. DynamoDB hashes "Quagsire" to 40292b9f, which routes the request to partition P3.
  98. P3 stores Quagsire.
  99. This call consumed 1 WCU.
  100. DynamoDB responds with success.
  101. Your app sends PutItem to the Pokemon table with Name = "Abra".
  102. DynamoDB hashes "Abra" to 5440add7, which routes the request to partition P3.
  103. P3 stores Abra.
  104. This call consumed 1 WCU.
  105. DynamoDB responds with success.
  106. Your app sends PutItem to the Pokemon table with Name = "Ho-Oh".
  107. DynamoDB hashes "Ho-Oh" to c7683bc5, which routes the request to partition P1.
  108. P1 stores Ho-Oh.
  109. This call consumed 1 WCU.
  110. DynamoDB responds with success.
  111. Your app sends PutItem to the Pokemon table with Name = "Chinchou".
  112. DynamoDB hashes "Chinchou" to c05d1c5f, which routes the request to partition P3.
  113. P3 stores Chinchou.
  114. This call consumed 1 WCU.
  115. DynamoDB responds with success.
  116. Your app sends PutItem to the Pokemon table with Name = "Lanturn".
  117. DynamoDB hashes "Lanturn" to 5432a098, which routes the request to partition P0.
  118. P0 stores Lanturn.
  119. This call consumed 1 WCU.
  120. DynamoDB responds with success.

Teaching model: 4 partitions and a stand-in hash function. DynamoDB manages partitions itself, and adaptive capacity shifts throughput toward busy partitions, but a single partition key value still cannot exceed 1,000 WCU or 3,000 RCU per second.

Section 03

Types of Primary Keys

DynamoDB supports two primary key patterns.

Section 04

Simple Primary Key (only Partition Key)

Uses one attribute to uniquely identify an item.

Example:

  • Partition Key: Name
  • Every Pokémon's name is unique → each item = one Pokémon.
NameType1Type2Height(m)Weight(kg)
Bulbasaurgrasspoison0.76.9
Charmanderfire---0.68.5
Squirtlewater---0.59.0

Each Pokémon is uniquely identified by its Name attribute.

Use Case: Perfect when each Pokémon is unique and can be fetched directly by name:

GetItem input (document client)JavaScript
{
  TableName: "Pokemon",
  Key: { Name: "Bulbasaur" }
}

Section 05

Composite Primary Key (Partition + Sort Key)

Uses two attributes together for uniqueness.

The following is a small teaching example. Type1 has very few possible values, so a large production workload could concentrate traffic on hot keys. Start from real access patterns and choose a high-cardinality, evenly used partition key—or add a deliberate shard when one logical group receives heavy traffic.

Toy example:

  • Partition Key: Type1
  • Sort Key: Name
  • This way, Pokémon of the same type are grouped together.
Type1NameHeight(m)Weight(kg)
grassBulbasaur0.76.9
grassIvysaur1.013.0
fireCharmander0.68.5
fireCharizard1.790.5

Useful for seeing composite-key mechanics, not a blanket production recommendation for a high-traffic Pokédex.

Use Case: Quickly find all Pokémon of a specific type, sorted alphabetically:

Query exampleJavaScript
{
  TableName: "PokemonByType",
  KeyConditionExpression: "Type1 = :type",
  ExpressionAttributeValues: { ":type": "fire" }
}

Check

Check your understanding

Quick Quiz · one question, as many tries as you need.

If you define a table with only one attribute (Name) as a key, what type of key is that?

Choose one answer.