Serverless com AWS Lambda: quando e como usar
Atualizado em Março 2026Serverless é um modelo de computação em nuvem onde o provedor gerência completamente a infraestrutura, é o usuário paga apenas pelo tempo de execução real do código. Na AWS, o serviço central é o AWS Lambda, que executa funções em resposta a eventos como chamadas de API, uploads de arquivos ou mensagens em filas, sem necessidade de provisionar ou gerenciar servidores.
Serverless é um modelo de computação onde o provedor cloud gerência completamente a infraestrutura: provisionamento, scaling, patching e disponibilidade. Você escreve código, faz deploy, e só paga pelo tempo de execução real. Na AWS, o AWS Lambda é o serviço central desse modelo, executando funções em resposta a eventos sem a necessidade de gerenciar servidores.
Neste guia, vamos explorar quando serverless faz sentido, como construir aplicações com Lambda e API Gateway, lidar com cold starts, usar Layers para dependências e deployar com AWS SAM.
Quando usar (e quando NÃO usar) serverless
Serverless não é bala de prata. Entender seus pontos fortes e limitações é essencial para evitar frustrações:
Use serverless quando:
- Workloads event-driven: processamento de uploads S3, mensagens SQS, eventos DynamoDB Streams, webhooks
- APIs com tráfego variável: endpoints que escalam de zero a milhares de requests sem provisioning manual
- Processamento batch leve: ETL de arquivos, transformação de dados, geração de relatórios
- Automação de infraestrutura: rotação de secrets, cleanup de recursos, remediação automática
- MVPs e protótipos: time-to-market rápido sem overhead de infraestrutura
Evite serverless quando:
- Processamento longo (>15 min): Lambda tem limite de 15 minutos de execução
- Latência ultra-baixa exigida: cold starts adicionam latência variável
- Workloads com tráfego constante e alto: containers (ECS/EKS) podem ser mais economicos
- Aplicações stateful: Lambda é stateless por design
Exemplo prático: API REST com Lambda e API Gateway
Vamos construir uma API REST para gerenciar pedidos usando Lambda (Python), API Gateway e DynamoDB:
import json
import boto3
import uuid
from datetime import datetime
from decimal import Decimal
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('pedidos')
# Helper para serializar Decimal do DynamoDB
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return float(obj)
return super().default(obj)
def lambda_handler(event, context):
"""Handler principal que roteia por método HTTP."""
http_method = event['httpMethod']
path = event.get('pathParameters')
try:
if http_method == 'GET' and path and path.get('id'):
return get_pedido(path['id'])
elif http_method == 'GET':
return listar_pedidos()
elif http_method == 'POST':
return criar_pedido(json.loads(event['body']))
elif http_method == 'PUT' and path:
return atualizar_pedido(
path['id'], json.loads(event['body'])
)
elif http_method == 'DELETE' and path:
return deletar_pedido(path['id'])
else:
return response(400, {'error': 'Rota não encontrada'})
except Exception as e:
print(f"Erro: {str(e)}")
return response(500, {'error': 'Erro interno'})
def criar_pedido(body):
"""Cria um novo pedido no DynamoDB."""
pedido = {
'id': str(uuid.uuid4()),
'cliente': body['cliente'],
'itens': body['itens'],
'valor_total': Decimal(str(body['valor_total'])),
'status': 'pendente',
'criado_em': datetime.utcnow().isoformat(),
}
table.put_item(Item=pedido)
return response(201, pedido)
def listar_pedidos():
"""Lista todos os pedidos."""
result = table.scan(Limit=100)
return response(200, result['Items'])
def get_pedido(pedido_id):
"""Busca um pedido por ID."""
result = table.get_item(Key={'id': pedido_id})
if 'Item' not in result:
return response(404, {'error': 'Pedido não encontrado'})
return response(200, result['Item'])
def response(status_code, body):
"""Helper para formatar resposta do API Gateway."""
return {
'statusCode': status_code,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
'body': json.dumps(body, cls=DecimalEncoder),
}
Deploy com AWS SAM
O AWS SAM (Serverless Application Model) simplifica o deploy de aplicações serverless com um template declarativo. Ele abstrai a complexidade do CloudFormation e oferece ferramentas como sam local para testes locais.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: API de Pedidos - Serverless
Globals:
Function:
Runtime: python3.12
Timeout: 30
MemorySize: 256
Tracing: Active # Habilita X-Ray
Environment:
Variables:
TABLE_NAME: !Ref PedidosTable
POWERTOOLS_SERVICE_NAME: pedidos-api
LOG_LEVEL: INFO
Resources:
# API Gateway
PedidosApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
Cors:
AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
AllowHeaders: "'Content-Type,Authorization'"
AllowOrigin: "'*'"
# Lambda Function
PedidosFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
CodeUri: src/
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref PedidosTable
Events:
ListarPedidos:
Type: Api
Properties:
RestApiId: !Ref PedidosApi
Path: /pedidos
Method: GET
CriarPedido:
Type: Api
Properties:
RestApiId: !Ref PedidosApi
Path: /pedidos
Method: POST
GetPedido:
Type: Api
Properties:
RestApiId: !Ref PedidosApi
Path: /pedidos/{id}
Method: GET
AtualizarPedido:
Type: Api
Properties:
RestApiId: !Ref PedidosApi
Path: /pedidos/{id}
Method: PUT
DeletarPedido:
Type: Api
Properties:
RestApiId: !Ref PedidosApi
Path: /pedidos/{id}
Method: DELETE
# DynamoDB Table
PedidosTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: pedidos
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
Outputs:
ApiUrl:
Description: URL da API
Value: !Sub "https://${PedidosApi}.execute-api.${AWS::Region}.amazonaws.com/prod/"
Para fazer deploy, basta executar:
# Build e deploy com SAM
sam build
sam deploy --guided
# Testar localmente antes do deploy
sam local start-api
# A API estará disponível em http://localhost:3000
# Invocar função localmente com evento de teste
sam local invoke PedidosFunction -e events/create.json
Cold starts: entendendo e mitigando
O cold start acontece quando o Lambda precisa provisionar um novo ambiente de execução para sua função. Isso adiciona latência extra (100ms a 10s, dependendo do runtime e dependências) na primeira invocação ou em picos de tráfego.
Estratégias para mitigar cold starts:
- Provisioned Concurrency: mantém N instâncias pré-aquecidas, eliminando cold starts. Ideal para funções de API com requisitos de latência.
- Runtime leve: Python e Node.js têm cold starts muito mais rápidos que Java ou .NET. Considere isso na escolha do runtime.
- Pacote pequeno: minimize o tamanho do deployment package. Use Layers para dependências pesadas.
- Inicialização fora do handler: crie clientes SDK (boto3, DynamoDB client) fora da função handler. Eles são reutilizados entre invocações no mesmo ambiente.
- SnapStart (Java): recurso que cria snapshots do ambiente inicializado, reduzindo cold starts de Java de ~6s para ~200ms.
Lambda Layers: compartilhando dependências
Lambda Layers permitem empacotar bibliotecas, runtimes customizados ou código compartilhado que podem ser reutilizados por múltiplas funções. Isso reduz o tamanho do deployment package e facilita a manutenção de dependências.
Casos de uso comuns para Layers:
- Bibliotecas pesadas (pandas, numpy, Pillow)
- AWS Lambda Powertools (logging, tracing, validation)
- Código compartilhado entre funções (models, utils)
- Certificados e configurações
Arquitetura event-driven com Lambda
O verdadeiro poder do Lambda aparece em arquiteturas event-driven, onde funções são disparadas por eventos de outros serviços AWS:
- S3 + Lambda: processamento de imagens no upload, ETL de arquivos CSV, validação de documentos
- SQS + Lambda: processamento assíncrono de filas com retry automático e dead-letter queue
- DynamoDB Streams + Lambda: reações a mudanças no banco (auditoria, sincronização, notificações)
- EventBridge + Lambda: orquestração de eventos entre serviços e contas AWS
- Kinesis + Lambda: processamento de streaming de dados em tempo real
"Serverless não é sobre não ter servidores, é sobre não pensar em servidores. Quando bem aplicado, libera o time de engenharia para focar 100% na lógica de negócio."
Melhores práticas para Lambda em produção
1. Use AWS Lambda Powertools
O Lambda Powertools é uma biblioteca oficial da AWS que adiciona logging estruturado, tracing com X-Ray, validação de input e idempotência com uma única linha de código. Disponível para Python, TypeScript, Java e .NET.
2. Implemente dead-letter queues
Configure DLQs (SQS ou SNS) para capturar invocações que falharam após todas as tentativas de retry. Isso evita perda de dados e permite investigação posterior.
3. Defina timeouts adequados
Nunca use o timeout máximo de 15 minutos como padrão. Defina um timeout razoável para cada função (ex: 30s para APIs, 5min para processamento batch). Isso evita custos desnecessários em caso de bugs.
4. Monitore com métricas customizadas
Além das métricas padrão (invocações, erros, duração), publique métricas de negócio usando CloudWatch Embedded Metrics Format (EMF) do Lambda Powertools.
5. Gerencie secrets com Secrets Manager
Seguindo os principios de Zero Trust, nunca hardcode credenciais em variáveis de ambiente. Use AWS Secrets Manager com caching no Lambda para buscar secrets de forma segura e eficiente.
Gotchas e armadilhas do Lambda em produção
- Concurrency limits: cada conta AWS tem um limite padrão de 1.000 execuções concorrentes por região (todas as funções somadas). Uma única função com pico de tráfego pode consumir toda a quota e bloquear outras funções. Use Reserved Concurrency para isolar funções críticas e solicite aumento de limite proativamente.
- Timeout do API Gateway: mesmo que sua Lambda tenha timeout de 15 min, o API Gateway tem um limite fixo de 29 segundos. Para processamentos longos, use API Gateway com invocação assíncrona ou Step Functions.
- Tamanho do payload: API Gateway tem limite de 10 MB para payload síncrono. Para uploads grandes, gere pre-signed URLs do S3 e faça upload direto do client.
- Custo de Provisioned Concurrency: manter 10 instâncias pré-aquecidas de uma função com 512 MB custa aproximadamente USD 43/mes. Use somente para funções com requisitos de latencia abaixo de 100ms.
# Verificar concurrency atual e limites
aws lambda get-account-settings --region sa-east-1
# Configurar Reserved Concurrency para função crítica
aws lambda put-function-concurrency \
--function-name api-pagamentos \
--reserved-concurrent-executions 100 \
--region sa-east-1
# Configurar Provisioned Concurrency (elimina cold starts)
aws lambda put-provisioned-concurrency-config \
--function-name api-pagamentos \
--qualifier prod \
--provisioned-concurrent-executions 5 \
--region sa-east-1
# Listar funções com invocações com erro nas últimas 24h
aws cloudwatch get-metric-data --metric-data-queries '[
{
"Id": "errors",
"MetricStat": {
"Metric": {
"Namespace": "AWS/Lambda",
"MetricName": "Errors",
"Dimensions": [{"Name": "FunctionName", "Value": "api-pedidos"}]
},
"Period": 86400,
"Stat": "Sum"
}
}
]' --start-time 2026-03-14T00:00:00Z --end-time 2026-03-15T00:00:00Z \
--region sa-east-1
Na Prática: API serverless para marketplace
Um marketplace de serviços precisava de uma API que escalasse automaticamente de 100 requests/min em dias normais para 5.000 requests/min em campanhas promocionais, sem provisionar infraestrutura manualmente.
- Arquitetura: API Gateway (REST) + Lambda (Python 3.12 com Powertools) + DynamoDB (on-demand) + SQS para processamento assíncrono de pagamentos + EventBridge para notificações.
- Cold start mitigado: Provisioned Concurrency de 5 para a função de checkout (P99 abaixo de 150ms). Demais funções usam Python puro sem dependencias pesadas, com cold start médio de 200ms.
- Custo: no mês normal (2M requests), o custo total foi USD 28 (Lambda USD 4, API Gateway USD 7, DynamoDB USD 12, SQS USD 2, CloudWatch USD 3). O equivalente em ECS Fargate seria aproximadamente USD 180/mes.
Resultado: zero gerenciamento de infraestrutura, scaling automático de 0 a 5.000 req/min sem nenhuma configuração, custo 6x menor que containers para esse padrão de tráfego.
KPIs para o Decisor
- Custo por 1 milhão de requests: custo total (Lambda + API Gateway + DynamoDB) dividido por requests. Target: menos de USD 3 para APIs simples.
- Cold start P99 (ms): latencia do pior 1% das invocações. Target: menos de 500ms sem Provisioned Concurrency, menos de 100ms com.
- Error rate (%): percentual de invocações com erro. Target: abaixo de 0,1% em produção.
- Throttle rate (count/dia): número de invocações rejeitadas por limite de concurrency. Target: zero (ajuste Reserved Concurrency).
- DLQ depth (count): mensagens na dead-letter queue esperando reprocessamento. Target: zero em estado normal, com alarme para acima de 10.
Próximos passos
Se você está começando com serverless, comece com um caso de uso simples: uma função Lambda que processa uploads no S3 ou uma API pequena com API Gateway. À medida que ganha confiança, evolua para arquiteturas event-driven mais complexas com Step Functions, EventBridge e SQS.
Na RFX Tecnologia, por meio da nossa consultoria em nuvem, projetamos e implementamos arquiteturas serverless que escalam automaticamente e custam uma fração de infraestrutura tradicional. De APIs de alta performance a pipelines de processamento de dados, ajudamos empresas a aproveitar o máximo do modelo serverless na AWS. Agende uma consultoria gratuita e descubra como serverless pode acelerar seu projeto.