← Back to home

Escalabilidade

By Pscodium · 8/4/2026 · 3 views

Escalabilidade — System Design

Escalabilidade é a capacidade de um sistema de continuar atendendo sua demanda conforme o número de usuários, requisições e volume de dados aumenta.

Imagine uma aplicação que começa com:

100 usuários
    │
    ▼
┌─────────────┐
│   Server    │
│  2 CPU      │
│  4 GB RAM   │
└─────────────┘

Com o crescimento da aplicação:

10.000 usuários
100.000 usuários
1.000.000 usuários

Um único servidor pode deixar de ser suficiente.

Nesse momento, precisamos pensar em como aumentar a capacidade do sistema.

Existem duas estratégias principais:

  • Escalabilidade vertical
  • Escalabilidade horizontal

Além disso, precisamos de componentes como Load Balancers, servidores Stateless e arquiteturas distribuídas.


1. O que você vai aprender

Neste artigo, vamos entender:

  • Diferença entre escalabilidade vertical e horizontal
  • Como funciona um Load Balancer
  • Estratégias de distribuição de tráfego
  • Round-Robin
  • Least Connections
  • IP Hash
  • Por que servidores Stateless são importantes
  • As 3 camadas de um sistema web
  • Como escalar cada camada
  • Quando é hora de escalar
  • Quais métricas observar
  • Trade-offs envolvidos nas decisões de escalabilidade

2. O que é escalabilidade?

Escalabilidade é a capacidade de um sistema aumentar sua capacidade de processamento conforme a demanda cresce.

Podemos representar:

Demanda
   │
   │              /
   │            /
   │          /
   │        /
   │      /
   │    /
   └────────────────── Tempo

À medida que a demanda aumenta, precisamos aumentar a capacidade:

Demanda ↑
   │
   │
   ▼

Capacidade ↑

O objetivo é evitar que o sistema fique:

  • Lento
  • Instável
  • Indisponível
  • Sobrecarregado

3. Escalabilidade Vertical

A escalabilidade vertical, também chamada de Scale Up, consiste em aumentar os recursos de um servidor existente.

Por exemplo:

ANTES

┌─────────────────────┐
│       SERVER        │
├─────────────────────┤
│ 2 CPU               │
│ 4 GB RAM             │
│ 100 GB SSD           │
└─────────────────────┘

Podemos aumentar para:

DEPOIS

┌─────────────────────┐
│       SERVER        │
├─────────────────────┤
│ 16 CPU              │
│ 64 GB RAM           │
│ 1 TB SSD            │
└─────────────────────┘

O sistema continua rodando em um único servidor.

           CLIENTS
              │
              ▼
       ┌─────────────┐
       │   SERVER    │
       │             │
       │ 16 CPU      │
       │ 64 GB RAM   │
       └─────────────┘

Vantagens

A principal vantagem é a simplicidade.

Não precisamos necessariamente modificar a arquitetura.

Podemos continuar utilizando:

Client
  │
  ▼
Server
  │
  ▼
Database

Outras vantagens:

  • Fácil implementação
  • Menor complexidade operacional
  • Menos componentes distribuídos
  • Mais simples de monitorar
  • Menos problemas de sincronização

Desvantagens

Existe um limite físico.

Não podemos aumentar os recursos infinitamente.

Além disso, servidores maiores podem se tornar muito caros.

Também existe outro problema:

Se o único servidor falhar, toda a aplicação pode ficar indisponível.

Temos então um possível Single Point of Failure.

             CLIENTS
                │
                ▼
          ┌───────────┐
          │ SERVER    │
          └─────┬─────┘
                X
             FALHA
                │
                ▼
          SISTEMA OFFLINE

4. Escalabilidade Horizontal

A escalabilidade horizontal, ou Scale Out, consiste em adicionar mais servidores.

Em vez de termos:

1 servidor gigante

podemos ter:

3 servidores menores

