Home Posts The Brutal Lessons from Scaling My App from 100 to 10,000 Users...

The Brutal Lessons from Scaling My App from 100 to 10,000 Users in 6 Months

13
0

Six months ago, my app had exactly 103 users. They were mostly friends, a few Reddit strangers, and my mom (who opened it once and asked why the font was so small). I had built the thing over three weekends as a lightweight habit tracker that worked entirely inside Slack. No fancy dashboards, no mobile app. Just a bot that sent you a reminder, you replied with a number, and it drew a tiny ASCII chart of your progress. I thought it was clever. I had no idea if it would ever be a real product.

Then a small tech newsletter featured it. In one day, 300 new teams signed up. My inbox exploded. The server held, barely. Over the next six months, user count climbed past 10,000. Revenue, which started at zero, hit $2,300 a month. The app got featured on Product Hunt. I gave two podcast interviews. I quit my part time freelance gig to focus on it full time.

That sounds like a dream run. It was not. Behind those numbers, I made a series of painful, expensive, and deeply embarrassing mistakes. I almost lost the entire user base twice. I burned through a chunk of savings fixing infrastructure I didn’t understand. I neglected my partner, my sleep, and my sense of perspective. This article is not a victory lap. It is a confession of the brutal lessons I learned while scaling from a hundred users to ten thousand, and the things I wish someone had screamed at me before I started.

The Starting Point: A Slack Bot That Nobody Needed

The app, which I called Habby, began as a personal annoyance. I wanted a habit tracker that didn’t require opening another app. I lived in Slack all day for work, so I wrote a small Node.js script that used the Slack API to send me a direct message each morning. I could reply “yes” or “no” and it would log the streak. Over time, I added a simple chart command (/habby chart) that spit out a monospaced bar graph. A coworker saw it and asked if his team could use it for a fitness challenge. I threw the bot into a new Slack workspace, hard coded his team’s habits, and forgot about it.

For two months, it sat there with 100 or so users, mostly from that one office. The server was a $10 DigitalOcean droplet. The database was a single SQLite file, because I couldn’t be bothered to set up Postgres. There were no backups, no monitoring, and no error logging beyond console.log. I was blissfully ignorant.

That ignorance shattered on a Tuesday morning when the newsletter hit. Within an hour, the droplet’s CPU was pinned at 100%. New sign ups were failing silently because the SQLite file was locked. Slack API rate limits were rejecting my messages. I sat in a coffee shop, frantically SSHing from my phone, trying to restart the process every two minutes while dozens of angry tweets (I didn’t have a support email) piled up. That day taught me the first brutal lesson.

Lesson One: “Scalable” Is Not a Future Problem

When you have a hundred users, you convince yourself that architecture doesn’t matter. You say things like “I’ll optimize when I need to” and “premature optimization is the root of all evil.” Those quotes are true for trillion dollar companies, not for a solo developer whose app just got attention. The moment traffic spikes, your technical debt becomes a ticking bomb.

I spent the next 48 hours rebuilding the backend. I migrated from SQLite to Postgres, not because Postgres was cool, but because SQLite simply cannot handle concurrent writes from hundreds of Slack teams all pinging a bot at the same time. I moved from a single DigitalOcean droplet to two: one for the app server, one for the database. I set up a process manager so the app would restart automatically if it crashed. I added structured logging and wired it into a free tier of an error tracking tool. All of this was done in a panic, with users actively complaining, while I tried to keep the old system limping along.

If I could go back, I would have used Postgres from day one. Not because it’s hard to set up (it takes maybe fifteen minutes), but because the cost of migration under fire is orders of magnitude higher than the cost of doing it right when there are no consequences. I lost dozens of users that first week because their sign ups never completed. They didn’t get an error message. The bot just never messaged them. I had no idea until someone emailed me three days later. That is the second lesson: if your app fails silently, you are invisible to your own failures.

Lesson Two: Silent Failures Are Reputation Killers

After the initial fire, I thought I was safe. The app was running on Postgres, the CPU was calm, and new users were trickling in. But I had not fixed the real problem: I had no way to know when things broke unless a user told me.

A month later, Slack deprecated an API endpoint I was using to look up user timezones. My code didn’t throw an error; it just received an empty response and defaulted everyone to UTC. For two weeks, users in Europe and Asia got their morning reminders at bizarre hours. Some got them at 3 a.m. Engagement dropped. People uninstalled the app. I only discovered it when a user in Germany emailed me with the subject line “Why is your bot waking me up at midnight.”

I immediately built a dead simple health check: a cron job that triggered a test message to a private Slack channel every 30 minutes. If the message didn’t arrive, I got a text via Twilio. This crude heartbeat monitor saved me more times than I can count over the next months. It took me 45 minutes to build, and it would have prevented the timezone disaster entirely.

The larger principle here is that small teams must invest in observability before they invest in new features. You need to know when your app is broken before your users do. It doesn’t require expensive tools. A cron job, a script, and a notification to your phone can be the difference between a bad week and a lost user base.

Lesson Three: Free Users Will Crush You (Without a Funnel)

