Embracing the 3-Month Rule: My Approach to Non-Scalable Solutions in Software Development
In the tech startup realm, there’s a well-known mantra from Paul Graham that encourages us to “do things that don’t scale.” Yet, the conversation often halts at that statement, leaving many to wonder: how do we actually put it into practice, particularly in coding?
Having spent the past eight months developing an AI podcast platform, I’ve devised a straightforward framework for navigating this challenge: each non-scalable solution earns a lifespan of three months. After this period, it must either demonstrate its value and merit a comprehensive build-out or be discarded.
As engineers, we tend to gravitate towards scalable solutions right from the outset. We are well-versed in building robust architectures—think microservices and distributed systems—designed to support millions of users. However, this approach often represents a big company mindset, which may not be suitable for a startup environment.
In many cases, focusing on scalability at this stage serves as an expensive form of procrastination. Why invest time in optimizing for hypothetical users and resolving potential issues that may never arise? My 3-month rule compels me to embrace simplicity and directness in my coding. This allows me to learn exactly what my users need, without overcomplicating the initial process.
Innovative Infrastructure Hacks: Practical Insights from My Experience
1. Consolidating Services on a Single VM
I run my entire platform—including the database, web server, and background jobs—on a lone virtual machine that costs $40 a month. While it lacks redundancy and relies on manual backups to my local system, this setup has proven invaluable.
Within just two months, I accumulated profound insights regarding my resource requirements. For instance, my platform’s peak memory usage has been around 4GB. The elaborate Kubernetes structure I contemplated would have wasted time managing empty containers.
When the system crashes—twice thus far—I gain real data about the root causes, revealing unexpected points of failure.
2. Hardcoded Configuration
Instead of utilizing configuration files or environment variables, I opted for hardcoded constants scattered throughout my codebase. This setup means that any change necessitates redeployment, but it comes with significant advantages.
By embedding configuration values directly within my code, I can quickly search my entire codebase for any parameter. Each price modification is tracked in Git, supporting clear version history. In the last three months, I’ve made only