Por exemplo:

              CLIENTS
                  │
                  ▼
            ┌──────────┐
            │   LOAD   │
            │ BALANCER │
            └────┬─────┘
                 │
        ┌────────┼────────┐
        │        │        │
        ▼        ▼        ▼
     ┌─────┐  ┌─────┐  ┌─────┐
     │App 1│  │App 2│  │App 3│
     └─────┘  └─────┘  └─────┘

O Load Balancer distribui as requisições entre os servidores.

Se a demanda aumentar:

3 servidores
      │
      ▼
5 servidores
      │
      ▼
10 servidores

Podemos adicionar novas instâncias.


5. Vertical vs Horizontal

CaracterísticaVerticalHorizontalEstratégiaAumentar servidorAdicionar servidoresComplexidadeMenorMaiorLimite físicoSimMuito maiorAlta disponibilidadeLimitadaMelhorCusto inicialPode ser menorPode ser maiorDistribuição de cargaNãoSimFalha de um servidorImpacto altoPode ser absorvidaOperaçãoSimplesMais complexa

De maneira geral:

Scale Up

SERVER
  │
  ▼
SERVER MAIOR

Enquanto:

Scale Out

SERVER
SERVER
SERVER
SERVER

Em sistemas modernos de grande escala, a escalabilidade horizontal é frequentemente preferida.

Porém, isso não significa que devemos ignorar a vertical.

Uma combinação das duas estratégias é bastante comum.


6. Load Balancer

Quando temos vários servidores, precisamos de uma maneira de distribuir as requisições.

É aí que entra o Load Balancer.

Sua função básica é:

             CLIENTS
                 │
                 ▼
         ┌───────────────┐
         │ LOAD BALANCER │
         └───────┬───────┘
                 │
       ┌─────────┼─────────┐
       │         │         │
       ▼         ▼         ▼
    SERVER 1  SERVER 2  SERVER 3

O cliente não precisa saber qual servidor irá processar a requisição.

Ele envia:

GET /users

O Load Balancer decide:

Servidor 1

Na próxima requisição:

GET /products

Pode decidir:

Servidor 2

Isso permite distribuir a carga.


7. Round-Robin

Round-Robin é uma das estratégias mais simples.

As requisições são distribuídas sequencialmente.

Imagine:

SERVER 1
SERVER 2
SERVER 3

As requisições seriam:

Request 1 → Server 1

Request 2 → Server 2

Request 3 → Server 3

Request 4 → Server 1

Request 5 → Server 2

Request 6 → Server 3

Visualmente:

              LOAD BALANCER
                    │
       ┌────────────┼────────────┐
       ▼            ▼            ▼
    Server 1     Server 2     Server 3
       ▲            ▲            ▲
       │            │            │
       └────────────┴────────────┘
              CICLO

Vantagem

É simples e funciona bem quando:

Server 1 = mesma capacidade
Server 2 = mesma capacidade
Server 3 = mesma capacidade

E quando as requisições possuem custos semelhantes.


Problema

Imagine:

Server 1 → 10 requisições pesadas
Server 2 → 10 requisições leves
Server 3 → 10 requisições leves

O Round-Robin pode considerar todos os servidores igualmente disponíveis.

Mas, na prática:

Server 1 → 95% CPU
Server 2 → 20% CPU
Server 3 → 15% CPU

O número de requisições não representa necessariamente a carga real.


8. Least Connections

O Least Connections tenta enviar a requisição para o servidor que possui menos conexões ativas.

Imagine:

Server 1 → 100 conexões
Server 2 → 20 conexões
Server 3 → 50 conexões

Uma nova requisição será enviada para:

Server 2

Visualmente:

              LOAD BALANCER
                    │
                    │
                    ▼
             Menos conexões
                    │
                    ▼
               SERVER 2

Isso pode funcionar melhor quando as requisições possuem durações diferentes.

Por exemplo:

Request A → 10 segundos
Request B → 100 ms

O Round-Robin pode distribuir igualmente.

O Least Connections tenta considerar a quantidade de trabalho atualmente em andamento.


Limitação

Número de conexões não é necessariamente igual a consumo de CPU ou memória.

Podemos ter:

Server 1
10 conexões
90% CPU


