The 3-Month Rule: A Practical Approach to Non-Scalable Coding Strategies
When it comes to building software, many of us have heard the wise words of Paul Graham: “Do things that don’t scale.” However, few seem to discuss how to practically apply this philosophy, especially in the realm of coding.
After spending the past eight months developing my AI podcast platform, I’ve established a straightforward framework to manage unscalable approaches. I call it the “3-Month Rule.” In this framework, each non-scalable solution has a lifespan of three months. At the end of that period, it must either demonstrate its value and evolve into a more robust solution or be discarded.
As engineers, we often aim to create scalable solutions from the outset. We gravitate towards established patterns, microservices, and distributed systems designed to handle large user bases. However, this mindset can be problematic, particularly in startup scenarios where such scalability may represent an unnecessary delay in progress.
My 3-Month Rule compels me to craft simple, straightforward, and often “inefficient” code that gets deployed and provides valuable insights into user needs. Here╬ô├ç├ûs a look at some of my current infrastructure decisions that may seem unconventional but have proven to be quite effective.
Current Infrastructure Hacks: Smart Decisions in Disguise
1. Consolidated to One Virtual Machine
I run my entire platformΓÇödatabase, web server, background jobs, and RedisΓÇöon a single $40/month virtual machine, without any redundancy. Backups are done manually to my local machine.
Although this setup may seem reckless, it has allowed me to gain greater insights into my actual resource needs in just a couple of months. I discovered that my ΓÇ£AI-heavyΓÇ¥ platform only requires about 4GB of RAM during peak usage. The complex Kubernetes infrastructure I nearly implemented would have been managing empty containers. During the few crashes I experienced, I gathered concrete data on the actual issues, none of which matched my initial assumptions.
2. Hardcoded Configurations
I utilize hardcoded configuration values for key parameters, such as pricing tiers and user limits. This approach enables me to quickly search my entire codebase for any configuration item and track changes via Git history with ease.
While developing a configuration service would involve significant engineering hours, I’ve made only a handful of changes in this area over three months. Considering the time saved, it╬ô├ç├ûs a no-brainer.
3. Using SQLite in Production
I











2 Comments
This is a refreshing perspective that emphasizes the importance of prioritizing learning and experimentation over premature optimization. The 3-Month Rule reminds me of the concept of “minimum viable product” (MVP) ╬ô├ç├╢ emphasizing that sometimes, simple and quick solutions can provide invaluable insights that guide future scaling efforts. Your approach to starting small with consolidated infrastructure and hardcoded values allows for rapid iteration and validation, which is especially crucial in startup environments.
Using SQLite in production, for example, might seem unorthodox, but if it suits your workload and accelerates your learning, itΓÇÖs a justified trade-off. The key takeaway is that building scalable solutions from the start can sometimes hinder agility and learning, so applying a disciplined, time-boxed approach like your rule can strike a healthy balance between action and reflection.
Would love to hear more about how you’ve transitioned or plan to transition these solutions into more scalable ones as your platform grows!
This framework elegantly exemplifies the power of pragmatic engineering╬ô├ç├╢prioritizing learning and iteration over premature optimization. The “3-Month Rule” echoes the insights from Lean Startup principles, emphasizing rapid experimentation and validation. Your approach to consolidating infrastructure on a single VM and leveraging hardcoded configs aligns with the concept of minimizing cognitive load and technical overhead during early stages.
Using SQLite in production, while unconventional, can be particularly effective for initial data needs, especially when dealing with a limited user base or when rapid iteration is essential. The key is that it allows you to understand actual usage patterns and data needs without overcomplicating from the outset.
Overall, adopting an intentionally unscalable solution for a fixed period fosters a growth mindsetΓÇövaluing adaptability, learning, and deliberate evolution. This mindset can often lead to more refined, scalable solutions in the future, built on a solid understanding of real-world constraints. ItΓÇÖs a reminder that, in development, sometimes doing less from a scale perspective actually enables us to do more in terms of learning and fast iteration.