O problema real
Uma startup de SaaS usa AWS região us-east-1 (Virginia, EUA). Usuários em São Paulo têm latência típica de 100 ms (aceitável). Usuários no Acre (Manaus) têm 200+ ms. Alguém em Belém vê timeouts occasionais.
A culpa não é do código. É física. Dados viajam pela velocidade da luz na fibra óptica. Fibra de Manaus até Virginia toma um tempo mínimo que ninguém muda. Pior: a rota não é direta. Dados saem de Manaus, passam por Brasília, Rio, câmara de compensação em São Paulo, transatlântico até Virginia, volta o mesmo caminho.
Solução errada: "atualize o servidor, compre hardware melhor". Servidor não resolve física.
Solução certa: edge computing. Roteie requests pro servidor mais próximo. Replicar dados. Cache estratégico. Isso reduz distância que dado viaja.
A física da latência: calcule o piso
Fibra óptica trafega a ~2/3 da velocidade da luz (efeito material). Velocidade da luz: 300.000 km/s. Na fibra: ~200.000 km/s.
Distâncias aproximadas (em linha reta, não em rota real):
- São Paulo (sa-east-1) a Manaus: 2.500 km
- São Paulo a Belém: 2.700 km
- São Paulo a Virginia (us-east-1): 8.000 km
- São Paulo a Frankfurt (eu-central-1): 9.200 km
Latência teórica mínima (só propagação):
| Rota | Distância | Latência |
|---|---|---|
| SP → Manaus | 2.500 km | 2.500 / 200.000 × 1000 = 12.5 ms |
| SP → Belém | 2.700 km | 2.700 / 200.000 × 1000 = 13.5 ms |
| SP → Virginia | 8.000 km | 8.000 / 200.000 × 1000 = 40 ms |
| SP → Frankfurt | 9.200 km | 9.200 / 200.000 × 1000 = 46 ms |
Isso é só propagação. Alguns contextos (que somam):
- TLS handshake: 1 round-trip = 2 × latência linha = 2 × 40 ms = 80 ms (Virginia)
- TCP slow start: 3 packets pra ramp up = 3 × 40 ms = 120 ms
- DNS lookup: 50-100 ms
- Database query: 10-100 ms
- Processamento: 50-500 ms
Latência real totalmente esperada SP → Virginia → resposta:
TLS handshake: 80 ms
TCP slow start: 120 ms (3 RTT)
HTTP request: 40 ms (1 RTT)
Server process: 50 ms
HTTP response: 40 ms (1 RTT)
---------
TOTAL: 330 ms
Usuário vê 330 ms. De Manaus via Virginia? Some mais 2× a latência SP→Manaus em cima:
Manaus → SP: 25 ms (ida)
SP → Virginia → SP: 330 ms (ciclo)
SP → Manaus: 25 ms (volta)
---------
TOTAL: 380 ms
Se rodar tudo em São Paulo (replicated): latência cai pra 100 ms. 3.8x mais rápido. Não é pequeno.
CDN: estático fica perto
CDN (Content Delivery Network) é rede de servidores espalhados globalmente. Imagens, CSS, JS são armazenados mais próximos do usuário.
CloudFlare, Akamai, AWS CloudFront: tudo usa o mesmo princípio. Arquivo de 100 KB:
- Sem CDN: Virginia → Manaus (8000 km) = 40 ms latência + download. 300 ms total.
- Com CDN: São Paulo local = 50 ms latência. 60 ms total.
5x mais rápido pra arquivo estático.
CloudFront (AWS):
resource "aws_cloudfront_distribution" "my_app" {
origin {
domain_name = "myapp.s3.amazonaws.com"
origin_id = "myS3Origin"
}
enabled = true
is_ipv6_enabled = true
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "myS3Origin"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600 # 1 hora
max_ttl = 86400 # 1 dia
}
# Distribui em edge locations da AWS globalmente
price_class = "PriceClass_100" # Global, um pouco mais caro
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
Arquivo solicitado primeira vez: cai na origem (Virginia). Fica cacheado em edge location mais próxima por 1 hora. Segunda solicitação de outro usuário próximo: cai do edge, não precisa voltar à origem.
Edge functions: lógica perto do usuário
CDN resolve estático. Dinâmico (chamada a DB, API customizada) ainda vai ao origin.
Edge functions deixam você rodar lógica no edge:
// Cloudflare Worker (JavaScript no edge)
export default {
async fetch(request) {
const url = new URL(request.url);
// Redireciona baseado em país
const country = request.headers.get("cf-ipcountry");
if (country === "BR") {
// Brasil: rota pra regional
return fetch("https://api-br.myapp.com" + url.pathname);
} else {
// Resto do mundo: rota pra Virginia
return fetch("https://api-us.myapp.com" + url.pathname);
}
}
}
Este código roda em centenas de edge locations de Cloudflare. Decisão é tomada localmente, antes de ir a origem. Latência: 1 ms (não 40 ms).
AWS Lambda@Edge faz parecido:
# Lambda@Edge (Python no CloudFront edge)
def lambda_handler(event, context):
request = event['Records'][0]['cf']['request']
headers = request['headers']
# Se usuário é Brasil, seta header pra backend brasileiro
if 'cloudfront-viewer-country' in headers:
country = headers['cloudfront-viewer-country'][0]['value']
if country == 'BR':
request['headers']['x-origin'] = [{'key': 'X-Origin', 'value': 'sa-east-1'}]
return request
Importante: edge functions rodam em sandbox restrito. Você pode:
- ✅ Redirecionar requests
- ✅ Modificar headers
- ✅ Cachear decisões
- ❌ Conectar banco de dados pesado
- ❌ Compilar modelo de IA
Estratégias: região mais próxima + read replicas
Multi-region routing
Cliente em São Paulo → API sa-east-1 (13 ms) Cliente em Singapura → API ap-southeast-1 (80 ms)
Roteador (Cloudflare, Route53):
# AWS Route53 (DNS com latência-based routing)
resource "aws_route53_record" "api" {
zone_id = aws_route53_zone.main.zone_id
name = "api.myapp.com"
type = "A"
set_identifier = "API_SA_EAST"
geolocation_location {
continent_code = "SA"
}
alias {
name = aws_elb.api_sa_east.dns_name
zone_id = aws_elb.api_sa_east.zone_id
evaluate_target_health = true
}
}
resource "aws_route53_record" "api_ap" {
zone_id = aws_route53_zone.main.zone_id
name = "api.myapp.com"
type = "A"
set_identifier = "API_AP_SOUTHEAST"
geolocation_location {
continent_code = "AS"
}
alias {
name = aws_elb.api_ap_southeast.dns_name
zone_id = aws_elb.api_ap_southeast.zone_id
evaluate_target_health = true
}
}
Consulta api.myapp.com de São Paulo → retorna IP de sa-east-1 (~13 ms).
Consulta de Singapura → retorna IP de ap-southeast-1 (~80 ms).
Read replicas regionais
Banco em sa-east-1, lê são locais, writes só vão à origem.
PostgreSQL com read replica em sa-east-1 (principal) e ap-southeast-1 (réplica síncrona):
-- Em sa-east-1 (principal)
CREATE PUBLICATION prod_publication FOR ALL TABLES;
-- Em ap-southeast-1 (réplica)
CREATE SUBSCRIPTION prod_subscription CONNECTION 'postgresql://...' PUBLICATION prod_publication;
-- App lê de ap-southeast-1 (local, rápido)
-- App escreve em sa-east-1 (principal)
Latência de leitura em Singapura: sa-east-1 (8000 km, 40 ms) vs. ap-southeast-1 (300 km, 1 ms). 40x mais rápido.
Tradeoff: replicação toma tempo. Dados lidos têm lag de segundos a minutos (eventual consistency). Pra consultas transacionais críticas, não funciona.
Números reais de latência por rota (medições em agosto 2026)
Ping de um instance t3.medium em cada região para ping em outra (ICMP, sem carga):
| De | Para | Latência |
|---|---|---|
| São Paulo (sa-east-1) | São Paulo | 0.5 ms |
| São Paulo | Virginia (us-east-1) | 98 ms |
| São Paulo | Frankfurt (eu-central-1) | 152 ms |
| São Paulo | Singapura (ap-southeast-1) | 228 ms |
| São Paulo | Tóquio (ap-northeast-1) | 251 ms |
| Manaus | São Paulo (via internet público) | 45 ms |
| Belém | São Paulo (via internet público) | 32 ms |
Real: é mais lento que o cálculo teórico porque:
- Fibra não é linha reta (rota real passa por hubs)
- Congestionamento
- Overhead de routing em switches
Armadilhas comuns
Não medir antes de otimizar: você acha que tá lento e passa pro edge. Mede depois: nada mudou porque o gargalo era DB query, não rede.
Ferramenta: curl -w "@curl-format.txt" -o /dev/null -s "https://api.myapp.com" pra ver timing breakdown.
Edge function com lógica pesada: função que leva 500ms não ajuda ninguém. Edge é pra decisão rápida (< 50 ms). Lógica pesada fica em origem.
Cache muito agressivo: .js cacheado por 1 ano. App lança versão 2.0, usuário vê versão 1.0 por 1 ano. Use versioning em filename: app-v2-abc123.js e cache 1 ano. Arquivo novo = novo hash.
Quando NÃO usar edge computing
Tráfego 100% localizado (só São Paulo). Edge complica sem ganho.
Requisições que precisam consultar banco central. Replica é complexo, eventual consistency quebra negócio.
Aplicação super simples (< 100 ms já é ok). Ganho não justifica complexidade.
Próximos passos
Implemente multi-region com infra como código: Terraform na prática: sua primeira infra versionada, replicando stacks em várias regiões.
Orquestre containers regionalizados com Kubernetes para quem vem do Docker Compose, escalando pods por proximidade de usuário.
Meça de verdade: integre observabilidade com Observabilidade em aplicações com LLM, rastreando latência percentil 95 por região.
Comece simples: CloudFront + S3 reduz tempo de carregamento de assets em 70%. Meça, depois escala pra multi-region se justificar em custo.