Server 2
50 conexões
20% CPU

O algoritmo pode interpretar que o Server 1 está mais livre, mesmo que esteja quase saturado.

Por isso, sistemas mais sofisticados podem utilizar métricas de saúde e carga.


9. IP Hash

O IP Hash utiliza o endereço IP do cliente para determinar qual servidor irá atender a requisição.

Por exemplo:

Cliente A
IP: 192.168.1.10
       │
       ▼
    Server 1

Enquanto:

Cliente B
IP: 192.168.1.20
       │
       ▼
    Server 2

O objetivo é fazer com que o mesmo cliente seja direcionado consistentemente para o mesmo servidor.

Isso pode ser útil quando existe algum estado local no servidor.

Por exemplo:

Cliente A
    │
    ▼
Server 1
    │
    ▼
Session local

Nas próximas requisições:

Cliente A
    │
    ▼
Server 1

Problema

Se o servidor cair:

Server 1
    X

O cliente pode ser direcionado para outro servidor.

Nesse momento:

Server 2
    │
    └── Não possui a sessão local

Isso mostra um dos principais problemas de manter estado dentro do servidor.


10. Stateless vs Stateful

Para escalar horizontalmente de maneira eficiente, normalmente queremos servidores Stateless.

Um servidor Stateless não depende de informações armazenadas localmente entre requisições.

Por exemplo:

Request 1
    │
    ▼
Server 1

Request 2:

Request 2
    │
    ▼
Server 3

O Server 3 consegue processar a requisição sem precisar saber que o Server 1 processou a anterior.


11. O problema de servidores Stateful

Imagine uma aplicação que armazena a sessão na memória do servidor.

              CLIENT
                 │
                 ▼
            SERVER 1
                 │
                 ▼
          Session: user123

Na próxima requisição:

              CLIENT
                 │
                 ▼
            SERVER 2

O Server 2 não conhece:

Session: user123

Isso pode causar problemas.

Uma solução seria usar:

Sticky Sessions

Ou seja, sempre enviar o usuário para o mesmo servidor.

Porém, isso dificulta a escalabilidade.


12. Transformando o sistema em Stateless

Uma abordagem melhor é retirar o estado do servidor.

Podemos utilizar:

             CLIENT
                │
                ▼
         ┌──────────────┐
         │ Load Balancer│
         └───────┬──────┘
                 │
        ┌────────┼────────┐
        ▼        ▼        ▼
      App 1    App 2    App 3
        │        │        │
        └────────┼────────┘
                 │
                 ▼
              Redis

Agora:

App 1 ──┐
App 2 ──┼──► Redis
App 3 ──┘

Todas as instâncias podem acessar o mesmo estado compartilhado.

Isso permite:

Request 1 → App 1
Request 2 → App 3
Request 3 → App 2

Sem problemas.


13. Stateless com JWT

Outra abordagem comum é utilizar tokens.

Por exemplo:

CLIENT
   │
   │ Login
   ▼
SERVER
   │
   ▼
JWT

O cliente recebe:

JWT Token

E envia em cada requisição:

Authorization: Bearer <token>

Agora qualquer servidor pode validar o token:

          REQUEST
             │
             ▼
       ┌────────────┐
       │ Load       │
       │ Balancer   │
       └─────┬──────┘
             │
       ┌─────┼─────┐
       ▼     ▼     ▼
     App 1 App 2 App 3
       │     │     │
       └─────┼─────┘
             │
        Valida JWT

Não é necessário armazenar a sessão na memória de uma instância específica.

Isso facilita o Scale Out.


14. As 3 camadas de um sistema web

Uma arquitetura web tradicional pode ser dividida em três camadas:

1. Presentation Layer
2. Application Layer
3. Data Layer

Ou:

        CLIENT
           │
           ▼
   ┌───────────────┐
   │ PRESENTATION  │
   └───────┬───────┘
           │
           ▼
   ┌───────────────┐
   │ APPLICATION   │
   └───────┬───────┘
           │
           ▼
   ┌───────────────┐
   │     DATA      │
   └───────────────┘

