Por que um DynamoDB GSI limita as gravações da tabela base
Você escreve para sua mesa. A gravação falha com uma exceção de rendimento — mas o a exceção nomeia um Índice Secundário Global, não a tabela. A mesa tem sobra capacidade.
Vindo de SQL, isso não faz sentido: um índice secundário não pode bloquear um INSERT. Em
DynamoDB pode, e o mecanismo é chamado de GSI contrapressão.
Por que um DynamoDB GSI limita as gravações da tabela base?
DynamoDB limita a gravação da tabela base porque cada gravação também é replicada para cada GSI, e se uma partição GSI não puder absorver sua participação, DynamoDB aplica contrapressão para impedir que o índice fique permanentemente para trás. Portanto, uma chave GSI subprovisionada ou de baixa cardinalidade torna-se um teto rígido na taxa de gravação da tabela base.
- Uma gravação na tabela base também grava em cada GSI. Se um GSI não puder absorver sua participação, DynamoDB limita a gravação da tabela base para evitar que o índice ficando permanentemente para trás. (AWS documentos)
- Uma tabela base par não salva você. O GSI é particionado por sua própria chave.
Uma chave GSI de baixa cardinalidade (como
status) cria ummesmo quando as gravações da tabela base estão perfeitamente espalhadas. - A exceção é sobre a vítima. O
ResourceArnaponta para GSI; a operação que realmente está sendo acelerada é a sua gravação na tabela. - A correção é a capacidade ou o design da chave, não os loops de repetição - aumentar a taxa de transferência GSI, ou escolha um GSIque se espalha.
Como uma única gravação atinge o índice
Um PutItem na tabela base não é uma gravação. DynamoDB replica o item
atributos projetados em cada GSI de forma assíncrona, em um formato eventualmente consistente
modelo. Uma gravação lógica se espalha para N gravações físicas - tabela mais todos os índices.
Essa replicação não é gratuita nem opcional. O GSI deve acompanhar, ou o o índice se afasta ainda mais da tabela em cada operação.
Para parar esse desvio, DynamoDB aplica contrapressão: ele estrangula a fonte escreva para que o índice nunca fique obsoleto ilimitadamente.
Portanto, a capacidade de gravação do GSI é um teto rígido para a taxa de gravação da tabela base - mesmo que você nunca escreva diretamente para GSI.
Um exemplo prático: uma tabela de pedidos
Digamos que você administre uma tabela de pedidos. O item base:
| field | value | note |
|---|---|---|
| PK | "CUST#8841" | partition key |
| SK | "ORD#2026-06-23#A7" | sort key |
| order_state | "PROCESSING" | |
| warehouse | "EU-MAD-2" | |
| total_cents | 4990 |
As gravações da tabela base estão íntegras. CUST#... tem alta cardinalidade, então a ordem é escrita
espalhado uniformemente pelas partições básicas. Nenhuma tecla de atalho, muita capacidade.
Agora você adiciona um GSI para responder "mostre-me todos os pedidos em um determinado estado":
| field | value | note |
|---|---|---|
| GSI-PK | order_state | "PENDING" | "PROCESSING" | "SHIPPED" | "CANCELED" |
| GSI-SK | SK |
Quatro possíveis valores de chave de partição. Durante uma venda relâmpago, quase todos os novos pedidos
chega em order_state = "PENDING". Cada uma dessas gravações atinge o mesmo
Partição GSI.
Essa partição tem um limite de rendimento por partição, e você acabou de direcionar seu toda a tempestade de gravação nisso.
A tabela base está bem. A partição PENDING GSI está pegando fogo. DynamoDB
limita a tabela base PutItem para proteger o índice.
O fluxo que te morde
Caminho de contrapressão - gravação de base balanceada, gravação de índice concentrada:
Uma partição GSI ativa rejeita a gravação da tabela base que o alimentou.
Leia a exceção, não seu instinto
O tipo de exceção informa exatamente qual limite você atingiu. O ResourceArn
nomeia o GSI; a operação acelerada ainda é a gravação da tabela.
| Modo | Código de motivo | O que acabou |
|---|---|---|
| Provisionado | IndexWriteProvisionedThroughputExceeded | Capacidade de gravação provisionada de GSI |
| Ambos | IndexWriteKeyRangeThroughputExceeded | Uma única partição GSI ativa |
| Sob demanda | IndexWriteMaxOnDemandThroughputExceeded | Teto máximo sob demanda configurado de GSI |
| Sob demanda | IndexWriteAccountLimitExceeded | Limite de taxa de transferência de conta/região |
Fonte: Compreendendo a limitação de gravação e a contrapressão de GSI.
O motivo KeyRange é a revelação para o caso de partição quente acima: geral
A capacidade GSI pode parecer boa enquanto um intervalo de teclas está saturado.
Como corrigir
Dê espaço ao GSI. A causa mais simples é o subprovisionamento. Um GSI tem seu própria capacidade de leitura e gravação, totalmente separada da tabela - consulte GSI vs LSI.
Se você provisionou a mesa generosamente e deixou o GSI fino, aumente o GSI capacidade de gravação (ou seu máximo sob demanda).
Corrija a chave de partição. A capacidade não salvará uma chave de baixa cardinalidade — você não pode provisionar uma única partição ativa. Escolha uma chave de partição GSI que se espalhe.
Componha: order_state#shard onde shard é um pequeno sufixo aleatório, ou dobre
a data em (PENDING#2026-06-23). As gravações se espalham pelas partições e você ainda
Query um estado consultando os fragmentos.
Projete menos atributos. Cada gravação GSI copia os atributos projetados. Um
KEYS_ONLY ou projeção estreita INCLUDE significa gravações de índice menores e menos
pressão do que ALL. Não projete o que você nunca lerá no índice.
Elimine o GSI se for apenas para relatórios. Se "pedidos por estado" for um pergunta ocasional do administrador, não um caminho ativo, uma verificação periódica com um filtro pode superar um índice permanentemente quente - compare-o Query vs Scan.
Quando você consulta esse índice, o
Expression Builder grava o
KeyConditionExpression para você - por exemplo. #s = :estado AND begins_with(SK, :prefixo) —
com os nomes e valores escapados corretamente:
KeyConditionExpression "#s = :state AND begins_with(SK, :prefix)"
ExpressionAttributeNames { "#s": "order_state" }
ExpressionAttributeValues { ":state": { "S": "PENDING" }, ":prefix": { "S": "ORD#2026-06-23" } }
A armadilha para lembrar
O instinto relacional - "indexa apenas escrita lenta um pouco" - não transferência. Um DynamoDB GSI é uma dependência de rendimento, não uma estrutura passiva. Reduza o tamanho ou escolha uma chave aglomerada e ela exercerá contrapressão na mesa que serve.
Assista ConsumedWriteCapacityUnits e WriteThrottleEvents no GSI
dimensão, não apenas da tabela, e use o Contributor Insights para encontrar os principais
chaves.
Próximos passos
- GSI vs LSI — por que um GSI tem sua própria capacidade e um chave de partição diferente.
- Design de tabela única — sobrecarregando um GSI para servir muitos padrões sem multiplicar índices quentes.
- Query vs Scan — quando um índice não vale seu custo de gravação.
Tente DynoTable para inspecionar cada GSI em suas tabelas — esquema chave e contagem de itens - e consulte seus índices antes que uma venda os torne vermelhos.