Skip to content
4 min read

Winter Database Clean-Up

Winter Database Clean-Up

Imagine you're running a restaurant. When you first start, you have a single fridge in the kitchen. As you grow and add more dishes to your menu, you add more fridges. One for vegetables, one for meat, one for drinks.

It works, but your kitchen is getting cramped. Eventually, you realize it might make more sense to have one large, industrial cooling room instead of dozens of small fridges.

That's exactly the journey I've been on with Magic Pages lately - just with databases instead of fridges.

A few weeks ago, I was looking at the statistics of Magic Pages' infrastructure. Something caught my eye: most of my server memory was being used by databases.

It kinda works like this: Each customer website had its own small database, running on its own, taking up its own slice of memory (for the technical people among you: a Kubernetes StatefulSet). Think of it like those restaurant fridges. Each one needs power, takes up space, and needs maintenance. Just like each individual database needs memory, processing power, and regular updates.

This wasn't exactly news to me. I knew this day would come. Hitting a new memory limit? Let's add a new server to it. But...Magic Pages grew to the point where around 70-80% of memory was used by databases.

Instead of combining fridges, I just kept adding new ones. Why? Because it was easy. It was the "Call up the next appliance store and order a new fridge"-solution, rather than planning a whole construction project to add a walk-in cooler. That's kind of the dimensions we're talking about.

It wasn't my first attempt at solving this problem though. About a year ago, I tried to set up a centralized database system. But back then, I wasn't as experienced with Kubernetes, the technology Magic Pages is using. I was just getting to know that powerful toolset, like a chef learning to use professional kitchen equipment.

The result? I spent more time managing databases than actually improving Magic Pages. It was overwhelming. As a solo founder, you quickly learn that your time is your most precious resource. And spending it all on database management? That wasn't sustainable. But sometimes, failure is the best teacher.

Fast forward to today. After working with Kubernetes for quite a while, I've grown more comfortable with the technology - especially with tools that can handle complex tasks automatically (Operators, anyone? ๐Ÿ˜).

But I didn't just jump in. I ran experiments. Small scale tests. What happens when a database server crashes? What if data gets corrupted? I needed to be sure this would work. When the experiments looked promising, I ran the numbers and found the right servers that could handle my needs for quite some time into the future.

But here's the real challenge. Setting up new servers is one thing. But moving customer data? That's a whole different dimension. Imagine trying to move all the food from your small fridges to the new cooling room - while the restaurant is open and serving customers. You can't just tell everyone to take a chill pill and not serve food for a few hours. Everything needs to keep running smoothly.

In my world, it meant that I couldn't just take backups from the middle of the night and restore them into the new database cluster. Customer data is always changing. Blog posts are being published, members are signing up, newsletters are being sent. What was "new" at 2am when the backups ran, is horribly outdated when I wake up to run the migration.

So, the moving data had to happen live - one second a Ghost site runs on the old system, the next on the new one. Without anybody noticing.

I worked on an automated migration workflow for around a week โ€“ and it has been busy for the last couple of days. Always supervised. Moving databases is such a delicate task that I didn't want to let that happen overnight while I was asleep. It had to happen when I could keep an eye on its progress.

And tadaaa. It's done. Nearly 400 customer sites were migrated โ€“ and I bet most customers didn't even notice. Admittedly, not everything went smooth. There were a few issues that impacted a small subset of users. Thanks to everybody who reported them (cough, cough - encoding issues). But overall...I am very happy with how it went.

The Impact on Magic Pages

While the overall server costs stay about the same for Magic Pages' current customer base, this change makes future growth much more manageable. Instead of adding more server capacity just to fit more databases, Magic Pages can now grow more efficiently. The new database cluster is able to handle the growth that I expect in the next year. And even when demand outgrows its resources, upgrading it is literally changing one line of code, thanks to the awesome project I am using to manage Magic Pages infrastructure: hetzner-k3s (Magic Pages is sponsoring it because it's so awesome).

At the same time, the new setup also means better backup systems and easier disaster recovery. It's like having a dedicated database administrator - just without the salary ๐Ÿ˜‰

I feel like this whole journey reflects Magic Pages' evolution. It's not just about technical improvements - it's about growing up as a platform. Finding ways to do the same things more efficiently, with minimal customer impact (or at least, make the impact a positive one ๐Ÿ˜„).

When I started Magic Pages, every decision felt smaller, more manageable. With 20 customers, you can afford to experiment more freely. But with 400? That's 400 businesses, creators, bloggers, or non-profits trusting Magic Pages with their online presence. 400 blogs, newsletters, and communities that need to keep running smoothly.

This growth brings a different kind of responsibility. It's no longer just about making things work โ€“ it's about making them work reliably, efficiently, and at scale.

That's the beauty of running a bootstrapped business. You can take the time to learn, to experiment, and to do things right. Because at the end of the day, it's not about moving fast and breaking things - it's about building something that lasts.