Como eu deixei meu site lento e mais caro
Como analisei a lentidão no meu site e corrige isolando cada ponto.
(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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/th0ouhwf5340as05lllz.png)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t13c3yem6cs4ol2ep4ro.png)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9h5bj17reogsxw216yn.png)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1n5uqxy3dvrxd3pwz9xx.png)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fxmzsdfhntd385vzfgx4.png)
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:
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lmoeq0z95w0teq87ow5c.png)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45loarh961uoyqkuedbz.png)
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ksjkmlom2oukn67k9l7g.png)
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