DynamoDB-Limits und -Kontingente, geprüft gegen den Live-Service
Was sind die DynamoDB-Limits?
Ein Item ist bei 400 KB gedeckelt, ein Partitionsschlüssel bei 2.048 Bytes und ein Sortierschlüssel bei 1.024 Bytes. Ein Batch-Write nimmt 25 Items, ein Batch-Get 100 Keys, eine Transaction 100 Aktionen. Eine Tabelle bekommt 20 Global Secondary Indexes und 5 Local Secondary Indexes. Jede einzelne Zahl auf dieser Seite wurde ermittelt, indem der Request an Amazon DynamoDB geschickt und die Antwort ausgewertet wurde.
Wie diese Zahlen ermittelt wurden
AWS veröffentlicht seine Kontingente ohne Beleg, und das ist normalerweise kein Problem — bis eine Zahl für eine Designentscheidung tragend wird und du wissen willst, ob sie 400.000 Bytes oder 409.600 meint, ob sie deine Attributnamen mitzählt und was genau der Service sagt, wenn du sie überschreitest.
Also haben wir sie geprüft. Für jedes Limit in der ersten Tabelle unten wurde
ein Request gebaut, der genau auf dem dokumentierten Wert liegt, und an den
Live-Service in us-east-1 geschickt; danach ein zweiter Request, eine
Einheit darüber. Der erste muss akzeptiert und der zweite abgelehnt werden —
dieses Paar lokalisiert die Kante, statt der Dokumentation aufs Wort zu
glauben. Die Ablehnungsmeldung in der letzten Spalte ist der eigene Satz des
Service, wörtlich erfasst und nie abgetippt.
Vier Zeilen ließen sich nur von der Ablehnungsseite aus ermitteln. Das sind
CreateTable-Limits, deren Annahmeseite bedeuten würde, eine Tabelle mit
zwanzig Indizes zu bauen und zu warten, bis jeder aktiv wird, für eine Zahl,
die die Ablehnung ohnehin direkt nennt. Die Spalte Wie es ermittelt wurde
sagt, welche das sind; sie ist keine Dekoration.
Geprüfte Limits
| Limit | Wert | Wie es ermittelt wurde | Was der Service zurückgibt, wenn du es überschreitest |
|---|---|---|---|
| Maximale Item-Größe | 409.600 Bytes | Akzeptiert bei 409.600, abgelehnt bei 409.601 | ValidationException: Item size has exceeded the maximum allowed size |
| Maximale Partitionsschlüssel-Größe | 2.048 Bytes | Akzeptiert bei 2.048, abgelehnt bei 2.049 | ValidationException: One or more parameter values were invalid: Size of hashkey has exceeded the maximum size limit of2048 bytes |
| Maximale Sortierschlüssel-Größe | 1.024 Bytes | Akzeptiert bei 1.024, abgelehnt bei 1.025 | ValidationException: One or more parameter values were invalid: Aggregated size of all range keys has exceeded the size limit of 1024 bytes |
| Maximale Verschachtelungstiefe | 32 Ebenen | Akzeptiert bei 32, abgelehnt bei 33 | ValidationException: 1 validation error detected: Nesting Levels have exceeded supported limits: Attributes in the item have nested levels beyond supported limit |
| Maximale Ausdruckslänge | 4.096 Bytes | Akzeptiert bei 4.096, abgelehnt bei 4.097 | ValidationException: 1 validation error detected: Invalid ConditionExpression: Expression size has exceeded the maximum allowed size; |
| Maximale Items pro BatchWriteItem | 25 Items | Akzeptiert bei 25, abgelehnt bei 26 | ValidationException: 1 validation error detected: Value '<your request>' at 'requestItems' failed to satisfy constraint: Map value must satisfy constraint: [Member must have length less than or equal to 25, Member must have length greater than or equal to 1] |
| Maximale Keys pro BatchGetItem | 100 Items | Akzeptiert bei 100, abgelehnt bei 101 | ValidationException: 1 validation error detected: Value at 'RequestItems.<table-name>.member.Keys' failed to satisfy constraint: Member must have length less than or equal to 100 |
| Maximale Aktionen pro TransactWriteItems | 100 Items | Akzeptiert bei 100, abgelehnt bei 101 | ValidationException: 1 validation error detected: Value '<your request>' at 'transactItems' failed to satisfy constraint: Member must have length less than or equal to 100 |
| Global Secondary Indexes pro Tabelle | 20 | Nur Ablehnung | ValidationException: One or more parameter values were invalid: GlobalSecondaryIndex count exceeds the per-table limit of 20 |
| Local Secondary Indexes pro Tabelle | 5 | Nur Ablehnung | ValidationException: One or more parameter values were invalid: Number of LocalSecondaryIndexes exceeds per-table limit of 5 |
| Projizierte Non-Key-Attribute pro Index | 20 | Nur Ablehnung | ValidationException: 1 validation error detected: Value '<your request>' at 'globalSecondaryIndexes.1.member.projection.nonKeyAttributes' failed to satisfy constraint: Member must have length less than or equal to 20 |
| Projizierte Non-Key-Attribute pro Tabelle | 100 | Nur Ablehnung | ValidationException: One or more parameter values were invalid: Number of projected attributes in all indexes exceeds limit of 100, number of projected attributes:120 |
Umgebung: Amazon DynamoDB, Live-Service, us-east-1, geprüft am 27.08.2026 mit
dem AWS SDK for JavaScript v3.
Was die Sonden zutage brachten
400 KB heißt 409.600 Bytes, und es zählt deine Attributnamen mit. Ein Item, gemessen bei genau 409.600 Bytes, wurde akzeptiert; 409.601 wurde abgelehnt. Die Messung zählt die UTF-8-Länge jedes Attributnamens plus jedes Werts, was dieselbe Berechnung ist, die unser Item-Größenrechner umsetzt — die Sonde baut ihre Payload mit genau dieser Library, sodass beide durch Konstruktion übereinstimmen und nicht nur durch Behauptung. Das tiefere Modellierungsproblem hinter diesem Limit hat seinen eigenen Guide: die DynamoDB-Item-Größengrenze.
Das Projected-Attributes-Limit, das alle zitieren, ist das falsche. Die
AWS-Quotas-Seite
dokumentiert eine Zahl — „up to 100 attributes combined for all of a table's
local and global secondary indexes" — und erwähnt nie eine Obergrenze pro
Index. Es gibt eine, und sie liegt bei 20. Ein CreateTable, der 21
Non-Key-Attribute in einen einzigen Index projiziert, wird abgelehnt, lange
bevor die Gesamtsumme pro Tabelle in die Nähe von 100 kommt. Die 20 ist
dokumentiert, aber nur auf der
Projection-Seite
der API-Referenz, als Constraint für Array-Member: „Maximum number of 20
items". Wer einen Index allein nach der Quotas-Seite plant, dem verweigert die
API ein Schema, das die Quotas-Seite für in Ordnung erklärt. Beide Zahlen
stehen in der Tabelle oben, jede mit der Ablehnung, die sie belegt.
Zwei der Meldungen enthalten AWS' eigene Tippfehler, hier reproduziert
statt still korrigiert — maximum size limit of2048 bytes fehlt ein
Leerzeichen, und number of projected attributes:120 fehlt ein weiteres.
Grepst du Logs nach diesen Strings, grep nach dem, was der Service sendet,
nicht nach dem, was sich richtig liest.
Sortierschlüssel werden aggregiert gemessen. Die Sortierschlüssel-Ablehnung sagt „Aggregated size of all range keys", nicht „the sort key", weil dasselbe 1.024-Byte-Budget den Sortierschlüssel der Tabelle und den jedes Local Secondary Index abdeckt, in dem das Item landet.
Die 1-MB-Seite, die überhaupt nichts auslöst
Jedes Limit oben kündigt sich durch eine Ablehnung an. Das Seitenlimit von
Query und Scan nicht. Überschreitest du es, liefert DynamoDB eine kurze Seite
und einen LastEvaluatedKey, ohne Fehler und ohne Warnung — weshalb „mein Scan
hat nur einen Teil der Tabelle zurückgegeben" eine so verbreitete Überraschung
ist, und weshalb Paginierung nicht optional ist.
Das heißt auch, es gibt keine Fehlermeldung zu zitieren, also wurde stattdessen gemessen:
Bei 1.000 Bytes pro Item hielt eine Seite 1.029 Items und lieferte
einen LastEvaluatedKey — 1.029.000 Bytes Item-Daten, wobei das 1.030. Item
für den nächsten Request übrig blieb. Bei 5.000 Bytes pro Item hielt eine
Seite 208 Items und lieferte einen LastEvaluatedKey — 1.040.000 Bytes
Item-Daten, wobei das 209. Item für den nächsten Request übrig blieb.
Keine der beiden Seiten hielt 1 MiB Item-Daten — die erste blieb rund 19.576 Bytes darunter. Das Seitenbudget berechnet also pro Item mehr, als das Item selbst an Bytes hat.
Zwei Sonden bei unterschiedlichen Item-Größen reichen, um das einzugrenzen.
Behandelt man eine Seite als Items × (Item-Bytes + Overhead pro Item) ≤ Budget, sind nur 7 ganzzahlige Byte-Overheads mit beiden Messungen
konsistent, und genau einer davon legt das Budget auf ein rundes binäres
Megabyte: ein Overhead von 19 Bytes pro Item, mit einem Budget zwischen
1.048.551 und 1.048.971 Bytes — ein Bereich, der 1.048.576 enthält.
DynamoDBs „1 MB" ist binär, wie die eigene Quotas-Seite feststellt, und es
wird für Item-Bytes plus Overhead pro Item ausgegeben. Rechne mit rund 19
Bytes davon pro Item.
Kontingente, die wir nicht geprüft haben
Die Limits unten sind von AWS zitiert, nicht gemessen. Es sind kontoweite Kontingente: Die meisten lassen sich auf Anfrage anpassen, und sie zu erreichen bedeutet, Durchsatz zu provisionieren, der stundenweise abgerechnet wird, Tausende Tabellen anzulegen oder ein Jahr reservierte Kapazität zu kaufen. Nichts davon ist eine Sonde, also wird nichts davon als eine präsentiert. Die Quelle für jede Zeile ist die AWS-Seite Quotas in Amazon DynamoDB.
| Kontingent | Standardwert | Anpassbar | Warum wir es nicht geprüft haben |
|---|---|---|---|
| Tabellen pro Konto pro Region | 2.500 | Ja | 2.500 Tabellen zu erstellen, nur um das Scheitern der 2.501. zu beobachten, hinterlässt ein Konto, das jemand wieder aufräumen muss. |
| Provisionierter Durchsatz pro Tabelle | 40.000 RCU und 40.000 WCU | Ja | 40.000 Units zu provisionieren, wird stundenweise abgerechnet, egal ob auch nur ein einziger Request gestellt wird. |
| Provisionierter Durchsatz pro Konto | 80.000 RCU und 80.000 WCU | Ja | Derselbe Grund, doppelt — und es ändert eine kontoweite Einstellung. |
| On-Demand-Durchsatz pro Tabelle | 40.000 RRU und 40.000 WRU | Ja | Es zu erreichen bedeutet, 40.000 Requests pro Sekunde aufrechtzuerhalten — das ist ein Lasttest mit Rechnung. |
| Aktive reservierte Kapazität pro Konto | 1.000.000 Capacity Units | Ja | Reservierte Kapazität ist eine einjährige Kaufverpflichtung, keine Messung. |
| Tabellengröße | Kein praktisches Limit | — | AWS erklärt, Tabellen seien bei Items und Bytes unbeschränkt; es gibt keine Kante zu finden. |
Um welche Limits du dein Design herum bauen solltest
Die meisten davon wirst du nie erreichen. Die Handvoll, die reale Designs prägt:
- 400 KB pro Item ist ein Modellierungs-Constraint, kein Kontingent. Ein Item, das sich dem nähert, ist meist eine unbegrenzte 1:n-Beziehung, die als eingebettete Liste gespeichert ist. Siehe die Item-Größengrenze.
- Die 1-MB-Seite regiert jedes Query und Scan, das du schreibst. Code, der
LastEvaluatedKeyignoriert, ist heimlich falsch, sobald deine Daten eine Seite überwachsen. - 25 Items pro Batch-Write und 100 pro Batch-Get formen deine Bulk-Load-Schleifen. Siehe Batch-Operationen.
- 100 Aktionen pro Transaction ist das Limit, an das die meisten stoßen, wenn sie versuchen, DynamoDB relational verhalten zu lassen. Siehe Transactions.
- 20 GSIs, 5 LSIs, 100 projizierte Attribute schränken Access-Pattern-Design weit häufiger ein als die Durchsatz-Kontingente, und die LSI-Anzahl steht fest, sobald die Tabelle angelegt ist. Siehe Index-Projektionen und GSI vs. LSI.
Die meisten der oben zitierten Ablehnungen haben auch eine eigene Seite unter
DynamoDB-Fehlern, mit dem Request, der jede davon
produziert. Die vier CreateTable-Ablehnungen nicht — sie wurden für diese
Seite erfasst.
Um ein einzelnes Item ohne Schreiben gegen die 400-KB-Grenze zu prüfen, läuft der Item-Größenrechner in deinem Browser. Um die Items in deinen eigenen Tabellen anzusehen, ist DynoTable ein Desktop-DynamoDB-Client.