Intermediário9 min de leitura

Throttling no DynamoDB — por que acontece e como resolver

Throttling é o DynamoDB te dizendo que um limite foi atingido — mas são quatro limites diferentes, três exceções diferentes, e a correção de uma causa piora outra. Aumentar a capacidade da tabela não faz nada por uma chave quente; mudar para on-demand também não faz nada por uma chave quente e ainda pode aplicar throttling pelas próprias regras. Este guia é o guarda-chuva: qual limite você de fato atingiu, como as métricas os diferenciam, e a correção que corresponde a cada causa.

Por que o DynamoDB está aplicando throttling nas minhas requisições?

Por uma de quatro razões documentadas: uma única partição excedeu seu limite fixo por partição de 3.000 unidades de leitura ou 1.000 unidades de escrita por segundo (uma chave quente — acontece nos dois modos de capacidade); a tabela excedeu seu RCU/WCU provisionado (modo provisionado); a conta excedeu sua cota de throughput no nível da região; ou uma tabela on-demand cresceu mais rápido que o dobro do seu pico anterior dentro de 30 minutos. A correção depende de qual foi, então diagnostique antes de redimensionar qualquer coisa.

Os quatro cenários de throttling

A própria página de solução de problemas da AWS divide o throttling em exatamente quatro casos:

  1. Throughput de faixa de chaves (partição) excedido — nos dois modos. Toda partição é projetada para um máximo de 3.000 unidades de leitura e 1.000 unidades de escrita por segundo (documentação de chave de partição), e o tamanho do item conta nessa conta. Nenhuma configuração no nível da tabela aumenta isso; só o design da chave distribui. Este é o caso da partição quente, e a tabela pode parecer enormemente subutilizada enquanto sofre throttling.
  2. Throughput provisionado excedido — modo provisionado. O consumo superou o RCU/WCU provisionado da tabela (ou de um GSI), e o colchão de ~5 minutos de capacidade de rajada foi gasto. A escada de correções é do lado da capacidade: auto-scaling, uma provisão maior ou uma troca de modo.
  3. Cota no nível da conta excedida. As cotas regionais da conta limitam o throughput total — por padrão 40.000 unidades de leitura e 40.000 de escrita por tabela e, no modo provisionado, 80.000 RCU e 80.000 WCU por conta (cotas); esses são valores padrão iniciais, ajustáveis via Service Quotas, e tabelas on-demand não têm cota de throughput no nível da conta.
  4. Throughput máximo do on-demand excedido. O on-demand acomoda instantaneamente até o dobro do pico anterior; cresça além do dobro dentro de 30 minutos e ele pode aplicar throttling (documentação do on-demand). Tabelas on-demand novas sustentam 4.000 escritas/s e 12.000 leituras/s de saída. Para um pico em degrau planejado (lançamento, promoção, migração), pré-aqueça a tabela com warm throughput em vez de torcer para que a subida seja gradual.

As três exceções e o campo que nomeia a causa

  • ProvisionedThroughputExceededException — throttling de capacidade no modo provisionado: "você excedeu o throughput provisionado máximo permitido para uma tabela ou para um ou mais índices secundários globais". Detalhes na página de erro dedicada.
  • ThrottlingException — operações do control plane emitidas rápido demais e, em tabelas on-demand, qualquer operação do data plane cuja taxa esteja alta demais (é a exceção por trás da regra do dobro do pico — veja a página de erro do on-demand e ThrottlingException).
  • RequestLimitExceeded — limites de throughput no nível da conta: território de "fale com o AWS Support", coberto na página de erro dela.

As três são marcadas como passíveis de retry, e as três agora carregam valores estruturados de ThrottlingReason no formato recurso + operação + limite — TableReadProvisionedThroughputExceeded, IndexWriteKeyRangeThroughputExceeded, TableWriteAccountLimitExceeded e assim por diante (referência de erros). Leia a razão, não só a classe da exceção: ela nomeia o recurso (tabela ou índice), a direção da operação e qual dos quatro limites você atingiu — que é exatamente o diagnóstico. Uma ressalva que a própria documentação impõe: as páginas da AWS divergem sobre se o throttling de limite de conta aparece como RequestLimitExceeded ou como uma ThrottlingException com a razão AccountLimitExceeded, então baseie seu tratamento na string da razão.

O que absorve carga antes de você sofrer throttling

Dois recursos nativos amaciam os limites, e conhecer as bordas deles explica o "ontem funcionava":

  • A capacidade de rajada (burst) retém até cinco minutos (300 segundos) de capacidade de leitura e escrita não usada para picos — mas o DynamoDB também pode consumi-la em manutenção em segundo plano "sem aviso prévio", e a AWS observa explicitamente que os detalhes podem mudar. Não projete contando com a rajada; trate-a como sorte.
  • A capacidade adaptativa desloca throughput automática e instantaneamente em direção às partições quentes e consegue isolar um item muito acessado em sua própria partição — mas só "desde que o tráfego não exceda a capacidade provisionada total da sua tabela nem a capacidade máxima da partição". Ela reequilibra o desvio; nunca levanta o teto de 3.000/1.000 por partição, e não divide coleções de itens quando a tabela tem um LSI. As páginas atuais de solução de problemas da AWS se apoiam no split-for-heat — partições se dividindo sob calor sustentado —, que leva tempo e não ajuda em uma única chave quente.

