CronPilot est passé d’un repo vide au premier client payant en 21 jours. Voilà la version honnête de ce lancement, y compris la partie où j’ai presque tout arrêté.
LE PLAN
Une semaine pour le coeur, une pour les parties boring mais vitales (auth, billing), une pour le lancement. J’ai time-boxé chaque feature : si ça ne rentrait pas dans une journée, ça ne partait pas en v1.
CE QUI A MARCHÉ
La stack boring. Phoenix + SQLite voulait dire zéro décision infra inutile. Toute l’app tourne sur une machine Fly.io :
def schedule(job, opts \\ []) do
job
|> with_retries(opts[:retries] || 3)
|> CronPilot.Queue.push()
end
Faire payer dès le premier jour a aussi marché. Les utilisateurs gratuits donnaient du feedback poli ; les utilisateurs payants donnaient des bugs énervés et utiles en quelques heures.
CE QUI A CASSÉ
Jour 14. Un deploy a vidé la queue en mémoire et supprimé silencieusement 40 jobs planifiés. J’ai passé une nuit à réécrire le worker autour d’une queue persistante.
Un scheduler qui perd des jobs n’est pas un produit : c’est une machine à excuses.
LES CHIFFRES
21 jours de build, $320 de MRR à la fin du mois, 840 signups, 12 clients payants. Environ la moitié des signups venait du post de lancement.
MOIS SUIVANT
MailForge est déjà en cours, et l’acquisition de ByteBroker a été bouclée le 10 juin, ce qui mérite son propre post. Abonne-toi en bas si tu veux le recap dans ta boîte mail.