De 5k para 15k usuários: as decisões de arquitetura para criar um Saas "canivete suíço" com infra enxuta.
Todos nós estamos acostumados a usar várias ferramentas para resolver pequenos problemas do dia a dia. Uma ferramenta para encurtar URLs, outra para agrupar links, outra para gerar QR Codes, e por aí vai...
Pensando sobre alguma oportunidade em cima dessa fragmentação de ferramentas, criei o dashy.me — uma plataforma que centraliza essas utilidades e em breve muitas outras em um único lugar, funcionando como um canivete suíço digital.
Mas o principal desafio desde o planejamento da aplicação, não foi a regra de negócio, e sim em como manter os custos de infraestrutura no chão sem o serviço engasgar. O caminho fácil para resolver problemas de performance seria escalar o servidor e utilizar recurso em cloud. Mas de inicio, preferi ir por outro caminho e tentar extrair o máximo da minha stack.
A fundação: Python, Rust e pragmatismo
Fui pragmático na escolha das tecnologias. O core do backend é em Python (Flask). Escolhi porque é uma linguagem que domino, o que me permiti focar no produto e resolver problemas futuros com mais agilidade. Utilizei Redis para gerenciar o cache, dar velocidade e para aliviar o peso das requisições ao banco.
Como a plataforma está agregando muitas funções, precisei lidar com processamento em background (como analytics, anlise de requisições, e afins) sem estourar a RAM da VPS. A solução foi escrever os workers em Rust. O Python me dá velocidade de desenvolvimento na regra de negócio, e o Rust me dá eficiência bruta no background. Tudo isso em cima plano gratuito da Cloudflare, que faz o trabalho pesado de cache global e algumas partes de segurança. Inclusive, o plano gratuito da Cloudflare é um monstro que nem todo mundo sabe como aproveitar toda sua capacidade, é incrível o que se pode fazer se estudar bem todas as funções que eles disponibilizam.
Segurança direto na fonte contra exploits: PostgreSQL e RLS
Para o banco de dados, a escolha óbvia foi o PostgreSQL. Mas eu não escolhi apenas pela robustez que é o argumento que muita gente usa. O grande trunfo pra é utilizar o RLS (Row-Level Security) pensando como uma última de linha de defesa.
Como o dashy.me é um SaaS multi-tenant (vários usuários na mesma base), a proteção dos dados é crítica. O RLS me permitiu mover grande parte da cama de responsabilidade de segurança da aplicação direto para o banco de dados. A ideia é simples: se, no pior dos cenários, ocorrer alguma exploração de vulnerabilidade no backend (um bypass de autenticação, uma injeção, etc.), o atacante não consegue extrair o banco inteiro.
Ele vai esbarrar nas políticas do próprio PostgreSQL, que simplesmente não vai entregar as linhas que não pertencem ao contexto do usuário que está logado. Isso limita drasticamente o raio de qualquer ataque, trazendo uma robustez absurda e me fazendo dormir muito mais tranquilo.
O gargalo do Proxy: Nginx Proxy Manager vs. Traefik
O maior aprendizado de performance, no entanto, veio da porta de entrada. No início, eu estava usando o Nginx Proxy Manager (NPM). É uma ferramenta incrível e uso para muitos projetos no meu homelab, mas comecei a notar um problema: as regras padrões dele estavam limitando meu RPS (Requests Per Second).
Quando a aplicação chegava perto da marca de 5.000 usuários, começava a se formar uma fila de requisições e a latência subia de ms para segundos.
Eu tinha algumas opções: gastar horas lutando contra as configurações padrões do NPM, customizando tudo na mão para tentar tunar a performance, usar nginx cru ou outro sistema que rode por cima dele como o OpenResty, e a terceira, que foi a que escolhi: buscar uma ferramenta que lidasse melhor com o meu cenário. Como a minha infraestrutura é 100% baseada em containers Docker, resolvi migrar para o Traefik.
O resultado foi imediato. O Traefik funciona superbem de forma nativa com o Docker e entregou um desempenho muito superior logo de cara. Sem precisar de muitas configurações, a aplicação passou a aguentar mais de 15.000 usuários de forma fluida, simplesmente por usar a ferramenta certa.
Planos futuros
A minha ideia é continuar agregando ferramentas que "melhorem a qualidade de vida na web", meio que deixar tudo em único local sem você precisar sair por ai pesquisando.
Esse é meu primeiro projeto solo que é lançado e queria compartilhar essa experiencia com vocês.
Uma das minhas grande preocupações é a segurança da aplicação, como vocês costumam lidar com essas questões iniciais de infra e segurança? Vocês utilizam também o RLS do Postgres como essa "camada de proteção" contra exploits?