Embracing the 3-Month Rule: A Pragmatic Approach to Non-Scalable Solutions
In the world of startups, particularly in tech and software development, there’s a familiar mantra often attributed to Paul Graham: “Do things that don’t scale.” However, the practical application of this wisdom in coding practices often goes unaddressed.
As I have journeyed through the development of my AI podcast platform over the past eight months, I’ve stumbled upon a framework that has significantly guided my approach: implement every non-scalable hack with a lifespan of three months. After this period, each solution must either demonstrate its value and transition into a fully-developed system or be discarded.
Understanding the Dilemma
Traditionally, engineers are trained to focus on scalable solutions from the outset. This includes building various architectural patterns like microservices and distributed systems designed to support millions of users. Such thinking may work well in larger organizations but often leads to wasted resources in a startup environment.
In a startup, dedicating time to scalable code can sometimes feel like a costly form of procrastination. Rather than optimizing for hypothetical future users and addressing theoretical problems, my 3-month rule encourages me to deploy straightforward, albeit imperfect, solutions that provide immediate user feedback and tangible learning experiences.
My Ingenious Infrastructure Hacks and Their Value
1. Consolidated Services on a Single VM
I chose to run my database, web server, background jobs, and Redis all on a single $40/month virtual machine, sacrificing redundancy for simplicity. This approach has been invaluable; in just two months, I gained insights into my actual resource demands that traditional capacity planning documents could not have provided. For example, I discovered my resource-intensive platform peaks at just 4GB of RAM, which could have led to unnecessary complexities if I had opted for a more elaborate setup.
When issues arise (and they have), I’m able to identify the root causes effectively and learn from them.
2. Hardcoded Configuration
Instead of using config files or environment variables, I’ve opted for hardcoded constants throughout my application. This method allows me to effortlessly search through my codebase and track changes in my git history. Although it may seem inefficient, the occasional redeployment required—only three times in three months—has proven far more efficient than dedicating a week to build a configuration service.
3. Utilizing SQLite in Production
Running SQLite for a multi-user web app might seem unconventional, yet it has functioned