Cada camada pode ter diferentes estratégias de escalabilidade.


15. Camada 1 — Presentation

Essa é a camada responsável pela interação com o usuário.

Pode incluir:

  • Frontend
  • HTML
  • CSS
  • JavaScript
  • React
  • Next.js
  • Aplicações mobile

Uma estratégia comum é utilizar uma CDN.

             CLIENT
                │
                ▼
               CDN
                │
       ┌────────┴────────┐
       │                 │
       ▼                 ▼
    Cache            Origin Server

Arquivos estáticos podem ser distribuídos globalmente:

JavaScript
CSS
Imagens
Vídeos
Fonts

Isso reduz a carga no servidor principal.


16. CDN

Imagine um usuário no Brasil acessando um servidor localizado nos Estados Unidos.

Sem CDN:

Brasil
   │
   │ Internet
   │
   └──────────────► EUA
                    │
                 Server

Com CDN:

Brasil
   │
   ▼
CDN São Paulo
   │
   │ Cache Hit
   ▼
Resposta

Se o conteúdo já estiver armazenado na CDN, não precisamos acessar o servidor de origem.

Isso melhora:

  • Latência
  • Performance
  • Disponibilidade
  • Escalabilidade

17. Camada 2 — Application

É onde normalmente encontramos:

  • APIs
  • Backend
  • Regras de negócio
  • Autenticação
  • Processamento

Podemos escalar horizontalmente:

                CLIENT
                   │
                   ▼
            LOAD BALANCER
                   │
       ┌───────────┼───────────┐
       ▼           ▼           ▼
    API 1        API 2        API 3

Essa camada é uma das mais fáceis de escalar horizontalmente quando os servidores são Stateless.

Se a demanda aumenta:

3 instances
    │
    ▼
10 instances

Podemos adicionar mais servidores.


18. Camada 3 — Data

Essa camada pode conter:

  • Bancos SQL
  • Bancos NoSQL
  • Cache
  • Storage

Ela geralmente é a mais difícil de escalar.

Podemos utilizar:

Read Replicas

             APPLICATION
                  │
                  ▼
              PRIMARY
             DATABASE
                  │
          ┌───────┴───────┐
          ▼               ▼
       REPLICA 1       REPLICA 2

As escritas vão para:

PRIMARY

As leituras podem ser distribuídas:

READ
 │
 ├── Replica 1
 │
 └── Replica 2

Isso ajuda a escalar sistemas com muitas leituras.


Sharding

Outra estratégia é dividir os dados.

Imagine:

Users 1 - 1.000.000

Podemos dividir:

Shard 1
Users 1 - 250.000

Shard 2
Users 250.001 - 500.000

Shard 3
Users 500.001 - 750.000

Shard 4
Users 750.001 - 1.000.000

Isso distribui os dados entre diferentes servidores.

Porém, adiciona bastante complexidade.


19. Escalando as três camadas

Uma arquitetura mais completa poderia ser:

                         CLIENTS
                            │
                            ▼
                           CDN
                            │
                            ▼
                      LOAD BALANCER
                            │
                 ┌──────────┼──────────┐
                 ▼          ▼          ▼
               API 1      API 2      API 3
                 │          │          │
                 └──────────┼──────────┘
                            │
                   ┌────────┴────────┐
                   ▼                 ▼
                 Redis           Database
                                     │
                            ┌────────┴────────┐
                            ▼                 ▼
                         Primary          Replicas

Cada camada possui uma estratégia diferente.

Presentation
    │
    └── CDN


Application
    │
    └── Load Balancer + Horizontal Scaling


Data
    │
    ├── Cache
    ├── Replicas
    ├── Partitioning
    └── Sharding

20. Quando é hora de escalar?

Não devemos escalar apenas porque:

"A aplicação está crescendo."

Precisamos observar métricas.

Alguns sinais importantes:

CPU
Memória
Latência
Throughput
Erros
Requests por segundo
Conexões
I/O
Database Load

21. CPU

Imagine:

CPU

20%
30%
40%
50%
60%
70%
80%
90%
95%

