The 3-Month Framework: A Practical Approach to Unscalable Solutions in Software Development
Paul Graham famously encourages entrepreneurs to “do things that don’t scale,” yet the implementation of this principle in coding seldom receives the attention it deserves. During the eight months of developing my AI podcast platform, I’ve established a straightforward framework: every temporary, unscalable hack receives a lifespan of three months. At the end of this period, based on performance and user feedback, it either evolves into a robust solution or is retired.
The Scalable Dilemma
As engineers, we often feel pressured to architect scalable systems right from the start. Concepts like microservices, distributed systems, and sophisticated design patterns are the hallmark of scalable thinking, intended to accommodate millions of users. However, in the startup landscape, prioritizing scalability too early can lead to costly delays and irrelevant optimizations. My three-month rule compels me to focus on simple, effective code that encourages rapid learning about user needs rather than creating elaborate but unnecessary infrastructure.
Ingenious Hacks in My Current Setup
Here’s a look at my current infrastructure hacks, which may seem unorthodox but serve a purpose:
1. Single VM Architecture
All components of my platform—database, web server, and background jobs—reside on a single, $40/month virtual machine without redundancy. While this may sound risky, this approach has illuminated my genuine resource requirements more effectively than any formal planning documentation. For instance, I learned that my AI platform peaks at just 4GB of RAM, revealing the superfluity of a complex Kubernetes setup that I initially considered.
2. Hardcoded Configurations
No environment variables or configuration files here; parameters like pricing tiers and user limits are hardcoded. This might appear inefficient, but it allows for quick look-ups across my codebase and easy tracking of changes via Git history. In three months, I’ve adjusted these values only thrice, saving an extraordinary amount of engineering time in the process.
3. Running SQLite in Production
By utilizing SQLite for my multi-user web app, I discovered that my database is only 47MB yet can effortlessly manage 50 concurrent users. This experiment revealed that my data access patterns skew heavily towards reads rather than writes, making SQLite the ideal choice for my current needs. Had I started with Postgres, I would have been bogged down in unnecessary optimization tasks.
4. Simplified Deployment with Git
Adopting