O que e Escalabilidade?
A capacidade de um sistema lidar com crescimento de carga sem degradar sua performance.
Escalabilidade e a propriedade de um sistema de se adaptar a um aumento de demanda, seja de usuários, dados ou requisições, mantendo performance e disponibilidade aceitáveis. Um sistema escalável consegue lidar com 10 usuários e com 10 milhões de usuários, ajustando seus recursos conforme necessário. Escalabilidade não e apenas sobre adicionar mais servidores: e sobre projetar o sistema para que essas adições sejam possíveis e eficazes. Um sistema não escalável tem gargalos que impedem o crescimento, como um banco de dados que não suporta mais conexões, um serviço que processa tudo em uma única thread, ou dados que precisam estar no mesmo servidor para serem processados. Projetar para escalabilidade desde cedo e muito mais barato do que tentar escalar um sistema que não foi pensado para isso.
Escalabilidade vertical vs horizontal
Vertical: melhorar o servidor. Horizontal: adicionar mais servidores.
Existem dois modelos básicos de escalabilidade. Escalabilidade vertical (scale up): aumentar os recursos de um único servidor, mais CPU, mais RAM, disco mais rápido. E mais simples de implementar pois não exige mudancas no código, mas tem limite fisico: não há servidor infinito, e servidores muito grandes são caros e tem ponto único de falha. Escalabilidade horizontal (scale out): adicionar mais instâncias do serviço rodando em paralelo, distribuindo a carga entre elas. Permite crescimento quase ilimitado e maior resiliência, pois a falha de uma instância não derruba o sistema inteiro. O desafio e que o código precisa ser stateless ou exige gerenciamento de estado distribuído. A maioria dos sistemas modernos começa com scale up por simplicidade e evolui para scale out quando os limites verticais são atingidos.
Gargalos mais comuns
Banco de dados, estado no servidor e acoplamento são os inimigos mais frequentes da escalabilidade.
Os gargalos de escalabilidade mais comuns incluem: o banco de dados e frequentemente o primeiro gargalo, pois e mais difícil de escalar horizontalmente do que a camada de aplicação. Soluções incluem read réplicas, sharding, caching agressivo e bancos de dados especializados para diferentes tipos de consulta. Estado armazenado no servidor (sessões HTTP em memória, arquivos no disco local) impede a distribuição de carga entre instâncias: se o usuário esta na instância A e a próxima requisição vai para a instância B, o estado e perdido. A solução e externalizar o estado para Redis (sessões) e object storage (arquivos). Acoplamento síncrono entre serviços cria dependências que limitam o throughput: se o serviço de email e lento, o serviço de pedidos fica esperando. Messaging assíncrono desacopla esses serviços.
Exemplo prático: do zero a milhões de usuários
A jornada arquitetural típica de uma startup que cresce.
A jornada de escalabilidade típica de uma startup segue etapas bem documentadas. Fase 1 (0-1000 usuários): um único servidor com aplicação e banco de dados, sem separação. Fase 2 (1k-10k usuários): separar aplicação e banco em servidores diferentes. Adicionar caching (Redis) para queries frequentes. Fase 3 (10k-100k usuários): adicionar load balancer e múltiplas instâncias da aplicação. Tornar a aplicação stateless. Adicionar CDN para assets estaticos. Fase 4 (100k-1M usuários): escalar o banco com read réplicas. Adicionar filas para processamento assíncrono. Separar serviços por dominio. Fase 5 (1M+ usuários): sharding do banco de dados. Microservicos para funcionalidades críticas. Cache distribuído em múltiplas camadas. Cada fase tem seus próprios desafios e não há motivo para implementar fase 5 quando a empresa ainda esta na fase 1.
Stateless e a chave para escala horizontal
Sem estado no servidor, qualquer instância pode atender qualquer requisição.
Stateless e um dos princípios mais importantes para escalabilidade horizontal. Um serviço stateless não guarda informação entre requisições no próprio servidor. Cada requisição contem ou referência toda a informação necessária para ser processada. Isso significa que qualquer instância pode atender qualquer requisição, e o load balancer pode distribuir de forma livre. Sessões de usuário ficam no Redis. Arquivos ficam no S3 ou equivalente. Estado transiente fica em caches distribuídos. O resultado e que adicionar uma nova instância e simplesmente iniciar um novo servidor e conectar ao load balancer, sem necessidade de migrar estado ou sincronizar dados entre instâncias. Stateless e pre-requisito para qualquer arquitetura que precise de escala horizontal real.
Load Balancing e auto-scaling
Distribuição inteligente de carga e ajuste automático de capacidade em resposta a demanda.
Load balancer e o componente que distribui requisições entre as instâncias disponíveis, garantindo que nenhuma seja sobrecarregada enquanto outras ficam ociosas. Algoritmos comuns incluem round-robin (distribuição circular), least connections (para a instância com menos conexões abertas) e IP hash (mesmo cliente vai sempre para a mesma instância, util para sessões). Auto-scaling ajusta automaticamente o número de instâncias baseado em métricas como CPU, memória ou número de requisições por segundo. Em picos de acesso, novas instâncias são lancadas automaticamente. Em períodos de baixo tráfego, instâncias são encerradas para economizar custo. AWS Auto Scaling, Google Cloud Autoscaler e Kubernetes HPA são exemplos de implementações de auto-scaling em produção.
Escalando o banco de dados
Read réplicas, connection pooling e sharding para bancos de dados sob alta carga.
Bancos de dados relacionais são o componente mais difícil de escalar horizontalmente. As estrategias mais comuns incluem: read réplicas, onde o banco primário recebe escritas e uma ou mais réplicas recebem leituras, distribuindo a carga de consulta. Connection pooling com ferramentas como PgBouncer, que gerência um pool de conexões e evita a sobrecarga de criar/encerrar conexões para cada requisição. Sharding horizontal, que divide os dados entre múltiplos bancos baseado em uma chave (ex: todos os usuários com ID 0-999999 no shard 1, 1000000-1999999 no shard 2), permitindo distribuição real da carga de escrita. Bancos NoSQL como MongoDB e Cassandra foram projetados para escala horizontal desde o inicio e podem ser mais adequados para dados que crescem muito rápido.
Quando pensar em escalabilidade
Desde o inicio para padrões críticos, gradualmente para o resto.
Não e necessário nem recomendado over-engineer escalabilidade desde o dia zero. Donald Knuth disse que "optimização prematura e a raiz de todo mal". Para projetos iniciais, um servidor simples e adequado e muito mais fácil de manter. O importante e tomar decisões que não bloqueiem a escalabilidade futura: tornar a aplicação stateless desde o inicio (custo baixo, beneficio alto), usar caching para operações caras, e projetar o banco de dados pensando em crescimento. A arquitetura de escalabilidade avançada (microservicos, sharding, multi-region) deve ser implementada gradualmente, conforme a demanda real justifica a complexidade. Escalar prematuramente gasta tempo e dinheiro em problemas que talvez nunca existam.
Resumo final
Escalar e uma jornada gradual, não uma grande refatoração de uma vez.
Escalabilidade e sobre fazer sistemas crescerem de forma controlada, mantendo performance e disponibilidade conforme a demanda aumenta. Começar simples, tornar a aplicação stateless cedo, usar caching estrategicamente, monitorar gargalos antes de otimizar e escalar gradualmente conforme a demanda real e a abordagem mais sensata. Os sistemas mais escaláveis do mundo, como os do Google e Amazon, não nasceram prontos para a escala atual: evoluiram gradualmente conforme os problemas apareciam. O importante e tomar decisões arquiteturais corretas desde cedo que não impedam o crescimento, e ter instrumentação suficiente para identificar gargalos antes que eles afetem os usuários.
Tutoriais em Video
Scaling Instagram Infrastructure
AWS re:Invent 2015: Scaling Up to Your First 10 Million Users
System Design BASICS: Horizontal vs. Vertical Scaling
Latency Numbers Programmer Should Know: Crash Course System Design
Consistent Hashing | Algorithms You Should Know
Uncovering Stack Overflow's Shocking Architecture
Conceitos-chave
Scale Up (Vertical)
Aumentar recursos de um único servidor: mais CPU, RAM, disco, simples mas tem limite fisico
Scale Out (Horizontal)
Adicionar mais instâncias em paralelo, permite crescimento ilimitado mas exige stateless
Stateless
Serviço que não guarda estado entre requisições, qualquer instância pode atender qualquer request
Load Balancer
Distribui requisições entre instâncias para evitar sobrecarga e aumentar throughput
Auto-scaling
Ajuste automático do número de instâncias baseado em métricas de uso (CPU, mem, RPS)
Sharding
Particionar dados entre múltiplos bancos para distribuir carga de escrita e leitura
Escalabilidade no Instagram
@bytebytego
Reels, Escalabilidade
@bytebytego
Escalabilidade no Facebook
Escalabilidade no X (Twitter)
Links Uteis
O que devs dizem
A maior lição que aprendi sobre escalabilidade e que stateless não e opcional. Quando tornamos nossa API stateless e migramos sessões para Redis, conseguimos adicionar instâncias sem nenhuma mudanca de código. O que antes era uma refatoração de semanas virou uma operação de horas.
Fizemos prematuramente uma arquitetura de microservicos pensando em escalabilidade. Adicionamos complexidade operacional enorme antes de ter o problema de escala. Hoje eu recomendo: comece com um monolito bem arquitetado e evolua para microservicos quando a necessidade de escala diferenciada for real.
Durante o Black Friday do marketplace, o auto-scaling do Kubernetes multiplicou as instâncias da API por 8 em 10 minutos automaticamente. Sem nenhuma intervenção humana, o sistema absorveu o pico e voltou ao normal depois. Investir em escalabilidade horizontal foi o que salvou o evento.