DynamoDB Modos de Capacidade: Provisionado vs. On-Demand — Como Escolher Sem Errar

Você acabou de modelar sua tabela DynamoDB e chegou na tela de configuração de capacidade. O tráfego da aplicação ainda é incerto — pode ser 10 requisições por segundo, pode ser 10.000. Escolher o modo errado aqui significa ou pagar por capacidade ociosa ou ver a aplicação throttlada em produção. Este post detalha como os modos de capacidade do DynamoDB funcionam internamente, quando cada um faz sentido, e como migrar entre eles sem surpresas.

TL;DR — Modos de Capacidade DynamoDB

CritérioOn-DemandProvisionado
Tráfego previsível❌ Custo mais alto✅ Mais econômico
Tráfego imprevisível ou novo✅ Sem risco de throttling❌ Risco de under-provisioning
Picos esporádicos e intensos✅ Absorve automaticamente⚠️ Depende de Auto Scaling
Custo por unidadeMais caro por RCU/WCU individualMais barato com uso consistente
Configuração operacionalZeroRequer monitoramento e ajuste
Troca de modoUma vez a cada 24 horas (com exceção documentada)

Como os Modos de Capacidade do DynamoDB Funcionam

Antes de escolher, você precisa entender o que está comprando. O DynamoDB não aloca servidores — ele aloca unidades de capacidade de leitura (RCU) e unidades de capacidade de escrita (WCU). Cada operação consome uma quantidade específica dessas unidades dependendo do tamanho do item e do tipo de leitura (eventual ou forte consistência).

O modo de capacidade determina como essas unidades são provisionadas e cobradas — não o que elas fazem.

