Como otimizar seu sistema

Todo sistema acumula dívida técnica com o tempo. Vou te mostrar os pontos que eu olho primeiro quando preciso otimizar um projeto, com foco especial em banco de dados, que geralmente é a maior fonte de gargalo.


Às vezes a gente tá projetando um sistema e cai em algumas ciladas, algumas cascas de banana. Isso acontece principalmente com quem tá criando e projetando o próprio sistema sozinho, mas serve pra qualquer nível de experiência. Nesse post eu vou falar sobre como otimizar um projeto e quais são os pontos que eu olho primeiro pra conseguir fazer essa otimização.

Dívida técnica

Dívida é algo que você faz agora e paga depois. Você faz a dívida hoje, mas não sofre a consequência hoje, ela aparece lá na frente.

Dívida técnica são decisões que você toma agora e que, com o tempo, viram gargalo. Aquilo que era rápido fica lento, e você vai ter que lidar com esse problema. É algo que resolveu uma questão no momento, mas que mais pra frente vai gerar um problema. Cabe a você, enquanto pessoa que arquiteta e organiza o sistema, ter a menor quantidade possível de dívidas técnicas.

Só que isso é inevitável, e não tem como fugir dessa realidade. Um sistema que aguenta 10 usuários não é o mesmo sistema que aguenta 1 milhão de usuários. As decisões técnicas que fazem sentido no começo de um projeto, quando só você e mais uma pessoa acessam, deixam de fazer sentido quando o volume de acesso cresce.

Existe até uma ideia interessante sobre isso: quando um projeto tem menos de 10 a 15 mil linhas de código (contando só o código do seu projeto, sem bibliotecas), você toma um conjunto de decisões técnicas. Quando o projeto passa dessa marca, boa parte das decisões que você tomou lá no começo, você vai querer revisar.

Ou seja, você não vai conseguir eliminar a dívida técnica, mas dá pra reduzir ela e, principalmente, ter consciência de que ela existe. Ter uma dívida técnica calculada, sabendo que ela vai virar um problema quando o volume aumentar, não é um erro. O problema é não saber que ela existe.

Banco de dados geralmente é a maior fonte de gargalo

Não é sempre, mas na maioria dos casos é o banco de dados que puxa o sistema pra baixo. O motivo é simples: o banco de dados é um serviço externo, mesmo que esteja rodando na mesma máquina que a aplicação. E todo banco de dados precisa lidar com pelo menos duas operações, escrita e leitura.

Na grande maioria dos sistemas, a quantidade de leitura é muito maior do que a de escrita. Pensa na home do seu sistema: praticamente tudo que acontece ali relacionado ao banco é leitura. O usuário cadastra alguma coisa ou clica em algo que gera uma escrita, mas a maior parte das consultas que rodam no dia a dia são leituras.

Então, quando você identifica que o banco de dados é o que tá deixando o sistema lento, existem algumas coisas que dá pra olhar pra melhorar isso.

Otimizando o banco de dados

Olhe pras leituras primeiro

Como leitura é a maior parte das consultas que o sistema faz, é ali que geralmente tem mais espaço pra ganho. A regra de ouro é: quanto menos leitura, melhor. Menos leitura significa menos dados trafegando, e dependendo do volume de informação, isso já resolve boa parte do problema.

Existem pelo menos três formas de reduzir a quantidade de leitura no banco.

1. Otimize as próprias queries

Evite fazer subquery sem necessidade. Evite o famoso N+1, que é quando o sistema dispara uma consulta extra pra cada item de uma lista, em vez de trazer tudo numa consulta só. Evite queries complexas desnecessariamente. O objetivo é simplificar ao máximo o que você tá pedindo pro banco, sem trazer mais dado do que precisa.

2. Use cache

Se uma informação não muda com frequência, ou muda de forma esporádica, talvez não faça sentido consultar o banco toda vez que ela é exibida. Pensa numa home que mostra a mesma coisa pra todos os usuários: se isso for um gargalo, você pode usar algum tipo de cache pra não precisar consultar o banco a cada acesso.

Um exemplo comum é usar o Redis. Em vez de ficar lendo o banco de dados o tempo todo pra buscar a mesma informação, você joga esse dado na memória RAM do servidor. Consultar a memória é muito mais rápido do que consultar o banco. Quando o dado original muda, você atualiza ou invalida o cache, seja através de um cron job, de um trigger ou de qualquer outro mecanismo que faça sentido pro seu caso.

3. Aumente o hardware

Se você já otimizou as queries e já colocou cache onde fazia sentido, e ainda assim o banco continua sendo o gargalo, a próxima opção é aumentar hardware: mais memória, mais processamento, mais capacidade pro servidor onde o banco está rodando.

Isso é uma solução válida, mas tem uma diferença importante em relação às duas anteriores. Aumentar hardware não torna o sistema mais eficiente, só dá mais espaço pra ele continuar ineficiente. É um custo que se mantém alto todo mês, porque você não resolveu a causa do problema, só comprou mais tempo.

Por isso a ordem costuma ser: otimizar queries, depois cache, e só aumentar hardware por último. Existe também quem prefira inverter essa ordem quando o sistema já está inutilizável e não tem tempo pra investigar com calma. Nesse caso, aumentar a infraestrutura primeiro pra estabilizar, e só depois voltar pro código pra otimizar de verdade, também é uma estratégia válida.

Resumo

Todo sistema vai acumular dívida técnica, isso é inevitável. O que muda é o quanto você consegue reduzir essa dívida e ter consciência de onde ela está. Quando o gargalo é o banco de dados, que costuma ser o ponto mais comum, a ordem que eu sigo é: olhar pras leituras primeiro, otimizar as queries evitando N+1 e consultas desnecessárias, usar cache pra informações que não mudam com frequência e, só depois disso, aumentar hardware.

Esse processo eu já fiz várias vezes, em sistemas diferentes: otimizei query, usei cache, aumentei hardware, de várias formas diferentes, dependendo do que o sistema pedia. Não é a única forma de otimizar um sistema, mas é o primeiro lugar que eu olho, e geralmente resolve boa parte do problema.