Como eu deixei meu site lento e mais caro

Como analisei a lentidão no meu site e corrige isolando cada ponto.

Como eu deixei meu site lento e mais caro
Photo by Nareeta Martin / Unsplash

(Enquanto escrevo esse post, estou deletando instancias na digital ocean...)

Desde que lancei meu novo blog, tem algo que sempre me incomodava nele, e não era o fato de eu nunca ter tirado o favicon do Svelte, era o tempo de carregamento.
Eu fiz um post falando sobre as tecnologias que utilizei para criar meu blog e resumindo foram: Svelt(Sveltkit), Strapi e deploy na Digital Ocean.

Tempo de requisição médio

Começando a investigar as causas exclui o front end da equação, desconfiei do droplet que utilizei, e pensei -Pode estar "gargalando", embora analisando as métricas coletadas, não chegava a tanto, mas resolvi tentar uma coisa, resolvi tirar o banco de dados da máquina e deixa-lo em uma instância propria (um RDS da Digital Ocean), nesse momento, que eu vou acessar a máquina para fazer o dump dos dados eu percebo que não consigo acessar o Postgres. Depois de alguns minutos, verifico as variáveis de ambiente do projeto para verificar as variáveis de ambiente e percebo que eu estava usando SQLITE.

Meme postgres

Como o serviço da DO não dá suporte a esse tipo de base de dados, eu resolvi mudar tudo para Postgres, recriar a base e migrar os dados para poder utilizar o serviço dedicado.
Tive alguns problemas para migrar os dados, o Strapi não oferece uma solução para migrar os dados, embora a estrutura seja totalmente "migravel". Fazer isso manualmente era maçante, então criei uma ferramenta para migrar os dados de SQLITE para Postgres (e vai sair um post sobre já já).

Ferramenta para migrar dados de SQLITE para Postgres

Após todos os dados migrados, configurei o Strapi para utilizar a nova base de dados e comecei os testes, até que de repente ... tive praticamente o mesmo resultado.
Sim, todo esse trabalho e ainda com uma resposta de mais de 1.5 segundos.
Então, resolvi fazer a coisa que deveria ter feito desde o início: desistir Um trace da API o mais detalhado possível.
Definido então e resolvi utilizar o Sentry para me ajudar, e de cara um problema: Não achei o plugin de trace para o Strapi (apenas para captura de erros estava disponível), então la fui eu estudar mais afundo o Strapi para entender como eu poderia implementar o trace.
Algum tempo (e bugs) depois consegui ter o trace funcionando e ao rodar a query eu me assustei quando vi isso:

Trace de uma requisição

Esses 4 segundos foram bem extremos, mas a requisição saiu do local e bateu no banco de dados na DO.
O Sentry tem um detalhamento incrível e me permitiu ver as querys executadas e o tempo que estavam levando, até que cheguei no meu gargalo:

select "t0".*, "t0"."id" from "posts" as "t0" where ("t0"."published_at" is not null) limit $1

Essa query era a minha maior ofensora e se pensarmos bem ela é um simples select * from posts limit 6, então por que demora tanto?
Baixei um client do Postgres e conectei na minha base de dados remota, por que na minha cabeça o problema ja era o Strapi e eu ja estava pensando e substitui-lo, porem iria fazer um teste antes, e esse foi o resultado do teste:

Tempo de query no PgAdmin

Tudo bem, talvez você já tenha entendido tudo agora, ou talvez antes, mas para mim ficou claro agora, tive a sensação de ter parado no tempo e de repente encontrado a resposta, esse GIF ilustra bem o sentimento:

GIF filme Lucy

Vamos rapidamente repassar tudo que fiz até aqui:

  • Identificar a fonte macro da lentidão.
  • Testei localmente para reproduzir o comportamento de produção.
  • Troquei componentes que poderiam ser ofensores (Banco de dados).
  • Trace na aplicação especifica com erro.
  • Isolar e testar separadamente os componentes envolvidos.

E agora vamos ao real problema: A região onde a máquina foi criada vs a região onde o banco de dados foi criado.

Regiões

Por algum motivo, eu criei o Droplet (a máquina) em Amsterdam, isso ja era suficiente para criar toda lentidão de quando eu ainda usava o SQLITE como banco de dados.
Para confirmar essa hipótese, eu utilizei uma ferramenta propria da DO para fazer testes de velocidade e latência:
http://speedtest-ams3.digitalocean.com e esse foi o resultado:

Teste de velocidade

Assim que percebi, rapidamente fui trocar a região, na DO isso não é tão "plugavel" como na AWS, mas o processo foi bem simples: Criar uma Snapshot da droplet atual, mudar a região na Snapshot e criar uma Droplet com base na Snapshot, por fim, bastou eu atualizar o novo IP no DNS do domínio e esse foi meu resultado:

Requisição

Tivemos um ganho de mais de 60% no tempo da requisição!
Isso é fantástico e nesse momento eu fiquei extremamente feliz, todo o processo que durou vários dias foram "pagos" com esse resultado.

Ah e se tiver alguma dúvida ou quiser me xingar por usar SQLITE em produção, fica à vontade nos comentários!

Caso queira criar uma conta na Digital Ocean, utilize esse cupom e ganhe 25 dólares de desconto: https://m.do.co/c/10755563c153