By month three, Habby had 4,000 free users and exactly 12 paying customers. The free tier was generous: unlimited habits, unlimited teams, a few chart styles. The paid tier added CSV exports and custom branding for $5 per team per month. I thought the free users would upgrade eventually. They didn’t.

My server costs had climbed to $80 a month. Support emails (mostly “why didn’t my chart show up” and “can you add a dark mode”) were eating 10 hours a week. I was effectively working for free. The stress of that reality hit me hard. I started resenting my users, which is a terrible place to be for a founder who claims to care about their product.

The brutal lesson was that free users aren’t customers; they’re prospects. If you don’t have a clear, time bound path to conversion, they will consume your resources and your patience indefinitely. I eventually introduced a 14 day trial for the premium features, and limited free workspaces to 3 habits. My user growth slowed, but my conversion rate tripled. Revenue went from $60 a month to $1,200 almost overnight. I learned that saying no to free users was actually an act of survival, not greed.

Lesson Four: The Solo Founder’s Loneliness Is a Real Risk

Nobody talks about the psychological weight of being a solo developer with a growing user base. You are the only person on call. Every bug is your fault. Every support email, every negative review, every server hiccup lands directly in your lap. I went through a stretch in month four where I didn’t leave my apartment for three days. I stopped exercising. I woke up at 3 a.m. to check server metrics. My partner told me I had become a “ghost who sometimes types angrily at a laptop.” That stung.

I didn’t have a co founder, but I eventually found a lifeline: a small Discord community of other indie developers. Every week, we would jump on a voice call and share our struggles. Nobody was trying to sell anything. We just listened. That group became my pressure valve. It also gave me practical advice: one member suggested a weekly “CEO day” where I didn’t write code, but instead focused on support, content, and planning. That single habit restored some of my sanity.

The lesson here is not “find a co founder,” because that’s not always possible. It’s that building in complete isolation is a recipe for burnout. You need at least one person who understands what you’re going through, even if they’re not on the payroll. The technical challenges of scaling are hard; the emotional ones are harder, and they will quietly destroy your project if you ignore them.

Lesson Five: Shipping Fast Beats Perfect (Every Time)

Around month five, I spent three weeks building a custom analytics dashboard that I was sure users would love. It had beautiful graphs, exportable reports, and a color scheme I tweaked endlessly. When I finally shipped it, I got a polite “cool” from a few users and near zero impact on retention. Meanwhile, a competitor launched a dead simple integration with Google Calendar that took them probably a weekend to build, and it got rave reviews on Product Hunt.

I had fallen into the trap of building what I thought was valuable, instead of asking users what they actually needed. When I eventually surveyed my paying customers, they didn’t ask for analytics. They asked for recurring habits (like “every Monday and Wednesday”) and a way to set habit reminders in a channel instead of a DM. Both features took less than a day each to build and ship. Both immediately reduced churn.

The brutal lesson is that your intuition is often wrong. You are not your user. The only way to know what to build is to ship something small, fast, and measurable. I adopted a rule after that: no feature takes more than two days to get in front of a user. If it does, I break it into smaller pieces. This forced me to launch ugly, functional versions of features, gather feedback, and iterate. It saved me from another three week detour into irrelevance.

What I’d Do Differently Now

Looking back at those six months, the user growth looks like a straight line on a graph, but the reality was a series of near misses and painful corrections. Here is what I would tell myself if I could go back.

Build on boring, reliable tech from day one. Postgres, a process manager, and structured logging are not overkill. They are the floor. You do not need Kubernetes, but you do need a database that handles concurrent writes. The cost of doing it later is measured in lost users and lost sleep.

Set up failure alerts before you need them. A simple health check that texts you when something is broken takes less than an hour. Without it, you’re flying blind. Every minute your app is silently broken, you lose trust that takes months to rebuild.

Design your free tier to convert, not to be generous. Free users who never pay will bankrupt your motivation and your bank account. A time limited trial or a functional but constrained free tier is not hostile; it’s honest. It sets expectations and keeps your business alive.

Protect your mind like you protect your database. Burnout is a bigger threat than any AWS outage. Schedule non coding time. Talk to other builders. Step away from the laptop. Your app needs you functioning, not fried.

Ship fast, then listen. The market will tell you what to build next, but only if you give it something to react to. Long development cycles are a gamble. Short ones are a conversation.

Where Habby Is Now

As of this writing, Habby has 11,200 registered workspaces and about 950 paying teams. Revenue covers my living expenses. The app runs on two DigitalOcean droplets, a managed Postgres database, and a single background worker. I still handle support alone, but I now use a shared inbox tool that helps me stay organized. The system has not gone down in four months. I sleep through the night most nights.

The journey from 100 to 10,000 users was not glamorous. It was full of moments where I wanted to quit. But each failure taught me something concrete about reliability, communication, pricing, and my own limits. If you’re building your own app and watching that user number tick upward, I hope these lessons help you avoid the worst of what I went through. Scaling is not just about servers; it’s about becoming a better operator, one painful mistake at a time.

LEAVE A REPLY

Please enter your comment!
Please enter your name here