15 Minutes vs. 3 Weeks: The Hidden Work Behind a Quick Fix

I finally gave up on talking to my GCP Cloud SQL instance while sitting at a coffee shop, watching my connection drop every few minutes like it was trying to escape a bad relationship. Even after tweaking network settings and firewall rules, it remained unreliable at best and infuriating at worst.

On top of that, I’ve been trying to optimize costs, and even a baby MySQL instance on GCP costs around $5 a day—which, if I didn’t absolutely need to spend, I wanted to avoid. So, I decided it was time to bite the bullet and set up MySQL locally.

Setting up MySQL locally wasn’t a one-click fix. It took a couple of hours to install MySQL via Homebrew, configure the necessary permissions, and create database dumps. Most of this was one-time setup—things like properly configuring MySQL user accounts and adjusting permissions, which weren’t specific to integrating with Django and my environment. However, once the groundwork was done, actually connecting MySQL to my platform—the part that mattered for my day-to-day workflow—took just 15 minutes. A few targeted configuration tweaks, a couple of Docker adjustments, and it was seamlessly running within my local development setup.


The Immediate Problem: Running MySQL Locally

I hit a point where I needed MySQL running on my local machine so I wasn’t dependent on my cloud instance. It should have been a straightforward task:

  1. Install MySQL locally.
  2. Configure it to match my cloud settings.
  3. Point my app to the new database.

However, reality is never that simple.

As I started configuring MySQL, I realized that small things were getting in my way—environment variables weren’t set up cleanly, hardcoded values were still lurking in the config, and my Docker setup wasn’t as portable as I had assumed.

This wasn’t just about running MySQL locally—it was exposing all the architectural decisions I had made up to this point.


The Hidden Pre-Work: Why This Wasn’t a 15-Minute Fix From the Start

A few weeks earlier, I had gone through a major cleanup process. At the time, it felt like I was just tidying up, but it turned out to be the key factor in making this MySQL setup painless.

1. Eliminating Hardcoded Values

Initially, my setup relied on a single .env file, which worked—until it didn’t. As my system evolved, I found myself needing multiple environment files to manage different configurations (I now have four). This also led to maintaining separate Docker Compose configurations—one for local development, one for GCP—and individual Dockerfiles for testing services in isolation. These weren’t just conveniences; they became essential guardrails as the project grew.

2. Modularizing Database Connections

Instead of initializing a new connection in multiple places, I had refactored my app to use a single, reusable connection module. This meant that once I pointed this module to my local database, the whole app followed suit.

3. Dockerizing for Portability

I had set up a Docker-based local development environment, ensuring that MySQL, Redis, and Django were all properly containerized. This removed dependencies on local installations and made switching between environments seamless.

These changes weren’t specifically done for MySQL, but they turned out to be exactly what I needed to get MySQL running locally with minimal effort.


The Bigger Takeaway: Real Speed Comes from Deep Work

The real insight from this experience wasn’t about MySQL at all—it was about*how foundational work enables rapid execution later. If I had attempted this same task three weeks earlier, it would have taken me days, not minutes.

This is a recurring theme in software development and AI-augmented work:

  • The speed you see in the moment is an illusion.
  • The real speed comes from the deep work you did beforehand.

Had I skipped the refactoring process, I might have been able to hack together a MySQL setup that worked—but it would have been brittle, full of workarounds, and difficult to maintain.

Instead, I had unknowingly laid the groundwork for a much smoother experience.


Final Thoughts

This wasn’t just a MySQL fix—it was a lesson in why investing in strong foundations matters. The time spent cleaning up my codebase, making my configurations flexible, and structuring my database connections properly didn’t just make this task easier—it made future iterations easier, too.

So next time something takes way longer than expected, consider this: you might not be just solving the immediate problem. You might be setting yourself up for real speed later.

And that’s the kind of optimization that actually matters.