Se a CPU permanece constantemente em:

90%+

podemos ter um problema.

Isso pode indicar:

  • Falta de capacidade
  • Código ineficiente
  • Query pesada
  • Loop excessivo
  • Processamento síncrono

Antes de simplesmente adicionar servidores, devemos investigar a causa.


22. Memória

Se a memória está constantemente alta:

RAM
95%
97%
99%

podemos ter:

  • Memory leak
  • Cache muito grande
  • Objetos mantidos em memória
  • Falta de recursos

Adicionar servidores pode ajudar, mas não necessariamente resolve a causa.


23. Latência

Uma das métricas mais importantes é o tempo de resposta.

Por exemplo:

P50 = 100 ms
P95 = 500 ms
P99 = 2 segundos

O P99 significa que 99% das requisições são mais rápidas que aquele valor.

Observar apenas a média pode esconder problemas.

Exemplo:

99 requisições → 100 ms
1 requisição   → 10 segundos

A média pode parecer aceitável, mas existe um usuário sofrendo com uma latência muito alta.

Por isso, métricas como:

P50
P95
P99

são extremamente importantes.


24. Throughput

Throughput representa a quantidade de trabalho processada pelo sistema.

Por exemplo:

Requests per Second (RPS)

Imagine:

Servidor suporta:
1.000 RPS

A demanda atual:

900 RPS

Estamos próximos do limite.

Se a demanda crescer:

1.500 RPS

o sistema pode começar a apresentar:

  • Aumento de latência
  • Timeouts
  • Erros
  • Fila de requisições

Esse é um sinal de que precisamos aumentar a capacidade.


25. Error Rate

Devemos monitorar a quantidade de erros.

Por exemplo:

HTTP 500
HTTP 502
HTTP 503
Timeouts

Imagine:

Error Rate

0.1%
0.2%
0.3%
0.5%
1%
5%

Um crescimento repentino pode indicar:

  • Saturação
  • Falha de servidor
  • Problema no banco
  • Problema de rede
  • Dependência externa indisponível

26. Database Load

Muitas vezes o problema não está na aplicação.

Podemos ter:

API
 │
 ▼
Database
 │
 ▼
CPU 100%

Nesse caso, adicionar mais servidores de aplicação:

API 1
API 2
API 3
API 4
API 5

não necessariamente resolve.

Na verdade, pode piorar.

Agora temos:

API 1 ──┐
API 2 ──┤
API 3 ──┼──► DATABASE
API 4 ──┤        │
API 5 ──┘        ▼
              100% CPU

O gargalo está no banco.

Precisamos investigar:

  • Queries lentas
  • Índices
  • Locks
  • Conexões
  • Cache
  • Read replicas
  • Particionamento

27. Gargalos

Um conceito fundamental é identificar o bottleneck.

Imagine:

Client
   │
   ▼
API
   │
   ▼
Database

Se:

API → 20% CPU
Database → 100% CPU

O banco é o gargalo.

Escalar a API não resolve.

Outro exemplo:

API → 100% CPU
Database → 20% CPU

Nesse caso, podemos escalar a camada de aplicação.

A regra é:

Escale o gargalo, não simplesmente o componente mais fácil de escalar.


28. Trade-offs da Escalabilidade

Escalar traz benefícios, mas também aumenta a complexidade.

Quanto mais distribuído o sistema:

┌────────┐
│ Server │
└────────┘

para:

Server 1
Server 2
Server 3
Server 4
Server 5
Database
Redis
Queue
CDN
Load Balancer

maior a complexidade operacional.

Agora precisamos lidar com:

  • Rede
  • Latência
  • Falhas parciais
  • Consistência
  • Observabilidade
  • Deploy
  • Monitoramento
  • Coordenação

29. Escalabilidade vs Custo

Mais servidores significam mais custos.

Por exemplo:

1 servidor
R$ 500/mês

Pode virar:

10 servidores
R$ 5.000/mês

Além disso:

Load Balancer
Redis
Database Replicas
CDN
Observabilidade

também possuem custos.