Diagnostique pelas métricas

O CloudWatch separa requisições de eventos, e a distinção é o que faz o diagnóstico (referência de métricas):

  • ThrottledRequests conta uma requisição uma vez se qualquer evento dentro dela sofreu throttling — um PutItem em uma tabela com três GSIs é uma requisição, mas quatro eventos de escrita. Em um batch, ela só incrementa se todos os itens sofrerem throttling.
  • ReadThrottleEvents / WriteThrottleEvents contam cada evento com throttling — um BatchGetItem de 10 itens são 10 eventos GetItem. Para ver o throttling de escrita de um GSI, você precisa consultar a métrica com TableName e GlobalSecondaryIndexName juntos — é assim que a contrapressão de GSI se esconde dos dashboards no nível da tabela.
  • As mais novas métricas de evento específicas por razão (WriteProvisionedThroughputThrottleEvents, ReadKeyRangeThroughputThrottleEvents, …AccountLimitThrottleEvents, …MaxOnDemandThroughputThrottleEvents) separam as contagens pelas mesmas quatro causas — se a sua região as exibe, elas respondem direto à pergunta "qual limite".

Uma armadilha: os SDKs refazem automaticamente as requisições com throttling — o modo de retry padrão faz 3 tentativas no total por padrão (a adesão opcional ao novo comportamento de retry de 2026 leva os clientes do DynamoDB a 4 tentativas com atrasos mais curtos). Um throttling leve, portanto, aparece como latência, não como erro; observe as métricas de throttling, não só os seus logs de exceção.

yesnoyesnoprovisionedon-demandThrottling observedThrottleEvents on a GSI(TableName + IndexName)?GSI back-pressure:scale the indexTable utilization far belowprovisioned / expected?Hot key: fix key design,split-for-heat needs timeCapacity mode?Raise capacity /auto scaling / switch modeGrew past 2x previous peak:pre-warm or spread the ramp

Contrapressão de GSI: o throttling que aponta para a tabela errada

Se algum GSI não consegue absorver a amplificação de escrita, "o DynamoDB aplica throttling nas escritas da tabela base para manter a consistência dos dados" (documentação de throttling de GSI) — mesmo quando a tabela base tem capacidade de sobra. O ResourceArn da exceção aponta para o índice, mas a operação que falhou é a sua escrita na tabela base. Todo índice precisa do seu próprio plano de capacidade (e da sua própria política de auto-scaling); por que um GSI aplica throttling nas escritas da tabela base percorre a mecânica.

Combine a correção com a causa

CausaO que resolveO que não resolve
Chave / partição quenteDesign de chave que distribui a carga (partições quentes); tempo para o split-for-heatAumentar a capacidade da tabela, mudar para on-demand
Capacidade provisionadaAuto-scaling, mínimo maior ou on-demandSó retries — eles adicionam carga
Contrapressão de GSIEscalar o índice; mudanças de índice esparso ou de projeçãoEscalar a tabela base
Cota da contaAumento via Service QuotasConfigurações no nível da tabela
Pico em degrau no on-demandPré-aquecer (warm throughput); espalhar a subida por 30+ minEsperar — o dobro do pico se ajusta devagar

Faça isso no DynoTable

A maior parte do throttling autoinfligido começa com leituras que custam mais do que aparentam: um Scan filtrado consome a leitura inteira de qualquer jeito. A prévia de custo do DynoTable, antes da execução, mostra se uma instrução vira um Query ou um Scan, qual índice ela atinge e um custo de leitura estimado antes de você gastá-lo — a correção de throttling mais barata é a leitura cara que você não rodou. O guia Scan vs Query cobre a diferença; a calculadora de tamanho de item gratuita transforma um item real nos números de RCU/WCU em que os limites acima são medidos.

Armadilhas e próximos passos

  • Retries amplificam a sobrecarga. O backoff já vem embutido nos SDKs, mas um laço de retry apertado no nível da aplicação, por cima dos retries do SDK, multiplica a pressão exatamente sobre a partição que está sofrendo.
  • Batches escondem throttling parcial. Um BatchWriteItem devolve itens não processados em vez de lançar exceção enquanto algum item tiver sucesso — confira UnprocessedItems, não só as exceções.
  • A visão no nível da tabela mente sobre os GSIs. Sempre plote os eventos de throttling por índice; os dashboards da tabela base parecem limpos durante a contrapressão.
  • Correções de capacidade levam minutos; design de chave é para sempre. O auto-scaling reage em ~5 minutos, aumentos de cota exigem um ticket de suporte, mas uma chave quente te segue em todo modo de capacidade — invista o esforço onde ele se acumula: como funcionam as chaves de partição.

Baixe o DynoTable para ver o plano Scan-vs-Query e o custo de leitura de cada consulta antes de ela rodar contra a sua capacidade.

Atualizado