Embracing the 3-Month Rule: A Practical Guide to Building Unscalable Solutions
In the entrepreneurial world, one piece of advice often echoed by startup guru Paul Graham is, “Do things that don’t scale.” However, the implementation of this principle, especially in the realm of software development, remains a topic that often goes unaddressed.
Having spent the past eight months developing my AI podcast platform, I’ve discovered a straightforward yet effective strategy: every unscalable solution is given a lifespan of three months. After this period, it must either demonstrate its worth and be refined into a full-fledged feature or be discarded.
Rethinking Scalability in Startups
As engineers, we are conditioned to prioritize scalable solutions right from the start—making use of advanced architecture, from microservices to distributed systems, intended to support millions of users. However, this mindset often aligns more closely with large companies rather than startups, where the pursuit of scalability can turn into costly delays.
In a nascent stage, focusing on scalability can become an exercise in optimizing for hypothetical users and solving theoretical issues. My 3-month rule encourages me to write simpler, more immediate solutions, often deemed “bad” code that can be deployed now to reveal actual user needs.
Current Practical Solutions: The Smart Side of Simplicity
Here’s an overview of my current infrastructure hacks and the surprising advantages they offer:
1. All Operations on a Single Virtual Machine
Currently, I run everything—a database, web server, background jobs, Redis—on a single $40/month virtual machine. While this lack of redundancy might seem risky, it has allowed me to gain invaluable insights about my resource requirements.
After two months of operation, I discovered that my platform’s peak usage only reached 4GB of RAM. The complex Kubernetes setup I nearly implemented would have only been managing idle resources. When the system crashes—which it has on two occasions—I glean real data about system failures, often revealing unexpected issues.
2. Hardcoded Configuration Values
Instead of using separate configuration files or environment variables, I hardcode key values like pricing and user limits directly into the code. While this might seem inefficient, it has its benefits.
With a simple grep command, I can easily search for configuration values throughout my codebase, and every change I make is documented in git history. Transitioning to a designated configuration service would require substantial development time, yet in three months, I’ve modified