AWS Builder Center
Como escolher os serviços certos na AWS: guia prático para arquitetar soluções eficientes

Como escolher os serviços certos na AWS: guia prático para arquitetar soluções eficientes

Aprenda a selecionar os serviços ideais com base em requisitos reais — com exemplos de código, comparações e padrões de arquitetura prontos para aplicar.

Senior Software Engineer .NET/AWS

O Problema Real

A AWS tem mais de 200 serviços. Cada um foi criado para resolver um problema específico. O segredo do arquiteto sênior não é conhecer todos — é saber qual ferramenta usar em qual contexto, e principalmente, quando não usar uma ferramenta.
Alguns números que mostram o impacto de escolhas erradas:
DadoImpacto
47% dos custos AWS são desperdícioOver-provisioning e serviço errado
3x mais caro ao escolher erradoEx: EC2 para workload event-driven
68% de over-engineering em startupsKubernetes para 100 req/dia
⚠️ O erro mais comum: escolher serviços pelo hype, não pelo problema. EC2 não é "legado" — é a escolha certa em dezenas de casos. Lambda não é sempre mais barato.

Caso Real: De $4.200 para $310 por mês

Antes de entrar no framework, deixa eu te contar o que motivou este artigo.
Uma startup de e-commerce chegou até mim com uma fatura AWS de $4.200/mês para um sistema que processava ~800 pedidos por dia. O stack deles:
  • 3x EC2 m5.xlarge rodando 24/7 para processar pedidos
  • RDS db.r5.large Multi-AZ
  • ElastiCache para sessões
  • 2x NAT Gateway
O problema? O processamento de pedidos era completamente event-driven. Cada pedido disparava uma série de etapas: validação de estoque, cobrança, notificação, atualização de relatório. O pico era entre 19h e 22h. Das 00h às 10h, as instâncias EC2 ficavam com 3% de CPU.
Após a migração para o padrão correto:
  • EC2 substituído por Lambda + SQS para processamento
  • RDS mantido (queries ad-hoc de relatório justificavam)
  • ElastiCache removido (DynamoDB para sessões)
  • NAT Gateway otimizado com VPC Endpoints
Resultado: $310/mês. Redução de 92,6% na fatura.
O código não mudou quase nada. O que mudou foi a escolha da ferramenta para o problema certo.

Anti-Patterns Famosos (e Caros)

Esses são os erros que eu vejo repetidamente em code reviews e arquiteturas:

❌ Anti-Pattern 1: Kubernetes para tudo

1
2
3
4
5
6
Situação real: startup com 200 usuários ativos, 50 req/min no pico.
Decisão: EKS com 3 nós m5.large "para escalar no futuro".
Custo: ~$450/mês só em infraestrutura + 40h/mês de ops.

Solução correta: ECS/Fargate ou App Runner.
Custo real: ~$60/mês, zero ops.
Por que acontece: o time ouviu que "Kubernetes é o padrão do mercado" e implementou sem avaliar o problema real.

❌ Anti-Pattern 2: Lambda para tudo serverless

1
2
3
4
5
6
7
8
Situação real: API de dashboard com relatórios complexos,
queries que levam 8-12 segundos, 5.000 usuários simultâneos.
Decisão: Lambda + API Gateway "porque serverless é moderno".

Problema: cold starts de 800ms + timeout de API Gateway (29s)
+ custo de 5.000 execuções simultâneas de 12s = conta salgada.

Solução correta: ECS/Fargate com auto-scaling.

❌ Anti-Pattern 3: DynamoDB sem design de tabela

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ❌ Como NÃO fazer — design relacional em DynamoDB
const getOrdersForUser = async (userId) => {
// Scan é O(n) — varre a tabela inteira
return await client.send(new ScanCommand({
TableName: "orders",
FilterExpression: "userId = :uid",
ExpressionAttributeValues: { ":uid": { S: userId } }
}));
// Com 10 milhões de itens: latência de 30s+ e custo absurdo
};

// ✅ Como fazer — acesso por chave
const getOrdersForUser = async (userId) => {
return await client.send(new QueryCommand({
TableName: "orders",
KeyConditionExpression: "PK = :pk",
ExpressionAttributeValues: { ":pk": { S: `USER#${userId}` } }
// Latência: < 5ms independente do tamanho da tabela
}));
};

❌ Anti-Pattern 4: RDS para tudo que é SQL

1
2
3
4
5
6
7
8
9
Situação: sistema de métricas de aplicação, 50 milhões de
eventos/dia, queries sempre por range de tempo + serviço.
Decisão: RDS PostgreSQL "porque a equipe conhece SQL".

Problema: índices de 200GB, queries de relatório travando
a instância, $800/mês em instância r5.2xlarge.

Solução correta: Amazon Timestream ou Redshift Serverless
para analytics, RDS apenas para dados transacionais.

Framework de Decisão: 4 Eixos