graph TD A["Requisição DynamoDB"] --> B{"Modo de Capacidade?"} B -->|"On-Demand"| C["DynamoDB escala
automaticamente"] B -->|"Provisionado"| D{"Tokens RCU/WCU
disponíveis?"} D -->|"Sim"| E["Requisição processada"] D -->|"Não"| F{"Burst Capacity
disponível?"} F -->|"Sim"| E F -->|"Não"| G["ProvisionedThroughput
ExceededException"] C --> E
  1. Requisição chega ao DynamoDB e é roteada para a partição correta.
  2. No modo Provisionado, o sistema verifica se há RCU/WCU disponíveis no bucket de tokens. Se não houver, a requisição é throttlada com ProvisionedThroughputExceededException.
  3. No modo On-Demand, o DynamoDB ajusta a capacidade automaticamente — sem bucket de tokens fixo exposto ao usuário.
  4. O Burst Capacity no modo Provisionado permite absorver picos temporários usando tokens acumulados (até 5 minutos de capacidade não utilizada), mas não é garantido e não substitui provisionamento adequado.

Modo On-Demand: Quando Faz Sentido

O On-Demand é a escolha certa quando você genuinamente não sabe o volume de tráfego — aplicações novas, MVPs, workloads com picos completamente imprevisíveis. Você paga por requisição processada, sem comprometimento de capacidade antecipado.

O ponto que a maioria ignora: no On-Demand, o DynamoDB escala baseado no pico de tráfego anterior da tabela. Uma tabela nova tem capacidade inicial limitada e pode levar alguns minutos para escalar se você disparar um volume muito alto imediatamente. Se você sabe que vai ter um pico de lançamento, é possível fazer um 'warm-up' executando tráfego gradual antes do evento.

Pense no On-Demand como um táxi — você paga pela corrida, não pela disponibilidade do carro. Conveniente e sem compromisso, mas o custo por km é mais alto do que ter seu próprio veículo rodando constantemente.

Verificando o modo atual de uma tabela:

aws dynamodb describe-table \
  --table-name minha-tabela \
  --query 'Table.BillingModeSummary'

Criando uma tabela em modo On-Demand:

aws dynamodb create-table \
  --table-name minha-tabela \
  --attribute-definitions AttributeName=pk,AttributeType=S \
  --key-schema AttributeName=pk,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

Modo Provisionado: Quando Faz Sentido

Quando o padrão de tráfego é conhecido e estável — ou previsível o suficiente para o Auto Scaling cobrir a variação — o modo Provisionado é significativamente mais barato. Você define RCU e WCU antecipadamente, e o DynamoDB garante essa capacidade para sua tabela.

O risco real não é o conceito, é a operação. Times que configuram Provisionado sem habilitar Auto Scaling e depois esquecem a tabela são os que abrem tickets de throttling às 2h da manhã.

graph LR A["Tráfego"] --> B["Tabela DynamoDB
Provisionado"] B --> C["CloudWatch
ConsumedCapacityUnits"] C --> D{"Utilização >
threshold?"} D -->|"Sim"| E["Application
Auto Scaling"] E --> F["Ajusta RCU/WCU
dentro dos limites"] F --> B D -->|"Não"| G["Capacidade mantida"]
  1. O CloudWatch monitora as métricas ConsumedReadCapacityUnits e ConsumedWriteCapacityUnits.
  2. Quando o consumo ultrapassa o threshold configurado, o Application Auto Scaling é acionado.
  3. O Auto Scaling ajusta os valores de RCU/WCU dentro dos limites mínimo e máximo que você definiu.
  4. Requisições que chegam antes do Auto Scaling completar o ajuste podem ser throttladas — o Burst Capacity pode absorver parte desse intervalo.

Criando uma tabela em modo Provisionado com Auto Scaling habilitado via CLI requer dois passos: criar a tabela com capacidade inicial e depois registrar o target de Auto Scaling.

🔽 Clique para expandir — Criar tabela Provisionada e configurar Auto Scaling
# Passo 1: Criar tabela com capacidade provisionada
aws dynamodb create-table \
  --table-name minha-tabela \
  --attribute-definitions AttributeName=pk,AttributeType=S \
  --key-schema AttributeName=pk,KeyType=HASH \
  --billing-mode PROVISIONED \
  --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

# Passo 2: Registrar recurso no Application Auto Scaling (escrita)
aws application-autoscaling register-scalable-target \
  --service-namespace dynamodb \
  --resource-id 'table/minha-tabela' \
  --scalable-dimension 'dynamodb:table:WriteCapacityUnits' \
  --min-capacity 5 \
  --max-capacity 100

# Passo 3: Criar política de scaling para escrita
aws application-autoscaling put-scaling-policy \
  --service-namespace dynamodb \
  --resource-id 'table/minha-tabela' \
  --scalable-dimension 'dynamodb:table:WriteCapacityUnits' \
  --policy-name 'WriteAutoScalingPolicy' \
  --policy-type 'TargetTrackingScaling' \
  --target-tracking-scaling-policy-configuration \
    'TargetValue=70.0,PredefinedMetricSpecification={PredefinedMetricType=DynamoDBWriteCapacityUtilization}'

Regras de Troca de Modo — Leia Antes de Migrar

Este é o ponto onde mais engenheiros se surpreendem. A regra geral é: você pode trocar o modo de capacidade de uma tabela uma vez a cada 24 horas. Existe uma exceção importante documentada pela AWS:

Se você migrar uma tabela de Provisionado para On-Demand, é permitido voltar para o modo Provisionado dentro do mesmo período de 24 horas. Ou seja, essa transição específica (Provisionado → On-Demand → Provisionado) pode acontecer sem aguardar 24 horas completas entre as trocas.

Para qualquer outra sequência de trocas, o intervalo mínimo de 24 horas entre mudanças se aplica normalmente.

stateDiagram-v2 [*] --> Provisionado Provisionado --> OnDemand : Troca permitida OnDemand --> Provisionado : Reversão permitida dentro das 24h OnDemand --> Provisionado : Ou após 24h da última troca Provisionado --> OnDemand : Próxima troca após 24h
  1. Trocar de Provisionado para On-Demand é permitido a qualquer momento (respeitando o limite de uma troca por 24h).
  2. Após essa troca, você pode reverter para Provisionado dentro das mesmas 24 horas — essa é a exceção documentada.
  3. Qualquer outra sequência de trocas exige aguardar 24 horas desde a última mudança.
  4. O status UPDATING da tabela deve ser aguardado antes de realizar qualquer outra operação de configuração.

Migrando uma tabela existente para On-Demand:

aws dynamodb update-table \
  --table-name minha-tabela \
  --billing-mode PAY_PER_REQUEST

Verificando quando a última troca de modo ocorreu:

aws dynamodb describe-table \
  --table-name minha-tabela \
  --query 'Table.BillingModeSummary.LastUpdateToPayPerRequestDateTime'

Diagnóstico de Throttling — O Padrão de Erro que Engana

Aqui está um padrão que aparece com frequência em produção: a aplicação começa a retornar erros intermitentes, os logs mostram timeouts, e o primeiro instinto é olhar para a camada de rede ou para o código. O DynamoDB está sendo ignorado porque 'a tabela está em On-Demand, não pode ser throttling'.

Errado. Tabelas On-Demand também podem ser throttladas — especialmente se o tráfego aumentar mais rápido do que o DynamoDB consegue escalar a partir do pico histórico da tabela. O sintoma é idêntico ao throttling em modo Provisionado.

O diagnóstico correto começa aqui:

# Verificar eventos de throttling nos últimos 60 minutos
aws cloudwatch get-metric-statistics \
  --namespace AWS/DynamoDB \
  --metric-name WriteThrottleEvents \
  --dimensions Name=TableName,Value=minha-tabela \
  --start-time $(date -u -d '60 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Sum
# Verificar também throttling de leitura
aws cloudwatch get-metric-statistics \
  --namespace AWS/DynamoDB \
  --metric-name ReadThrottleEvents \
  --dimensions Name=TableName,Value=minha-tabela \
  --start-time $(date -u -d '60 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Sum

Se os eventos de throttling confirmarem o problema em uma tabela On-Demand com tráfego crescente, a solução mais rápida é migrar temporariamente para Provisionado com capacidade alta e Auto Scaling configurado — ou aguardar o DynamoDB ajustar sua capacidade interna ao novo patamar de tráfego.

Throttling em On-Demand com tráfego crescente não é um bug — é o sistema sinalizando que o pico histórico foi ultrapassado abruptamente.

IAM Mínimo para Operações de Configuração de Capacidade

Para executar os comandos de troca de modo e configuração de Auto Scaling, a role ou usuário precisa das seguintes permissões:

🔽 Clique para expandir — Política IAM mínima
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DynamoDBCapacityManagement",
      "Effect": "Allow",
      "Action": [
        "dynamodb:UpdateTable",
        "dynamodb:DescribeTable"
      ],
      "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/minha-tabela"
    },
    {
      "Sid": "AutoScalingManagement",
      "Effect": "Allow",
      "Action": [
        "application-autoscaling:RegisterScalableTarget",
        "application-autoscaling:PutScalingPolicy",
        "application-autoscaling:DescribeScalableTargets",
        "application-autoscaling:DescribeScalingPolicies"
      ],
      "Resource": "*"
    },
    {
      "Sid": "CloudWatchMetrics",
      "Effect": "Allow",
      "Action": [
        "cloudwatch:GetMetricStatistics"
      ],
      "Resource": "*"
    }
  ]
}

Note que application-autoscaling e cloudwatch requerem "Resource": "*" para as ações de leitura e registro — verifique o Service Authorization Reference da AWS para confirmar o suporte a resource-level permissions para cada ação específica antes de restringir.

Como Escolher o Modo de Capacidade DynamoDB: Guia de Decisão

graph TD A["Tráfego conhecido
e estável?"] -->|"Sim"| B["Provisionado
+ Auto Scaling"] A -->|"Não"| C["On-Demand"] C --> D["Coletar métricas
2-4 semanas"] D --> E{"Padrão
consistente?"} E -->|"Sim"| F["Migrar para
Provisionado"] E -->|"Não / Picos
esporádicos"| G["Manter
On-Demand"]
  1. Se o tráfego é completamente desconhecido, comece com On-Demand — elimina o risco de throttling enquanto você coleta dados reais.
  2. Após algumas semanas de produção, analise o padrão de consumo no CloudWatch. Se o tráfego for consistente, a migração para Provisionado com Auto Scaling reduz o custo.
  3. Workloads com picos muito esporádicos (ex: processamento batch semanal) frequentemente ficam mais baratos em On-Demand mesmo a longo prazo.
  4. Ambientes de desenvolvimento e staging quase sempre devem usar On-Demand — o tráfego é irregular e o custo absoluto é baixo.

Próximos Passos e Conclusão sobre Modos de Capacidade DynamoDB

A escolha entre On-Demand e Provisionado não é permanente — é uma decisão que deve evoluir com o conhecimento do seu padrão de tráfego. Comece com On-Demand se há incerteza, instrumente o CloudWatch desde o primeiro dia, e reavalie após 2-4 semanas de dados reais. A migração é simples; o custo de throttling em produção não é.

Para aprofundar:

Glossário

TermoDefinição
RCU (Read Capacity Unit)Unidade que representa uma leitura fortemente consistente de até 4 KB, ou duas leituras eventualmente consistentes de até 4 KB cada.
WCU (Write Capacity Unit)Unidade que representa uma escrita de até 1 KB em uma tabela DynamoDB.
ThrottlingRejeição de requisições pelo DynamoDB quando o consumo excede a capacidade disponível, retornando erro de throughput excedido.
Burst CapacityCapacidade acumulada de tokens não utilizados no modo Provisionado, disponível para absorver picos temporários. Não é garantida e não substitui provisionamento adequado.
Auto ScalingIntegração entre DynamoDB e Application Auto Scaling que ajusta automaticamente RCU/WCU dentro de limites configurados com base em métricas de utilização.

Comentários

Postagens mais visitadas deste blog

EC2 SSH Connection Timeout: Quais Regras do Security Group Verificar

EC2 Sem Acesso à Internet em VPC Customizada: Como Configurar Internet Gateway e Route Table

S3 Access Denied: Por que 'Bloquear Acesso Público' impede seu objeto mesmo após torná-lo público