A stack que nos fez atingir R$ 100k de MRR em 9 meses
O quão complexa deve ser uma arquitetura de uma startup early stage?
👋🏼 Bem vindo a edição de número #24 da newsletter do Moa.
⚠️ Antes de começarmos, um breve recado: Me ajude a produzir um conteúdo cada vez mais relevante. Separe alguns poucos minutinhos e toque aqui para responder algumas perguntas. 🙏🏼
Há algumas semanas atingimos um marco importante no Tintim: R$ 100K de MRR em 9 meses de operação!
Para os que não estão familiarizados, MRR é a sigla para monthly recurring revenue, o termo em inglês para faturamento recorrente mensal. Esse é um dos grandes marcos do início da jornada de uma empresa de software como serviço.
Dado o contexto, eu resolvi comentar um pouco sobre a arquitetura de software por trás da nossa solução.
Bora?
Programador não sabe vender
Antes de falarmos da tecnologia do Tintim, eu preciso falar sobre a nossa capacidade de vendas, como programador. O resumo desse assunto é: essa capacidade não existe.
O programador é um executor, por natureza. Além do mais, o programador é uma pessoa pragmática. A natureza do seu trabalho é o foco na habilidade técnica e, especificamente, em transformar uma ideia em realidade.
Dado essa natureza, a mentalidade do programador é, quase sempre, orientada a solução. É justamente essa mentalidade que impede o programador de vender.
Calma, vou explicar…
O programador inexperiente acredita que a qualidade do seu produto está diretamente relacionada a sua capacidade técnica. Usou a melhor linguagem? Então o produto é bom. Usou o melhor banco de dados? Então o produto é bom. Os endpoints respondem a dezenas de milhares de requisições por segundo? Então o produto é bom.
Mas aí eu te pergunto, meu querido amigo programador: Melhor linguagem para o que? Melhor banco para qual situação? Por que o endpoint precisa responder a dezenas de milhares de requests?
Como eu nunca me canso de dizer, tecnologia é meio. A tecnologia é apenas uma ferramenta. O que dita a arquitetura de um software é, primariamente, a natureza do problema que esse software se propõe a resolver.
Sob o ponto de vista de negócio, a qualidade de um software está diretamente relacionada a sua capacidade de resolver o problema. Essa deve ser a única métrica que importa. O software está resolvendo o problema? Então ele é bom, independente de ser um monolito ou um microsserviço.
Ter um software que resolve bem um problema é uma premissa não só para a área de tecnologia mas, principalmente, para a área de vendas. Para vender bem, o produto tem que resolver uma dor que dói bastante. Isso é geração de valor. Por isso, para vender bem, você precisa de uma mentalidade orientada a problema, e não a solução.
E qual o problema que o Tintim resolve?
No Brasil existem 170 milhões de brasileiros que usam o WhatsApp praticamente todo dia. Segundo pesquisas, mais de 5 milhões de empresas possuem contas ativas no WhatsApp Business, a versão do aplicativo voltada para pequenas e médias empresas. Faz sentido, afinal, 83% dos brasileiros já utilizam o WhatsApp para fazer compras.
Esses números foram catapultados pela inclusão digital que ocorreu, principalmente, nos últimos 3 anos. Outro grande fenômeno dessa inclusão digital foi a explosão dos social ads. É aí que o Tintim entra.
Quem trabalha com marketing digital sabe que uma das melhores formas de se vender pela internet é anunciando nas redes sociais. Devido a enorme quantidade de dados que essas redes coletam, as possibilidades de segmentação para o anunciante são praticamente infinitas. "Mas, dentre tantas opções, como saber o que pode dar certo para o meu negócio?"
A prática de quem trabalha com social ads é testar, incansavelmente, até encontrar a segmentação que traga maior retorno financeiro. O mercado do e-commerce, sabendo disso, desenvolveu centenas de formas de fazer essas medições. O mesmo aconteceu para produtos digitais, como livros, cursos e mentorias. Mas o pequeno negócio, que ainda concentra grande parte do seu atendimento comercial no WhatsApp?
Quem vende pelo WhatsApp simplesmente não consegue medir, de maneira simples e eficaz, a performance de suas campanhas. Sem essa medição, é impossível investir sua verba de mídia de forma estratégica. Foi para resolver essa dor que o Tintim nasceu.
O Tintim é a única solução que identifica e rastreia as vendas feitas pelo WhatsApp de forma simples e automatizada. O que o Tintim faz, na prática, é identificar e atribuir de qual anúncio veio determinada conversa. Sabendo isso e sabendo também quais conversas viraram venda, conseguimos traçar a jornada de compras completa do cliente e fazer comparações, identificando quais são as campanhas, públicos e anúncios que trazem lucro e devem ser escaladas.
Resolvendo somente este simples (mas muito doído) problema, a gente conseguiu alcançar os R$ 100k de MRR.
A arquitetura do Tintim
Como eu disse: se você está esperando uma arquitetura super sofisticada, sinto te desapontar. A arquitetura do Tintim é super simples e muito parecida com a que eu usei durante todos os meus quase 15 anos de carreira como programador.
A linguagem principal é Python e o software foi construído todo em cima do framework Django. O Django tem absolutamente tudo o que eu preciso para construir um software como o Tintim. Ele me entrega muita coisa pronta e com qualidade. Além disso, ele é super simples de se usar mas, ao mesmo tempo, altamente customizável.
Não usamos nenhum tipo de mecanismo de client server rendering. Não tem React, não tem Vue, não tem frameworks javascript da moda. Por quê? Dois motivos. O principal é que não temos nenhuma pessoa no time especialista em frontend. Segundo, porque não precisamos desse tipo de complexidade. Aqui no Tintim, usamos a trinca que vem funcionando super bem há, pelo menos, 20 anos: HTML + CSS + Javascript (vanilla). Quando precisamos de algo um pouco mais elaborado, recorremos ao jQuery.
A infraestrutura é bem simples também. Desde a invenção das chamadas plataformas como serviço, eu fujo de montar servidores como o diabo foge da cruz (já já explico o porquê). Por isso, o Tintim está hospedado no Heroku desde o seu início.
No começo usávamos apenas uma máquina hobby e o banco mais básico deles. Era apenas um dyno (a nomenclatura que o Heroku usa para denominar seus contêineres) e tudo rodava nesse dyno. Para processamentos em background, usávamos o Heroku Scheduler. Usávamos também o Papertrail para logs, o Sentry para monitoramento de erros e o New Relic para observabilidade. Tudo no plano free.
Conforme fomos sentindo a necessidade, implementamos um segundo dyno para processar requisições assíncronas. Essa implementação foi feita utilizando o Celery para o processamento das tarefas e o SQS para gestão da fila. Muita gente, nesse caso, gosta de usar o RabbitMQ para a fila, pois o SQS traz uma série de limitações ao Celery. Ainda sim resolvemos ir de SQS porque essas limitações não interferem nos nossos casos de uso e, usando o SQS, a gente ganha uma grande vantagem: menos um servidor/serviço para cuidar.
Recentemente implementamos um terceiro dyno para separar e processar exclusivamente as mensagens de WhatsApp dos nossos usuários. Também aumentamos os dynos do plano hobby para o plano profissional. Aumentamos o banco também (até uns 6 meses de empresa rodávamos num banco de $9/mês).
Durante a operação, alguns gargalos começaram a surgir em partes específicas do sistema. Para resolver esses problemas, a gente isola essas implementações em pequenos microsserviços, utilizando Lambda + API Gateway, da AWS (tudo serverless, ou seja, menos um serviço para cuidar).
A única infraestrutura gerenciada internamente que tivemos que implementar foi para os serviços de WhatsApp. Começamos com uma máquina simples na Digital Ocean e depois fizemos uma segunda instância na AWS, porque ganhamos um crédito de $5k por lá (meu amigo Bruno Okamoto que descolou). Infelizmente não deu pra fugir de fazer essa implementação. Inclusive, essa é, de longe, a parte que mais nos dá trabalho de manutenção hoje em dia.
O Tintim começou da forma mais simples possível. Não tinha microsserviços, não tinha processamento assíncrono, não tinha infraestrutura gerenciada no software principal. Não tinha porque não precisava. Agora, o que sempre teve foi qualidade.
Desde o começo o código foi desenvolvido seguindo boas práticas. Sempre tivemos a preocupação em separar responsabilidades. Sempre tivemos a preocupação em escrever código simples e padronizado. Sempre tivemos, principalmente, a preocupação em escrever testes para TODAS as implementações. A simplicidade não tem relação nenhuma com (falta de) qualidade.
Sempre nos preocupamos também em manter um bom fluxo de trabalho. A partir do momento que mais de uma pessoa começou a escrever código, implementamos uma boa organização de branches. Também começamos a implementar novo código somente via pull requests.
Sempre nos preocupamos, também, em deixar o processo de deployment o mais automatizado possível. Ele nunca foi 100% automático (e nem sei se um dia será), mas sempre foi super simples de fazer. Apenas um comando e o novo código está entregue em produção (caso os testes tenham passado, óbvio). Mais importante que desenvolver rápido é entregar código rápido na mão do usuário.
Importante ressaltar que grande parte dessa agilidade se dá pelo fato de usarmos uma plataforma como o Heroku. A gente não cuida de banco, não cuida de log, não cuida de backup, não cuida de máquina, não cuida de disponibilidade. Tudo isso é terceirizado.
"Ah, mas o Heroku é muito mais caro do que montar uma máquina na Digital Ocean". Caro mesmo é o custo de oportunidade de não entregar valor para o seu usuário porque você está desperdiçando tempo tendo que dar manutenção em servidor. Enquanto você não tem um DevOps bom no time, esquece esse papo de montar máquina.
O Tintim é um software "simples", tecnicamente falando. O maior desafio dos próximos meses será o aumento de acessos e, consequentemente, de processamento. Esses são os desafios padrão de qualquer software e já existe muita literatura e ferramentas para lidar. Se o desafio é simples, não há porque implementar um codebase complexo.
Esse codebase nos trás problemas? Sem dúvidas, afinal, software em produção é sinônimo de software dando problema. Mas, o mais importante, é que essa é uma stack que o nosso time possui experiência e maturidade para lidar. Existem outras stacks tão eficientes quanto essa para o nosso contexto. Mesmo assim, decidimos seguir pelo o que a gente já conhecia. Lembre-se: a melhor linguagem de programação é aquela que o time domina.
Se houvesse a demanda, sem dúvidas recorreríamos a uma solução mais sofisticada. Se a nossa interface fosse mais complexa e demandasse uma ferramenta que lide bem com reatividade, implementaríamos um framework estilo React sem pestanejar. Não fizemos isso porque não precisa. Simples assim.
Somos uma empresa bootstrapped (ou seja, que não recebeu aporte financeiro de fundos de investimento). Devido a essa limitação de recursos, precisamos escolher muito bem nossas batalhas. Para você ter uma ideia, a gente ainda não tem integração com o gateway de pagamento. Assim que o cliente faz o pagamento, pinga um alerta no nosso Discord e o time de atendimento entra em contato para fazer os trâmites e liberar o acesso na ferramenta. É a forma mais efetiva? Obviamente não. Mas existem diversas demandas mais importantes do que automatizar esse fluxo, nesse momento.
Por sermos bootstrapped, nossa fonte de financiamento é o dinheiro do cliente. Para conseguir o dinheiro do cliente, é preciso resolver o seu problema e deixá-lo satisfeito. Se eu consigo resolver o problema do cliente usando uma planilha, ao invés de um banco de dados, por exemplo, eu vou usar a planilha. No fim das contas, a tecnologia é meio, e não fim.
O objetivo desse texto é justamente esse: te mostrar que tecnologia é meio, e não fim. Desculpe te desapontar, caso você esperava uma arquitetura super complexa (para mim já está complexo demais rs). O que eu quero te mostrar é que construir software de qualidade está ficando cada vez mais simples e barato.
Hoje, mais do que nunca, ganha o jogo quem sabe vender melhor. O principal fundamento que vai te fazer vender bem não é a tecnologia, mas sim a capacidade de gerar valor. Aprenda a resolver o problema do seu cliente, independente de qual será a tecnologia utilizada. Vende melhor quem resolve o problema do cliente.
🫡 Esta foi mais uma edição da newsletter do Moa.
👋🏼 Bem vindos aos 41 novos leitores desde a semana passada. Já somos 907 programadores estratégicos!
👊🏼 O meu objetivo com essa newsletter é ajudar programadores que desejam desenvolver uma visão mais estratégica.
Além disso, pretendo também compartilhar outras coisas, como um pouco dos bastidores da construção de um negócio SaaS, as minhas opiniões e meus aprendizados. A ideia geral é ser uma documentação pública e estruturada dos meus pensamentos e aprendizados ao longo dos anos.
Portanto, se você se interessa por soft-skill, desenvolvimento pessoal, empreendedorismo e opiniões relativamente polêmicas, sugiro que você se inscreva para receber as próximas edições. ⬇️
📈 Se você é inscrito e quer me ajudar a construir uma newsletter cada vez mais relevante, separe alguns poucos minutinhos e me ajude respondendo algumas perguntas. Toque aqui para responder.
🗣 Se você tem alguma crítica, sugestão ou quer bater um papo, toque aqui e me chame no WhatsApp.
.
🙏🏼 Obrigado pelo seu tempo! Compartilhe este post com um programador que deseja empreender, ou quer/precisa desenvolver soft-skills para evoluir na carreira. ⬇️
Estou iniciando na carreira de DEV agora, gosto muito da parte tecnológica, as vezes estudo sobre com finalidade em si mesma, além disso, também gosto muito da parte de negócio. Então desde o dia ZERO já vou liderar minha carreira com essa visão, tecnologia é meio.
Obrigado pelo conteúdo.
Parabéns Moa. Estão indo no caminho certo. Foco no que é mais importante.
Para mim tudo se resume em "escolher muito bem nossas batalhas" como você mesmo disse.
Torcendo por vocês!