Crítica de Arquitetura

A Máquina de Fazer Nada

Uma aba aberta consumindo 1 GB de RAM. Dezenas de microsserviços para servir um CRUD. Onde foi que erramos a mão?

O cooler começa a girar.

Você abriu uma página.

Uma página.

Não é um jogo em 4K. Não é uma máquina virtual. Não é uma compilação do Chromium. É uma página qualquer, dessas que deveriam carregar texto, algumas imagens e pronto.

Só que o navegador já está consumindo centenas de megabytes. Talvez 500 MB. Talvez 800 MB. Talvez mais de 1 GB.

E ainda está carregando coisa.

JavaScript. Framework. Tracker. Analytics. Publicidade. Fonte. API. Outro script. Mais uma chamada. Algum serviço remoto que você nunca ouviu falar.

Você queria ler.

O computador decidiu montar uma infraestrutura distribuída.

Existe alguma coisa profundamente errada nisso.

Não porque computadores modernos sejam lentos. Pelo contrário. Temos máquinas absurdamente mais poderosas do que aquelas que colocávamos em data centers décadas atrás. Temos SSDs rápidos, processadores com dezenas de núcleos, gigabytes e mais gigabytes de RAM e conexões de internet que fazem a antiga banda larga parecer uma piada.

E mesmo assim o software moderno parece determinado a desperdiçar tudo isso.

A tecnologia avançou.

A eficiência, nem sempre.

A requisição começa simples. Depois vira uma peregrinação

Vamos imaginar uma aplicação moderna.

Você faz uma requisição.

Em um mundo razoavelmente simples:

NavegadorServidorAplicaçãoBanco de DadosResposta

Acabou.

Agora tente desenhar o caminho de uma requisição em uma arquitetura moderna.

A Peregrinação de uma Requisição Moderna
CDN
WAF
Load Balancer
API Gateway
Ingress
Kubernetes
Pod
Service
Service Mesh
Sidecar
Microsserviço A
Microsserviço B
Fila
Cache
ORM
Banco
Outro Serviço
Mais uma API

E finalmente alguma coisa executa a lógica que realmente interessa.

Isso não é uma caricatura. Existem sistemas onde uma arquitetura desse tipo é perfeitamente justificável.

O problema é quando isso vira o padrão.

Quando toda aplicação precisa parecer preparada para suportar a carga de uma rede social global mesmo que tenha cinquenta usuários.

Quando um CRUD interno ganha Kubernetes.

Quando uma operação que poderia ser uma chamada de função vira uma chamada HTTP para outro serviço, que chama uma fila, que acorda um consumidor, que consulta um cache, que acessa um banco.

Tudo em nome da escalabilidade.

A pergunta que quase nunca aparece é:

escalabilidade para quê?

Kubernetes virou verbo

Kubernetes é uma ferramenta fantástica.

Também virou uma resposta automática.

“Como vamos colocar isso em produção?”

Kubernetes.

“Precisamos mesmo de dezenas de containers?”

Kubernetes.

“Temos três serviços e um banco.”

Kubernetes.

“Essa aplicação roda em uma máquina.”

Kubernetes.

É como se a indústria tivesse encontrado um martelo tão poderoso que passou a enxergar pregos em tudo.

E não é só Kubernetes.

É a coleção inteira.

Docker.

Helm.

Terraform.

Service mesh.

Observabilidade.

Tracing.

Prometheus.

Grafana.

CI/CD.

Secrets.

Ingress.

Autoscaling.

Operators.

Sidecars.

E dezenas de outras peças que precisam conversar entre si para manter a coisa funcionando.

De novo: nenhuma dessas tecnologias é inútil.

O problema é a soma.

Cada camada parece razoável isoladamente.

O conjunto começa a parecer uma piada.

A complexidade não desapareceu. Ela foi empurrada

Existe uma promessa implícita na abstração moderna: você não precisa mais entender os detalhes.

Isso é verdade.

Até o dia em que alguma coisa quebra.

Aí você descobre que alguém precisa entender.

O desenvolvedor não precisa saber como o kernel agenda threads.

O engenheiro de plataforma sabe.

O desenvolvedor não precisa saber como a rede funciona.

Algum outro time sabe.

O desenvolvedor não precisa administrar servidores.

Ótimo.

Agora precisa aprender o funcionamento de uma plataforma interna criada para abstrair a infraestrutura que abstrai os servidores.

A complexidade não sumiu.

Ela mudou de lugar.

E, frequentemente, aumentou.

O Paradoxo da Engenharia Moderna

"Criamos abstrações para reduzir o trabalho e acabamos criando sistemas cujo principal trabalho é administrar as próprias abstrações."

Microsserviço para tudo

Talvez nada represente melhor essa situação do que a febre dos microsserviços.