Por isso, devemos evitar escalar prematuramente.


30. Escalar verticalmente ou horizontalmente?

Uma estratégia prática:

Sistema pequeno
      │
      ▼
Scale Up
      │
      ▼
Monitoramento
      │
      ▼
Gargalo identificado
      │
      ▼
Scale Out
      │
      ▼
Load Balancer
      │
      ▼
Stateless
      │
      ▼
Escalar componentes individualmente

Podemos começar simples:

Client
  │
  ▼
Backend
  │
  ▼
Database

Depois evoluir:

Client
  │
  ▼
Load Balancer
  │
  ├── Backend 1
  ├── Backend 2
  └── Backend 3
         │
         ▼
       Redis
         │
         ▼
      Database

E somente quando necessário:

CDN
Load Balancer
API Servers
Cache
Queues
Workers
Read Replicas
Sharding

31. Resumo dos principais conceitos

Escalabilidade Vertical

Aumenta os recursos de uma máquina.

2 CPU
  ↓
16 CPU

Mais simples, mas possui limites.


Escalabilidade Horizontal

Adiciona mais máquinas.

Server 1
Server 2
Server 3

Mais complexa, mas oferece maior capacidade de crescimento.


Load Balancer

Distribui requisições.

Client
  │
  ▼
Load Balancer
  │
  ├── Server 1
  ├── Server 2
  └── Server 3

Algoritmos comuns:

Round-Robin
Least Connections
IP Hash

Stateless

Os servidores não dependem de estado local.

Isso permite:

Request 1 → Server 1
Request 2 → Server 3
Request 3 → Server 2

Facilitando o Scale Out.


Três camadas

Presentation
    │
    └── CDN


Application
    │
    └── Load Balancer + Servers


Data
    │
    └── Cache + Replicas + Sharding

Métricas importantes

CPU
Memory
Latency
P95 / P99
RPS
Throughput
Error Rate
Database Load
Connections
I/O

32. Checklist para System Design

Quando estiver desenhando um sistema, pergunte:

Aplicação

  • Os servidores são Stateless?
  • Posso adicionar novas instâncias?
  • Existe um Load Balancer?
  • Qual algoritmo de distribuição usar?

Performance

  • Qual é o RPS esperado?
  • Qual é a latência aceitável?
  • Qual é o P95?
  • Qual é o P99?

Banco

  • O banco é o gargalo?
  • Preciso de Read Replicas?
  • Preciso de cache?
  • Preciso particionar os dados?
  • Sharding é realmente necessário?

Disponibilidade

  • O que acontece se um servidor cair?
  • Existe Single Point of Failure?
  • Existe redundância?

Escalabilidade

  • O sistema escala verticalmente?
  • O sistema escala horizontalmente?
  • Qual componente será o primeiro gargalo?

Custo

  • Quanto custa adicionar capacidade?
  • Estou escalando antes de precisar?
  • Existe uma solução mais simples?

Conclusão

Escalabilidade não significa simplesmente adicionar mais servidores.

Um sistema escalável é aquele que consegue aumentar sua capacidade de acordo com a demanda sem que a complexidade e o custo cresçam de maneira descontrolada.

A arquitetura geralmente evolui de:

Servidor único

para:

Load Balancer
      │
      ├── Server 1
      ├── Server 2
      └── Server 3

E posteriormente pode incorporar:

CDN
Load Balancer
Stateless APIs
Redis
Queues
Workers
Database Replicas
Partitioning
Sharding

A principal habilidade em System Design é saber quando e por que introduzir cada componente.

A regra mais importante é:

Não escale por hábito. Escale quando os requisitos e as métricas mostrarem que você precisa.

Antes de adicionar complexidade, procure o gargalo.

Antes de usar uma tecnologia, entenda o problema.

Antes de fazer sharding, veja se um bom índice resolve.

Antes de adicionar dezenas de servidores, descubra se uma query mal otimizada está consumindo todo o banco.

E, principalmente:

Uma boa arquitetura não é a que possui mais componentes. É a que resolve o problema com a complexidade necessária.



Comments

No comments yet.