Limites e Cotas do DynamoDB, Verificados Contra o Serviço ao Vivo
Quais são os limites do DynamoDB?
Um item tem um teto de 400 KB, uma chave de partição de 2.048 bytes e uma chave de ordenação de 1.024 bytes. Uma gravação em lote leva 25 itens, uma busca em lote 100 chaves, uma transação 100 ações. Uma tabela recebe 20 índices secundários globais e 5 locais. Cada um desses números nesta página foi estabelecido enviando a requisição para o Amazon DynamoDB e lendo o que voltou.
Como esses números foram estabelecidos
A AWS publica suas cotas sem evidência, e isso normalmente é aceitável — até que um número seja decisivo para uma decisão de design e você queira saber se ele significa 400.000 bytes ou 409.600, se ele conta os nomes dos seus atributos, e o que exatamente o serviço diz quando você o ultrapassa.
Então nós os testamos. Para cada limite na primeira tabela abaixo, uma
requisição foi construída para ficar exatamente no valor documentado e
enviada para o serviço ao vivo em us-east-1; depois, uma segunda
requisição, uma unidade além dele. A primeira precisa ser aceita e a segunda
recusada — esse par é o que localiza a borda, em vez de confiar na palavra da
documentação. A mensagem de rejeição na última coluna é a própria frase do
serviço, capturada ao pé da letra e nunca redigitada.
Quatro linhas só puderam ser estabelecidas pelo lado da rejeição. São limites
de CreateTable cujo lado da aceitação significaria construir uma tabela com
vinte índices e esperar cada um ficar ativo, para um número que a rejeição
declara diretamente. A coluna Como foi estabelecido diz qual é qual; ela
não é decoração.
Limites verificados
| Limite | Valor | Como foi estabelecido | O que o serviço retorna quando você o ultrapassa |
|---|---|---|---|
| Tamanho máximo do item | 409.600 bytes | Aceito em 409.600, rejeitado em 409.601 | ValidationException: Item size has exceeded the maximum allowed size |
| Valor máximo da chave de partição | 2.048 bytes | Aceito em 2.048, rejeitado em 2.049 | ValidationException: One or more parameter values were invalid: Size of hashkey has exceeded the maximum size limit of2048 bytes |
| Valor máximo da chave de ordenação | 1.024 bytes | Aceito em 1.024, rejeitado em 1.025 | ValidationException: One or more parameter values were invalid: Aggregated size of all range keys has exceeded the size limit of 1024 bytes |
| Profundidade máxima de aninhamento | 32 níveis | Aceito em 32, rejeitado em 33 | ValidationException: 1 validation error detected: Nesting Levels have exceeded supported limits: Attributes in the item have nested levels beyond supported limit |
| Comprimento máximo da expressão | 4.096 bytes | Aceito em 4.096, rejeitado em 4.097 | ValidationException: 1 validation error detected: Invalid ConditionExpression: Expression size has exceeded the maximum allowed size; |
| Máximo de itens por BatchWriteItem | 25 itens | Aceito em 25, rejeitado em 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] |
| Máximo de chaves por BatchGetItem | 100 itens | Aceito em 100, rejeitado em 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 |
| Máximo de ações por TransactWriteItems | 100 itens | Aceito em 100, rejeitado em 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 |
| Índices secundários globais por tabela | 20 | Somente rejeição | ValidationException: One or more parameter values were invalid: GlobalSecondaryIndex count exceeds the per-table limit of 20 |
| Índices secundários locais por tabela | 5 | Somente rejeição | ValidationException: One or more parameter values were invalid: Number of LocalSecondaryIndexes exceeds per-table limit of 5 |
| Atributos não-chave projetados por índice | 20 | Somente rejeição | 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 |
| Atributos não-chave projetados por tabela | 100 | Somente rejeição | ValidationException: One or more parameter values were invalid: Number of projected attributes in all indexes exceeds limit of 100, number of projected attributes:120 |
Ambiente: Amazon DynamoDB, serviço ao vivo, us-east-1, testado em
2026-08-27 com o AWS SDK for JavaScript v3.
O que as sondas revelaram
400 KB significa 409.600 bytes, e isso conta os nomes dos seus atributos. Um item medido em exatamente 409.600 bytes foi aceito; 409.601 foi rejeitado. A medição conta o comprimento UTF-8 de cada nome de atributo mais cada valor, que é a mesma contabilidade que nossa calculadora de tamanho de item implementa — a sonda constrói seu payload com essa mesma biblioteca, então os dois concordam por construção, não por afirmação. O problema de modelagem mais profundo por trás desse limite tem seu próprio guia: o limite de tamanho de item do DynamoDB.
O limite de atributos projetados que todo mundo cita é o errado. A
página de Cotas
da AWS documenta um único número — "até 100 atributos combinados para todos
os índices secundários locais e globais de uma tabela" — e nunca menciona um
teto por índice. Existe um, e ele é 20. Um CreateTable que projeta 21
atributos não-chave em um único índice é rejeitado bem antes de o total por
tabela chegar perto de 100. O 20 está documentado, mas só na página
Projection
da Referência de API, como uma restrição de membro de array: "Maximum number
of 20 items". Se você planeja um índice só com a página de Cotas, a API vai
recusar um esquema que a página de Cotas diz que está tudo bem. Os dois
números estão na tabela acima, cada um com a rejeição que o comprova.
Duas das mensagens contêm erros de digitação da própria AWS, reproduzidos
aqui em vez de silenciosamente corrigidos — maximum size limit of2048 bytes
está sem um espaço, e number of projected attributes:120 está sem outro. Se
você está fazendo grep nos seus logs por essas strings, faça grep pelo que o
serviço envia, não pelo que se lê corretamente.
Chaves de ordenação são medidas de forma agregada. A rejeição da chave de ordenação diz "Aggregated size of all range keys" ("tamanho agregado de todas as chaves de intervalo"), não "a chave de ordenação", porque o mesmo orçamento de 1.024 bytes cobre a chave de ordenação da tabela e de cada índice secundário local em que o item cai.
A página de 1 MB, que não gera erro algum
Todo limite acima se anuncia rejeitando você. O limite de página de Query e
Scan não. Ultrapasse-o e o DynamoDB devolve uma página curta e um
LastEvaluatedKey, sem erro e sem aviso — o que explica por que "meu Scan só
retornou parte da tabela" é uma surpresa tão comum, e por que a
paginação não é opcional.
Isso também significa que não há mensagem de erro para citar, então foi medido em vez de provocado:
Com 1.000 bytes por item, uma página guardou 1.029 itens e devolveu
um LastEvaluatedKey — 1.029.000 bytes de dados de item, com o item 1.030
deixado para a próxima requisição. Com 5.000 bytes por item, uma página
guardou 208 itens e devolveu um LastEvaluatedKey — 1.040.000 bytes de
dados de item, com o item 209 deixado para a próxima requisição.
Nenhuma das duas páginas guardou 1 MiB de dados de item — a primeira ficou cerca de 19.576 bytes abaixo. Então o orçamento de página cobra mais por item do que os próprios bytes do item.
Duas sondas em tamanhos de item diferentes bastam para determinar isso.
Tratando uma página como
itens × (bytes do item + overhead por item) ≤ orçamento, apenas 7
overheads de byte inteiro são consistentes com as duas medições, e
exatamente um deles coloca o orçamento em um megabyte binário redondo: um
overhead de 19 bytes por item, com o orçamento entre 1.048.551 e
1.048.971 bytes — um intervalo que contém 1.048.576. O "1 MB" do
DynamoDB é binário, como a própria página de cotas afirma, e é gasto em bytes
de item mais overhead por item. Reserve orçamento para cerca de 19 bytes
dele por item.
Cotas que não testamos
Os limites abaixo são citados da AWS, não medidos. São cotas no nível da conta: a maioria é ajustável mediante solicitação, e alcançá-las significa provisionar throughput que fatura por hora, criar milhares de tabelas ou se comprometer com um ano de capacidade reservada. Nada disso é uma sonda, então nada disso é apresentado como uma. A fonte de cada linha é a página Cotas no Amazon DynamoDB da AWS.
| Cota | Valor padrão | Ajustável | Por que não testamos |
|---|---|---|---|
| Tabelas por conta por região | 2.500 | Sim | Criar 2.500 tabelas para ver a de número 2.501 falhar deixa uma conta que alguém tem que desfazer. |
| Throughput provisionado por tabela | 40.000 RCU e 40.000 WCU | Sim | Provisionar 40.000 unidades fatura por hora, faça ou não uma única requisição. |
| Throughput provisionado por conta | 80.000 RCU e 80.000 WCU | Sim | O mesmo motivo, em dobro — e isso muda uma configuração no nível da conta. |
| Throughput on-demand por tabela | 40.000 RRU e 40.000 WRU | Sim | Alcançá-lo significa sustentar 40.000 requisições por segundo, o que é um teste de carga com uma conta a pagar. |
| Capacidade reservada ativa por conta | 1.000.000 unidades de capacidade | Sim | Capacidade reservada é um compromisso de compra de um ano, não uma sonda. |
| Tamanho da tabela | Sem limite prático | — | A AWS afirma que as tabelas não têm restrição de itens ou bytes; não há borda para encontrar. |
Em torno de quais limites vale a pena projetar
A maioria desses você nunca vai encontrar. O punhado que molda designs reais:
- 400 KB por item é uma restrição de modelagem, não uma cota. Um item que se aproxima disso costuma ser um relacionamento um-para-muitos sem limite, armazenado como uma lista incorporada. Veja o limite de tamanho de item.
- A página de 1 MB governa cada Query e Scan que você escreve. Código
que ignora o
LastEvaluatedKeyestá silenciosamente errado no dia em que seus dados ultrapassarem uma página. - 25 itens por gravação em lote e 100 por busca em lote moldam seus loops de carga em massa. Veja operações em lote.
- 100 ações por transação é o limite que as pessoas atingem ao tentar fazer o DynamoDB se comportar de forma relacional. Veja transações.
- 20 GSIs, 5 LSIs, 100 atributos projetados restringem o design de padrões de acesso com muito mais frequência do que as cotas de throughput, e a contagem de LSIs fica fixa no momento em que a tabela é criada. Veja projeções de índice e GSI vs LSI.
A maioria das rejeições citadas acima também tem sua própria página em
erros do DynamoDB, com a requisição que produz cada uma.
As quatro rejeições de CreateTable não têm — elas foram capturadas para
esta página.
Para checar um único item contra a linha de 400 KB sem gravá-lo, a calculadora de tamanho de item roda no seu navegador. Para olhar os itens das suas próprias tabelas, o DynoTable é um cliente desktop para DynamoDB.