Performance
Qualidade de Software
Engenharia
Observabilidade
Arquitetura

Performance de software: o que casos reais ensinam sobre qualidade

Performance não é um luxo de engenharia, é a diferença entre um produto que escala e um que sangra dinheiro em silêncio.

Todo time já viveu a cena. O produto funciona perfeitamente na demo, passa nos testes, agrada o cliente. Três meses depois, com tráfego real, a aplicação começa a engasgar. As páginas demoram. O suporte enche de reclamações. E ninguém sabe exatamente onde está o problema.

Performance raramente quebra de uma vez. Ela se degrada aos poucos, escondida atrás de métricas que pareciam confortáveis quando o sistema tinha cem usuários e se tornam insustentáveis com cem mil. O perigo não é o pico óbvio, é a erosão silenciosa.

Quero usar este artigo para olhar performance pelo que ela realmente é: uma decisão de qualidade que tem consequências diretas no caixa, na reputação e na capacidade de crescer. Não como um problema de "otimizar código", mas como um sintoma de maturidade de engenharia.

Performance é qualidade, não enfeite

Existe uma cultura preguiçosa que separa "fazer funcionar" de "fazer rápido", como se o segundo fosse uma etapa opcional para depois. Essa separação é falsa. Um sistema lento é um sistema com defeito, só que o defeito se manifesta como abandono de usuário, não como tela de erro.

A tese que defendo é simples: performance é um requisito não funcional que precisa ser tratado com o mesmo rigor de um requisito funcional. Se a sua definição de "pronto" não inclui comportamento sob carga, a sua definição de pronto está incompleta.

Vi isso de forma dolorosa em produtos de governo digital. Um portal de serviços públicos pode estar tecnicamente correto e ainda assim falhar no dia em que abre o prazo de uma matrícula ou de uma declaração. Naquele dia, o pico de acesso é a regra, não a exceção. E é exatamente nesse dia que a confiança do cidadão se ganha ou se perde.

Caso 1: o gargalo que estava no banco, não no código

Um time investiu semanas reescrevendo a camada de aplicação convencido de que o problema era a linguagem. Trocaram bibliotecas, refatoraram funções, brigaram com o framework. A latência caiu pouco.

Quando finalmente instrumentaram as consultas, a verdade apareceu: uma única query sem índice estava varrendo a tabela inteira a cada requisição. O problema nunca foi a aplicação. Era o famoso N+1 disfarçado, multiplicado por cada item de uma lista que crescia todo mês.

A lição não é técnica, é cultural. Sem observabilidade, métricas, traces, logs estruturados, você não otimiza, você adivinha. E adivinhação custa caro. O time gastou semanas no lugar errado porque não tinha como ver onde o tempo realmente era consumido.

A regra que ficou: meça antes de mexer. Otimização sem medição é superstição.

Caso 2: o cache que mentia

Outro produto resolveu seus problemas de carga com cache agressivo. Funcionou lindamente, até que os dados começaram a ficar desatualizados. Usuários viam saldos antigos, status que já tinham mudado, informações que não correspondiam à realidade.

Performance foi conquistada às custas de correção. E correção, em sistemas que lidam com dinheiro ou com decisões do cidadão, não é negociável.

O aprendizado aqui é sobre trade-offs explícitos. Cache é uma das ferramentas mais poderosas que existem, mas todo cache é uma aposta de que o dado pode ficar levemente velho. Essa aposta precisa ser uma decisão consciente, documentada, com estratégia de invalidação clara, não um remendo aplicado sob pressão.

O erro comum é tratar cache como mágica. Quando o time não entende exatamente o que está sendo cacheado, por quanto tempo e por quê, o cache deixa de ser otimização e vira fonte de bugs difíceis de reproduzir.

Caso 3: o sistema que escalava verticalmente até não dar mais

Há um padrão clássico de empresa em crescimento: o tráfego aumenta, a resposta é contratar uma máquina maior. Funciona uma, duas, três vezes. Até o dia em que não existe máquina maior, ou ela custa absurdamente caro.

Um caso que acompanhei tinha exatamente esse limite. O sistema era monolítico, com estado guardado em memória local, o que impedia rodar várias instâncias em paralelo. Escalar horizontalmente exigia reescrever a forma como a aplicação guardava sessão.

A correção não foi heroica. Foi externalizar o estado, tornar a aplicação verdadeiramente sem estado e colocar um balanceador na frente. A partir daí, crescer virou uma questão de adicionar instâncias, algo que infraestrutura em nuvem resolve quase automaticamente.

A visão estratégica: arquitetura define o teto de crescimento muito antes do código. Decisões tomadas no início, quando o produto é pequeno, determinam o quão caro será escalar quando ele for grande.

O que esses casos têm em comum

Nenhum desses problemas era, na origem, um problema de linguagem ou de framework. Todos eram problemas de diagnóstico, trade-off e arquitetura. Times maduros não são os que escrevem o código mais rápido, são os que entendem onde o tempo é gasto e tomam decisões deliberadas sobre onde investir esforço.

Três princípios atravessam os três casos:

  • Meça antes de otimizar. Sem dados, você conserta o lugar errado.
  • Trade-offs precisam ser explícitos. Toda otimização troca uma coisa por outra. Saiba o que está trocando.
  • Arquitetura é destino. O custo de escalar é definido pelas decisões estruturais, não pelos detalhes de implementação.

A armadilha da otimização prematura, e da tardia

Existe um ditado conhecido na engenharia de que otimização prematura é a raiz de muitos males. É verdade, mas virou desculpa. Times usam a frase para ignorar performance até o problema explodir em produção.

O ponto correto fica no meio. Não otimize o que ninguém usa. Mas defina, desde cedo, limites aceitáveis de tempo de resposta e meça contra eles. Você não precisa otimizar tudo, precisa saber quando algo cruzou a linha do inaceitável.

A reflexão crítica honesta é esta: a maioria dos desastres de performance não vem de falta de conhecimento técnico. Vem de falta de visibilidade e de cultura. Times que não medem, que não conversam sobre carga esperada, que não revisam as consultas mais pesadas, vão repetir os mesmos erros independentemente da stack que usarem.

Performance como vantagem de negócio

Para quem lidera, vale inverter a lógica. Performance não é custo de engenharia, é alavanca de negócio. Um produto rápido converte mais, retém mais e custa menos para operar. Um sistema que escala sem reescrita libera o time para construir em vez de apagar incêndios.

No setor público, o argumento é ainda mais direto: um serviço digital que aguenta o pico de demanda é um serviço que cumpre sua função. Um que cai no dia mais importante destrói a confiança que levou anos para ser construída.

Qualidade de software, no fim, é a soma de muitas decisões pequenas tomadas com seriedade. Performance é uma das mais visíveis, e uma das que mais separam produtos que crescem de produtos que apenas sobrevivem.

Se a sua organização está enfrentando degradação de performance sem entender a causa, o primeiro passo quase nunca é trocar tecnologia, é ganhar visibilidade. Há outros artigos no blog sobre qualidade, arquitetura e escalabilidade que aprofundam esse caminho. Se esse é um problema que tira o seu sono, vale conversar.

Leia também

Performance de software: o que casos reais ensinam sobre qualidade | Matheus Breguêz