Embracing the Imperfect: My 3-Month Rule for Non-Scalable Coding
In the realm of tech entrepreneurship, Paul Graham’s mantra, “Do things that don’t scale,” often takes center stage. Yet, the conversation rarely delves into the nitty-gritty of how we can effectively put this principle into practice within our coding endeavors.
Having spent the last eight months developing an AI podcast platform, I’ve designed a pragmatic approach to executing unscalable tactics: each hack is permitted a lifespan of just three months. After this period, it either demonstrates its worth and is refined for better scalability, or it is discarded.
As engineers, we are typically conditioned to pursue scalable solutions from the outset. We focus on best practices, intricate design patterns, and advanced systems architecture capable of accommodating millions of users. However, this is often the mindset of larger companies, whereas startups may find that chasing scalability too soon leads to costly delays. My 3-month rule compels me to prioritize simplicity and speed of delivery, allowing for genuine feedback from users and insights into their true needs.
Current Infrastructure Insights: Why My Approach Works
1. Consolidated Operations on a Single VM
Running a database, web server, Redis, and background jobs all on a single $40/month virtual machine may seem reckless, but it’s revealing vital lessons. This approach has enabled me to understand my resource needs more effectively than elaborate planning could have. For instance, I discovered that my “AI-heavy” platform operates well within a 4GB RAM requirement. The intricate Kubernetes setup I almost adopted would have led to managing untapped containers. Furthermore, experiencing the occasional crash provided valuable insights into the actual points of failure—often surprising ones.
2. Direct Configuration via Hardcoded Values
Instead of relying on configuration files or environment variables, I’ve embedded constants directly in the code. Changes are straightforward—alter a line and redeploy. This might sound inefficient, but it simplifies tracking adjustments through git history and ensures that every modification is thoroughly reviewed. To date, I’ve changed configurations just a few times, saving considerable engineering hours.
3. Using SQLite for Production
Admittedly, I employ SQLite for a multi-user application, and it performs exceptionally well with just 47MB in size, handling 50 concurrent users effortlessly. This choice has taught me that in my case, where 95% of database interactions are read operations, SQLite is more than sufficient. If I had default