Embracing the Unscalable: A Practical Approach to Software Development
In the world of startups, there’s a well-known piece of advice from Paul Graham that resonates deeply: “Do things that don’t scale.” But while many discuss this principle, few illustrate how to apply it in the coding landscape effectively.
Over the past eight months, while developing my AI podcast platform, I’ve implemented a straightforward framework: every unscalable solution is given a three-month lifespan. After this period, the task either demonstrates its worth and evolves into a robust solution or it is retired from the project.
As software engineers, we are often conditioned to prioritize scalable solutions from the outset—think microservices, distributed systems, and intricate architecture designed for millions of users. However, for a startup, this approach can turn into costly procrastination, focusing on potential users who might never come.
My three-month rule compels me to create simple, albeit imperfect, code that can be deployed quickly. This hands-on experimentation provides invaluable insights into what users genuinely need.
Current Infrastructure Approaches: Emphasizing Learning Over Perfection
1. Consolidated Resources
Imagine having your database, web server, background jobs, and caching all running on a single $40/month virtual machine (VM). While this setup lacks redundancy and relies on manual data backups, its simplicity has allowed me to gauge my actual resource requirements swiftly. Not only did I discover that my resource usage peaks at 4GB of RAM, but each time it crashes—and it has—provides real learning opportunities about system weaknesses.
2. Direct Code Values
In my codebase, crucial configurations are hardcoded, like so:
python
PRICE_TIER_1 = 9.99
PRICE_TIER_2 = 19.99
MAX_USERS = 100
AI_MODEL = "gpt-4"
By avoiding the complexities of configuration files or environment variables, I’ve streamlined the process of updating values. Each price adjustment becomes a straightforward task that takes mere minutes rather than the lengthy process of building a configuration management service, which I’ve only needed to do a handful of times.
3. SQLite for Multi-User Access
Yes, I opted for SQLite to manage my web app’s multi-user environment, which has proven surprisingly effective. With a mere 47MB database, it comfortably supports 50 concurrent users. This decision was illuminated by discovering that 95% of my access patterns consist of