A ideia original é boa.

Um sistema grande pode ser difícil de manter. Dividir responsabilidades pode permitir deploy independente, isolamento de falhas e escalabilidade seletiva.

Perfeito.

Só que existe uma diferença gigantesca entre dividir um sistema grande e começar qualquer sistema já dividido em cinquenta partes.

Quando cada componente vira um serviço, comunicação interna vira rede.

Rede vira latência.

Latência vira timeout.

Timeout vira retry.

Retry vira carga adicional.

Carga adicional vira autoscaling.

Autoscaling vira mais containers.

Mais containers exigem mais observabilidade.

E, de repente, uma chamada que poderia ter sido:

resultado = calcular()

virou:

cliente
  ↓
API
  ↓
service A
  ↓
service B
  ↓
fila
  ↓
consumer
  ↓
service C
  ↓
cache
  ↓
database

Tudo isso para calcular alguma coisa.

É difícil não olhar para isso e pensar que perdemos alguma coisa no caminho.

O software moderno tem uma quantidade obscena de camadas

Framework sobre runtime.

Runtime sobre sistema operacional.

Sistema operacional sobre hardware.

Aplicação sobre framework.

Framework sobre biblioteca.

Biblioteca sobre outra biblioteca.

Container sobre kernel.

Orquestrador sobre containers.

Plataforma sobre orquestrador.

E depois alguém cria uma abstração para esconder a plataforma.

É abstração em cima de abstração em cima de abstração.

E existe uma pergunta que deveria aparecer muito mais nas revisões de arquitetura:

“O que aconteceria se simplesmente removêssemos isso?”

Não trocar.

Não atualizar.

Não substituir.

Remover.

Talvez a resposta seja “nada”.

E, se a resposta for “nada”, por que aquilo existe?

Enquanto isso, o navegador está comendo 1 GB

Agora vamos sair do backend.

Porque o problema não termina no servidor.

Ele chega até a máquina do usuário.

E talvez o navegador seja o maior monumento ao bloat moderno.

Existe um contraste histórico que deveria ser impossível de ignorar.

Houve uma época em que 32 MB de RAM eram suficientes para rodar um sistema operacional inteiro, uma interface gráfica completa (incluindo coisas como o servidor X em sistemas Linux) e ainda abrir um navegador com várias abas.

Trinta e dois megabytes.

Hoje você pode abrir uma única página e ver o navegador consumir centenas de megabytes.

Em alguns casos, mais de 1 GB.

Uma aba.

Não um banco de dados.

Não uma VM.

Não um servidor.

Uma aba.

A Desculpa do Hardware Farto

"A justificativa normalmente é que os computadores atuais têm memória suficiente."

Esse argumento é péssimo. Hardware abundante deveria nos permitir construir software melhor. Não deveria nos dar licença para parar de pensar.

Uma página deixou de ser um documento

O problema é que uma página moderna raramente é só uma página.

Ela é uma aplicação.

Você abre.

O navegador baixa JavaScript.

O JavaScript inicializa o framework.

O framework monta a aplicação.

A aplicação busca dados.

Os dados chegam.

A interface renderiza.

Outro componente percebe que precisa de mais dados.

Mais uma requisição.

A publicidade inicializa.

Analytics inicializa.

Tracker inicializa.

Consentimento inicializa.

Outro script de terceiros entra em cena.

E tudo isso acontece antes de você simplesmente conseguir ler o conteúdo.

A web deixou de ser apenas um meio de transportar documentos.

Virou um ambiente de execução gigantesco.

Às vezes parece que colocamos uma máquina virtual dentro do navegador para renderizar um botão.

Seu computador virou parte da infraestrutura de publicidade

Existe uma parte desse problema que é especialmente irritante.

Muito do processamento não está sendo gasto para entregar aquilo que você pediu.

Está sendo gasto para monetizar você.

Publicidade programática.

Leilões em tempo real.

Rastreamento.

Analytics.

Pixels.

Personalização.

Atribuição.

Testes A/B.

Scripts de terceiros.

O navegador trabalha.

A página trabalha.

Sua CPU trabalha.

Sua RAM trabalha.

Sua bateria trabalha.

Tudo isso para que algum sistema determine qual anúncio tem maior probabilidade de capturar sua atenção.

Seu computador virou parte da infraestrutura da indústria de publicidade.

E você paga a conta.

Com energia.

Com memória.

Com processamento.

Com tempo.

“Mas temos 32 GB de RAM”

Sim.

E daí?

Essa talvez seja uma das frases mais perigosas da computação moderna:

“Tem recurso sobrando.”

Se temos 32 GB de RAM, isso não significa que uma aplicação deveria consumir 4 GB porque pode.