Antes de escolher qualquer serviço, avalie seu workload em quatro eixos:
  1. Custo — fixo vs variável, ocioso vs sob demanda
  2. Complexidade operacional — quanto você quer gerenciar
  3. Flexibilidade — quanto controle você precisa
  4. Escala — previsível, imprevisível ou zero-to-hero

Guia de Decisão: Compute

Use este fluxo para escolher entre os principais serviços de computação:
1
2
3
4
5
6
7
8
9
Seu workload é event-driven ou tem tráfego contínuo?
│
├── Event-driven / esporádico
│ ├── Stateless + execução < 15min → Lambda ✅
│ └── Stateful / longa duração → ECS/Fargate ✅
│
└── Tráfego contínuo
├── Precisa customizar SO/kernel? → EC2 ✅
└── Só a aplicação importa → ECS/Fargate ✅

Comparação de Serviços

Compute

ServiçoCustoFlexibilidadeComplexidade OpsMelhor Para
EC2$$$⭐⭐⭐⭐⭐AltaControle total, SO customizado
Lambda$⭐⭐⭐BaixaEventos, webhooks, funções curtas
ECS/Fargate$$⭐⭐⭐⭐MédiaMicrosserviços, containers
App Runner$$⭐⭐Muito BaixaAPIs simples, deploy rápido

Database

ServiçoCustoFlexibilidadeComplexidade OpsMelhor Para
RDS$$⭐⭐⭐⭐MédiaSQL, queries ad-hoc, relatórios
DynamoDB$⭐⭐BaixaEscala massiva, padrão fixo de acesso
Aurora Serverless$$⭐⭐⭐⭐BaixaSQL com escala automática
ElastiCache$$⭐⭐⭐MédiaCache, sessões, leaderboards

Storage & Messaging

ServiçoCustoMelhor Para
S3$Arquivos, backups, static hosting
SQS$Filas, desacoplamento, retry automático
EventBridge$Eventos entre serviços, regras complexas
SNS$Fan-out, notificações, pub/sub

3 Padrões de Arquitetura com Trade-offs Reais

Padrão 1: Web App Tradicional

Stack: Route 53 → CloudFront → ALB → EC2/ECS → RDS → ElastiCache
Custo médio: ~$300–800/mês
✅ Vantagens:
  • Controle total sobre cada camada
  • Debugging familiar e direto
  • Latência previsível
❌ Limitações:
  • Custo fixo mesmo com baixo tráfego
  • Scaling requer configuração manual
  • Over-provisioning é comum
Use quando: aplicação com tráfego previsível e time com experiência em ops tradicional.

Padrão 2: Serverless Moderno

Stack: CloudFront → API Gateway → Lambda → DynamoDB → S3
Custo médio: ~$10–150/mês
✅ Vantagens:
  • Zero custo quando ocioso
  • Auto-scale de 0 a milhões de requisições
  • Zero gerenciamento de infraestrutura
❌ Limitações:
  • Cold starts (50–500ms na primeira invocação)
  • Limite de 15 minutos por execução
  • Vendor lock-in mais acentuado
Use quando: startup, MVP, workload imprevisível ou time pequeno sem ops dedicado.

Padrão 3: Event-Driven

Stack: EventBridge → SQS/SNS → Lambda → Step Functions → DynamoDB
Custo médio: ~$50–300/mês
✅ Vantagens:
  • Alta resiliência (falha de um serviço não derruba os outros)
  • Serviços totalmente desacoplados
  • Cada componente escala de forma independente
❌ Limitações:
  • Debugging distribuído é complexo
  • Eventual consistency exige cuidado no design
  • Curva de aprendizado acentuada
Use quando: sistemas distribuídos, múltiplos times, domínios de negócio separados.

Código Real, Comentado

Lambda: quando usar

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Lambda: ideal para processamento de eventos stateless
exports.handler = async (event) => {
// Escala de 0 a ∞ automaticamente
const records = event.Records.map(async (record) => {
const body = JSON.parse(record.body);

// Lógica de negócio aqui
await processOrder(body);

return { status: 'processed', id: body.orderId };
});

return await Promise.all(records);
};

// ✅ Use Lambda quando:
// - Execução < 15 minutos
// - Stateless e orientado a eventos
// - Volume imprevisível (0 a milhões/dia)
// - Quer pagar apenas pelo uso real

// ❌ Evite Lambda quando:
// - Processo precisa de mais de 15 minutos
// - Aplicação mantém estado em memória
// - Workload contínuo e previsível (EC2 Reserved é mais barato)

EC2: quando usar

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
# EC2 user-data: configuração que só EC2 permite

# Instale dependências específicas de SO
apt-get update && apt-get install -y \
custom-driver \
legacy-library==2.1.0

# Configure parâmetros do kernel
sysctl -w net.core.somaxconn=65535
sysctl -w vm.swappiness=10

# Deploy da aplicação
docker pull myapp:latest
docker run -d --restart=always \
--memory="4g" --cpus="2" \
-p 8080:8080 myapp:latest

