Fundamentos7 min

Limites Físicos vs Arquiteturais: entendendo barreiras de performance

Alguns limites são da física, outros são escolhas de arquitetura. Entender a diferença é essencial para otimização efetiva.

Quando um sistema não escala mais, a pergunta crucial é: estamos batendo em um limite físico ou arquitetural? Limites físicos requerem mais recursos. Limites arquiteturais requerem redesenho. Confundir os dois leva a investimentos errados.

Você não pode otimizar seu caminho através de um limite físico. Mas pode redesenhar através de um limite arquitetural.

Limites Físicos

O que são

Limites impostos pela física e hardware. Não podem ser superados com software.

Exemplos

1. Velocidade da luz (latência de rede)

São Paulo → Nova York: ~5.500 km
Velocidade da luz em fibra: ~200.000 km/s
Latência mínima teórica: 27.5 ms (ida)
Latência mínima round-trip: 55 ms

→ Nenhum software torna isso mais rápido

2. Largura de banda de disco

SSD NVMe típico: 3.500 MB/s read
Se precisa ler 10 GB: mínimo 2.9 segundos

→ Único caminho: menos dados ou mais discos

3. IOPS de storage

SSD típico: 100.000 IOPS
Se precisa 500.000 IOPS: precisa de 5 SSDs

→ Não há otimização que mude isso

4. Largura de banda de memória

DDR4: ~50 GB/s
Se processa 100 GB: ~2 segundos mínimo

→ Limite do hardware

5. Ciclos de CPU

CPU 3 GHz: 3 bilhões de ciclos/segundo
Operação complexa: 1000 ciclos
Máximo: 3 milhões de operações/segundo

→ Limite fundamental do processador

Como identificar

Sinais de limite físico:
✓ Recurso em 100% de utilização
✓ Adicionar mais software não ajuda
✓ Só resolve com mais/melhor hardware
✓ Matematicamente impossível ser mais rápido

Limites Arquiteturais

O que são

Limites impostos por decisões de design. Podem ser superados com redesenho.

Exemplos

1. Lock contention

# Arquitetura limitante
lock = Lock()
def process(item):
    with lock:  # Só uma thread por vez
        return do_work(item)

# Capacidade: 1 thread, não importa quantas CPUs

# Redesenho
def process(item):
    partition = get_partition(item)
    with partition_locks[partition]:  # Lock por partição
        return do_work(item)

# Capacidade: N threads (N partições)

2. Single point of serialization

Arquitetura limitante:
  Todos os requests → Um banco → Resposta
  Capacidade: limitada pelo banco único

Redesenho:
  Requests → Load Balancer → N bancos (sharding)
  Capacidade: N × capacidade individual

3. Algoritmo ineficiente

# O(n²) - limite arquitetural
def find_duplicates(items):
    duplicates = []
    for i, item in enumerate(items):
        for other in items[i+1:]:
            if item == other:
                duplicates.append(item)
    return duplicates

# O(n) - redesenho
def find_duplicates(items):
    seen = set()
    duplicates = []
    for item in items:
        if item in seen:
            duplicates.append(item)
        seen.add(item)
    return duplicates

4. Arquitetura síncrona

Limitante:
  Request → API → DB → Cache → External API → Response
  Latência: soma de todas as etapas

Redesenho:
  Request → API → [DB + Cache + External] paralelo → Response
  Latência: máximo das etapas

5. Modelo de dados inadequado

-- Limitante: JOIN em tabela de bilhões
SELECT * FROM orders
JOIN order_items ON orders.id = order_items.order_id
WHERE orders.user_id = 123;

-- Redesenho: desnormalização
SELECT * FROM orders_denormalized
WHERE user_id = 123;

Como identificar

Sinais de limite arquitetural:
✓ Recurso NÃO está em 100%
✓ Adicionar hardware não resolve
✓ Há filas ou bloqueios
✓ Componentes esperam uns pelos outros
✓ "Sempre foi assim" justifica o design

Comparação

Aspecto Físico Arquitetural
Causa Hardware/Física Decisões de design
Solução Mais/melhor hardware Redesenho
Custo $$ (infra) Tempo de engenharia
Limite Fundamental Removível

Diagnóstico

Passo 1: Medir utilização

CPU: 95% ← Pode ser físico ou arquitetural
Memória: 40% ← Provavelmente não é limite
Disco: 100% ← Pode ser físico
Rede: 20% ← Provavelmente não é limite

Passo 2: Identificar gargalo

# Profiling revela onde tempo é gasto
CPU:
  - 80% em função X ← Limite arquitetural (algoritmo)
  - 80% em syscalls ← Pode ser I/O

I/O:
  - Esperando lock ← Arquitetural
  - Esperando disco ← Pode ser físico

Passo 3: Testar hipótese

# Se físico: adicionar recurso deve ajudar
# Adicionar mais CPU
→ Performance melhora? Físico.
→ Não melhora? Arquitetural.

# Se arquitetural: otimização deve ajudar
# Mudar algoritmo/design
→ Performance melhora significativamente? Arquitetural confirmado.

Estratégias de Otimização

Para limites físicos

1. Escalar horizontalmente
   - Mais máquinas
   - Mais discos
   - Mais réplicas

2. Upgrade de hardware
   - CPU mais rápido
   - SSD NVMe
   - Mais memória

3. Aproximar dados
   - CDN
   - Cache local
   - Edge computing

4. Reduzir demanda
   - Compressão
   - Sampling
   - Agregação

Para limites arquiteturais

1. Eliminar contenção
   - Locks granulares
   - Lock-free structures
   - Particionamento

2. Paralelizar
   - Operações independentes em paralelo
   - Pipeline de processamento
   - Async I/O

3. Otimizar algoritmos
   - Melhor complexidade O()
   - Estruturas de dados adequadas
   - Caching estratégico

4. Redesenhar fluxos
   - Remover dependências
   - Batch processing
   - Event-driven

Casos Reais

Caso 1: "Banco está lento"

Observação: Queries levam 500ms
CPU do banco: 30%
Disco: 20%

Diagnóstico: Não é limite físico

Investigação: Query usa full table scan
Solução: Adicionar índice

Resultado: Queries em 5ms (100x melhoria)
→ Limite era arquitetural (falta de índice)

Caso 2: "API não escala"

Observação: 1000 req/s máximo, 4 CPUs a 100%
Adicionando mais CPUs: Não melhora

Diagnóstico: Parece físico, mas...

Investigação: Uma goroutine segura lock global
Solução: Remover lock desnecessário

Resultado: 10.000 req/s com mesmos 4 CPUs
→ Limite era arquitetural (lock)

Caso 3: "Latência trans-oceânica"

Observação: 200ms latência São Paulo → Europa
Rede: 10% utilização

Diagnóstico: Velocidade da luz

Solução possível: Edge na Europa

Resultado: 20ms latência
→ Limite era físico (contornado com arquitetura)

Conclusão

Antes de otimizar, diagnostique:

  1. Meça utilização de todos os recursos
  2. Profile para encontrar gargalos
  3. Teste hipóteses antes de investir

Regras práticas:

Recurso a 100% + adicionar ajuda = Físico
Recurso a 100% + adicionar não ajuda = Arquitetural mascarado
Recurso < 100% + lentidão = Arquitetural

Lembre-se:

  • Limites físicos são democratas: afetam todos igualmente
  • Limites arquiteturais são tiranias: criados por decisões passadas

Não jogue hardware em um problema de arquitetura. Não redesenhe quando precisa de mais disco.

limitesfísicaarquiteturaotimização
Compartilhar:
Read in English

Quer entender os limites da sua plataforma?

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

Fale Conosco