Se temos CPUs muito rápidas, isso não significa que uma operação que poderia levar 10 ms deveria levar 300 ms.

Se temos fibra, isso não significa que uma página deveria baixar dezenas de megabytes antes de mostrar o texto.

Hardware rápido não transforma desperdício em eficiência.

Só torna o desperdício menos perceptível.

Por algum tempo.

O bloat é uma dívida que ninguém coloca na planilha

Um megabyte desperdiçado parece irrelevante.

Uma dependência desnecessária parece irrelevante.

Uma chamada de rede extra parece irrelevante.

Mais um container parece irrelevante.

Mais um serviço parece irrelevante.

Mais um script de terceiros parece irrelevante.

O problema é a escala.

Mil decisões pequenas formam um sistema enorme.

E como nenhuma delas individualmente parece catastrófica, ninguém é responsável pelo resultado final.

Até chegar o dia em que alguém abre o monitoramento e percebe que uma aplicação simples precisa de uma frota de máquinas para fazer aquilo que deveria caber confortavelmente em uma.

É o bloat por acumulação.

Não existe um vilão único.

Existe uma sequência infinita de “só mais isso”.

O culto do “enterprise”

Também existe um problema cultural.

Complexidade parece profissional.

Uma arquitetura com vinte caixas no diagrama parece mais séria do que um servidor simples.

Uma aplicação com dezenas de serviços parece mais madura do que um monólito bem escrito.

Uma infraestrutura com dezenas de ferramentas parece mais sofisticada do que uma máquina funcionando.

E aí simplicidade passa a parecer ingenuidade.

“Mas isso não escala.”

Talvez não.

Mas será que precisa escalar?

Essa é a pergunta que deveria vir antes.

Se uma aplicação tem cem usuários, não existe prêmio por prepará-la para cem milhões.

Existe custo.

Existe manutenção.

Existe complexidade.

Existe uma equipe inteira acordando às três da manhã porque um componente que ninguém lembra de ter criado decidiu parar de responder.

Software deveria ser rápido porque é bom, não porque o hardware é rápido

Eficiência costumava ser uma característica de engenharia.

Você queria economizar memória.

Queria reduzir I/O.

Queria diminuir latência.

Queria evitar trabalho desnecessário.

Não porque o hardware era miserável.

Porque desperdício é desperdício.

Hoje essa mentalidade parece quase antiquada.

“Funciona.”

Essa frase encerra discussões demais.

Funciona, mas usa 1 GB.

Funciona, mas precisa de quinze serviços.

Funciona, mas demora três segundos.

Funciona, mas precisa de uma conexão constante.

Funciona, mas consome a bateria.

Funciona, mas ninguém entende mais como funciona.

Funciona.

E aparentemente isso basta.

Não precisamos voltar para 1998

A crítica aqui não é um convite à nostalgia.

Não precisamos abandonar navegadores modernos.

Não precisamos voltar a servidores físicos administrados manualmente.

Não precisamos jogar Kubernetes fora.

Não precisamos transformar todo sistema distribuído em um monólito.

Não precisamos escrever tudo em C.

O ponto é muito mais simples.

Precisamos recuperar a capacidade de perguntar se determinada complexidade é realmente necessária.

Porque existe uma diferença entre uma solução sofisticada e uma solução exagerada.

Existe uma diferença entre escala real e escala imaginária.

Existe uma diferença entre abstração útil e abstração ornamental.

E existe uma diferença enorme entre software que precisa de recursos e software que desperdiça recursos porque ninguém mais se importa.

Talvez o verdadeiro avanço seja remover coisas

A indústria de software passou décadas adicionando.

Mais frameworks.

Mais serviços.

Mais abstrações.

Mais automação.

Mais plataformas.

Mais ferramentas.

Mais camadas.

Talvez esteja na hora de experimentar uma ideia radical:

tirar coisas fora.

Menos dependências.

Menos chamadas.

Menos JavaScript.

Menos serviços.

Menos camadas.

Menos infraestrutura quando ela não é necessária.

Menos código executando no computador do usuário sem motivo.

Talvez uma aplicação precise simplesmente carregar.

Rápido.

E funcionar.

É uma ideia quase revolucionária em 2026.

No fim, a pergunta não deveria ser quantas tecnologias conseguimos empilhar para construir alguma coisa.

Deveria ser quantas conseguimos remover sem que ninguém perceba.

A Reflexão Final

Se você precisa de Kubernetes, microsserviços, dezenas de containers, meia dúzia de frameworks, centenas de megabytes de JavaScript e um navegador consumindo 1 GB de RAM para mostrar uma página...

Talvez a máquina não esteja fazendo muita coisa. Talvez ela só esteja ocupada demais fazendo tudo aquilo que colocamos no caminho.