Fundamentos9 min

Microserviços e Performance: o custo da distribuição

Microserviços trazem benefícios organizacionais, mas também desafios de performance. Entenda os trade-offs.

Microserviços se tornaram o padrão para sistemas modernos. Eles oferecem benefícios reais: independência de deploy, escalabilidade granular, autonomia de times. Mas esses benefícios vêm com custos de performance que muitas vezes são subestimados.

Este artigo explora os desafios de performance em arquiteturas de microserviços e estratégias para mitigá-los.

Microserviços não são grátis. Você troca complexidade interna por complexidade de rede.

O Custo da Distribuição

De função para rede

Monolito:
userService.getUser(id)  → 0.001ms (chamada de função)

Microserviço:
HTTP GET /users/{id}     → 1-5ms (chamada de rede)

Diferença de 1.000x a 5.000x por chamada.

Latência acumulada

Monolito:
Requisição → Processo interno → Resposta
            2ms total

Microserviços:
Requisição → API Gateway → Auth → User Service → Order Service → Resposta
            1ms        2ms    3ms      4ms           3ms
            = 13ms total

Falhas em cascata

Em um monolito, uma falha geralmente afeta apenas parte do sistema. Em microserviços, uma falha pode propagar:

Payment Service lento
    ↓
Order Service timeout esperando
    ↓
API Gateway acumula conexões
    ↓
Todos os endpoints ficam lentos
    ↓
Sistema inteiro degradado

Problemas Comuns

1. Over-fetching e Under-fetching

Over-fetching: buscar mais dados que necessário

// Cliente precisa apenas de nome
GET /users/123
{
    "id": 123,
    "name": "João",
    "email": "...",
    "address": {...},
    "preferences": {...},
    "history": [...]  // 50KB de dados desnecessários
}

Under-fetching: precisar de múltiplas chamadas

// Para montar uma página
const user = await getUser(id);           // Chamada 1
const orders = await getOrders(user.id);  // Chamada 2
const products = await getProducts(orders.map(o => o.productId));  // Chamada 3

2. Distributed Monolith

Microserviços fortemente acoplados que precisam ser deployados juntos.

Serviço A muda interface
    ↓
Serviço B precisa atualizar
    ↓
Serviço C depende de B
    ↓
Deploy coordenado de A, B, C
    ↓
Pior dos dois mundos

3. Overhead de serialização

Objeto em memória: acesso direto
Objeto via rede: serializar → transmitir → deserializar

JSON grande:
Serialização: 5ms
Transmissão: 10ms
Deserialização: 5ms
= 20ms overhead

4. Service mesh overhead

Sidecars adicionam latência a cada chamada.

App → Sidecar → Rede → Sidecar → App
     0.5ms            0.5ms

+1ms por hop (mínimo)

Padrões para Melhor Performance

1. API Composition

Agregue dados em um único endpoint.

// Em vez de 3 chamadas do cliente
GET /users/123
GET /orders?userId=123
GET /products?ids=1,2,3

// Uma chamada para um aggregator
GET /user-dashboard/123
{
    "user": {...},
    "orders": [...],
    "products": [...]
}

2. GraphQL

Cliente especifica exatamente o que precisa.

query {
    user(id: 123) {
        name
        orders {
            id
            total
        }
    }
}

3. CQRS (Command Query Responsibility Segregation)

Modelos separados para leitura e escrita.

Escrita: microserviços normalizados
Leitura: views desnormalizadas otimizadas

Usuário pede dashboard → View materializada → Resposta rápida

4. Event-Driven Architecture

Comunique via eventos em vez de chamadas síncronas.

// Síncrono
orderService.createOrder(order)
    → inventoryService.reserve(items)    // Espera
    → paymentService.charge(amount)      // Espera
    → notificationService.send(email)    // Espera

// Assíncrono
orderService.createOrder(order)
    → publish("OrderCreated")

// Outros serviços reagem aos eventos
// Sem espera, sem cascata

5. Cache entre serviços

// Serviço A cache dados do Serviço B
async function getUser(id) {
    const cached = await redis.get(`user:${id}`);
    if (cached) return JSON.parse(cached);

    const user = await userService.get(id);
    await redis.setex(`user:${id}`, 300, JSON.stringify(user));
    return user;
}

6. Bulk APIs

Suporte a operações em batch.

// Ineficiente
GET /products/1
GET /products/2
GET /products/3

// Eficiente
GET /products?ids=1,2,3
// ou
POST /products/batch
{"ids": [1, 2, 3]}

Observabilidade Distribuída

Distributed tracing

Essencial para entender latência end-to-end.

Request ID: abc-123
├── API Gateway (2ms)
├── Auth Service (5ms)
├── User Service (15ms)  ← Gargalo!
│   └── Database (12ms)
└── Response (total: 22ms)

Métricas por serviço

Métrica Por que importa
Latência por endpoint Identificar endpoints lentos
Error rate por dependência Identificar serviços problemáticos
Request rate Volume de comunicação
Timeout rate Problemas de integração

Logs correlacionados

Mesmo request ID em todos os serviços.

[abc-123] API Gateway: Received request
[abc-123] Auth: Token validated
[abc-123] User: Fetching user 456
[abc-123] User: Database query took 12ms

Quando NÃO Usar Microserviços

Microserviços não são sempre a resposta.

Evite quando:

  • Time pequeno (< 10 pessoas)
  • Domínio não é bem entendido
  • Latência é crítica e cada ms importa
  • Não tem infraestrutura de observabilidade
  • Não tem capacidade de operar sistemas distribuídos

O monolito bem estruturado pode ter:

  • Deploy simples
  • Debugging fácil
  • Latência mínima
  • Transações ACID

Conclusão

Microserviços são um trade-off:

Ganho Custo
Independência de deploy Complexidade operacional
Escalabilidade granular Latência de rede
Autonomia de times Observabilidade mais difícil
Resiliência (se bem feito) Falhas em cascata (se mal feito)

Para performance em microserviços:

  1. Minimize chamadas — agregadores, batch, cache
  2. Use async quando possível — eventos, filas
  3. Invista em observabilidade — tracing, métricas, logs
  4. Design para falha — timeouts, circuit breakers, fallbacks
  5. Questione a necessidade — nem tudo precisa ser microserviço

Microserviços são uma decisão organizacional com consequências técnicas. Entenda o custo antes de pagar.

microserviçosarquiteturadistribuídoslatência
Compartilhar:
Read in English

Quer entender os limites da sua plataforma?

Entre em contato para uma avaliação de performance.

Fale Conosco