# ✅ Use EC2 quando:
# - Precisa customizar SO ou kernel
# - Dependências não-containerizáveis
# - Licença de software por socket/core
# - Tráfego contínuo alto (Reserved Instances = 40-60% de desconto)

DynamoDB: design correto

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// DynamoDB: a chave está no design da tabela
const { DynamoDBClient, PutItemCommand, QueryCommand } =
require("@aws-sdk/client-dynamodb");

// ✅ Single Table Design — um único table para toda a aplicação
const TABLE = "ecommerce-prod";

async function saveOrder(order) {
await client.send(new PutItemCommand({
TableName: TABLE,
Item: {
PK: { S: `USER#${order.userId}` },
SK: { S: `ORDER#${order.id}` },
status: { S: order.status },
total: { N: String(order.total) },
GSI1PK: { S: `STATUS#${order.status}` },
GSI1SK: { S: order.createdAt },
}
}));
}

// ✅ Use DynamoDB quando:
// - Escala > 10.000 req/s
// - Padrões de acesso bem definidos e previsíveis
// - Latência single-digit milliseconds é requisito

// ❌ Evite DynamoDB quando:
// - Precisa de queries SQL ad-hoc e relatórios complexos
// - Relações many-to-many não mapeadas previamente
// - Time não tem experiência com NoSQL design

Checklist do Arquiteto

Use esta lista antes de qualquer decisão de serviço. "Não sei" em qualquer item significa que você precisa investigar antes de escolher.

Requisitos de Negócio

  • Requisitos de Negócio
  • [ ] Qual é o SLA exigido? (99.9%, 99.99%?)
  • [ ] Qual o volume estimado? (req/s, GB/dia)
  • [ ] Há sazonalidade ou picos previsíveis?
  • [ ] Qual o orçamento mensal máximo?

Padrões de Acesso

  • [ ] O workload é contínuo ou event-driven?
  • [ ] Há estado que precisa persistir entre execuções?
  • [ ] Os acessos ao banco seguem padrão fixo ou são ad-hoc?
  • [ ] Qual a latência máxima aceitável?

Operação e Manutenção

  • [ ] Quem vai operar isso em produção?
  • [ ] Há necessidade de customização de SO ou runtime?
  • [ ] Qual a estratégia de disaster recovery?
  • [ ] Como será feito o observability (logs, métricas, traces)?
💡 Regra de ouro: Se você não sabe responder pelo menos 80% dessas perguntas, a escolha de serviço é prematura. Arquitetura boa começa com requisitos bem entendidos.

Perguntas Frequentes

"Devo sempre preferir serverless para reduzir custos?"
Não. Lambda com tráfego contínuo e alto volume pode custar 3x mais do que uma EC2 Reserved. Serverless é mais barato quando o workload é imprevisível ou tem muito tempo ocioso. Para cargas constantes acima de ~10 req/s o dia todo, EC2 Reserved ou Savings Plans geralmente ganham na conta.

"DynamoDB ou RDS: qual escolher para uma nova aplicação?"
Depende dos seus padrões de acesso. Se você sabe exatamente como vai consultar os dados antes de escrever o código, DynamoDB é uma excelente escolha. Se você ainda está descobrindo o modelo de negócio e precisa de flexibilidade para queries, RDS é mais seguro. Startups em fase inicial geralmente se saem melhor com RDS — o custo de refatorar um DynamoDB mal modelado é alto.

"ECS ou EKS para containers?"
EKS faz sentido quando você já tem expertise em Kubernetes, tem múltiplos clusters para gerenciar ou precisa de portabilidade entre clouds. Para a maioria dos casos, ECS/Fargate entrega 90% dos benefícios com 30% da complexidade operacional. Comece com ECS e migre para EKS se e quando realmente precisar.

"Como justificar a migração para o time de negócio?"
Use números. Calcule o custo atual, estime o custo da arquitetura proposta com a AWS Pricing Calculator , e apresente o ROI. Uma migração que economiza $2.000/mês se paga em 2-3 sprints de trabalho. Fale em dinheiro, não em tecnologia.

"Qual o maior erro que times cometem na AWS?"
Não ativar o AWS Cost Explorer com alertas de budget. Descobrir uma fatura de $15.000 no final do mês porque alguém deixou uma instância GPU rodando por engano é mais comum do que parece. Configure alertas em 80% e 100% do budget desde o dia um.

Resumo: Quando Usar Cada Serviço

SituaçãoServiço Recomendado
Função simples acionada por eventoLambda
API com tráfego previsível e alto volumeEC2 (Reserved)
Microsserviços em containersECS/Fargate
Banco de dados relacional gerenciadoRDS ou Aurora
Escala massiva com padrão de acesso fixoDynamoDB
Arquivos, imagens, backupsS3
Desacoplar serviços com retry automáticoSQS
Roteamento de eventos entre serviçosEventBridge
Métricas e séries temporaisTimestream
Analytics em escalaRedshift Serverless
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article