Embracing the Unscalable: My 3-Month Approach to Learning Through Imperfection
In the tech-centric world of startups, the mantra “do things that don’t scale,” famously coined by Paul Graham, often gets talked about but rarely explored in the context of actual implementation, especially within the realms of coding. During my entrepreneurial journey with an AI podcast platform over the past eight months, I have devised a straightforward yet effective framework: every unscalable hack I implement gets a life span of three months. After this period, it must either prove its worth and be refined into a scalable solution or be discarded.
Many of us in engineering tend to gravitate towards the creation of scalable architectures right from the outset. We envision grand designs, utilizing intricate patterns, microservices, and distributed systems in anticipation of millions of users. However, in the fast-paced environment of a startup, building code with scalability in mind can sometimes lead to unnecessary delays and excessive resource allocation. The realities of our initial users often reveal that these elaborate plans are not only premature but can be seen as costly procrastination. My three-month rule encourages me to focus on simplicity, delivering functional, albeit “imperfect,” code that provides real insights into user needs.
Insights from My Current Simplistic Infrastructure Strategies
1. Consolidated Operations on a Single VM
My entire tech stack—database, web server, background jobs, and caching—runs seamlessly on a single VM costing just $40 a month. While this may seem reckless at first glance, it has allowed me to gauge my actual resource demands far better than any theoretical capacity document could provide. I’ve found that my AI-centric platform typically peaks at a mere 4GB of RAM, highlighting how a complicated Kubernetes setup would have resulted in wasted resources managing empty containers. When downtime occurs—which has happened a couple of times now—I glean valuable insights into real failure points.
2. Hardcoded Settings for Clarity
In my code, configuration values such as pricing tiers and user limits are directly embedded into the codebase rather than encompassed in complex configuration files or environment variables. This approach, while not conventional, has granted me the ability to swiftly search and track changes in my pricing strategy through Git history. With an average of three changes every three months, the 15 minutes spent redeploying is decidedly more efficient than investing 40 hours in engineering a dedicated configuration service.
3. Using SQLite for Production
Yes, SQLite powers my multi-user