Embracing the 3-Month Rule: A Pragmatic Approach to Unscalable Development
In the startup landscape, renowned entrepreneur Paul Graham famously advised entrepreneurs to “do things that don’t scale.” While this wisdom is widely acknowledged, there’s a surprising lack of discourse on how to effectively implement this philosophy in the realm of software development.
Having spent the past eight months developing my AI podcast platform, I’ve devised a straightforward framework: each unscalable tactic I adopt is given a lifespan of three months. At the end of this period, it must either demonstrate its value and evolve into a more robust solution or be discarded.
Why Traditional Development Approaches Can Fall Short
As engineers, we are often conditioned to prioritize scalable solutions right from the outset. We delve into design patterns, microservices, and distributed systems—techniques that are optimal for handling millions of users. However, this mindset can be counterproductive for startups. Often, scalable coding becomes a form of costly procrastination as we attempt to anticipate the needs of future users who may never materialize. My 3-month rule encourages me to create straightforward, if imperfect, code that can be deployed immediately, allowing for valuable insights into real user needs.
Insights from My Current Development Hacks
1. Consolidated Infrastructure on a Single VM
I currently host my entire application stack—including the database, web server, and background jobs—on one affordable $40/month virtual machine (VM). While this setup lacks redundancy and relies on manual backups, it possesses a hidden brilliance. In just two months, I’ve gained invaluable insights into my resource requirements. For instance, it turns out my AI-centric platform only spikes to 4GB of RAM. The intricate Kubernetes architecture I considered would have been a waste of resources managing idle containers. Crashes are informative; they reveal unexpected vulnerabilities rather than the anticipated issues.
2. Hardcoded Configuration Values
My configuration values, such as subscription prices and user limits, are hardcoded directly into the application. There’s no complex configuration file or a sea of environment variables; rather, constants reside throughout the codebase. Although this approach might seem primitive, it allows me to quickly locate and track configuration changes through Git history. With only three updates in three months, this method saves significant engineering time—my 15 minutes of redeployment is far more efficient than a week spent on building a configuration service.
3. SQLite as My Production Database
Surprisingly, I’ve chosen to run