Migrating my blog and why I built the redirector
I moved the blog from dailyhypervisor.com to echoesofthemachine.com. The new name fits where the writing actually went. A small Cloudflare Worker handles the redirect so every old link still lands somewhere useful. Here's the why, the architecture, and what I learned doing it.
I moved the blog. The URL you're reading this on, echoesofthemachine.com, is new. The old URL was dailyhypervisor.com, which I'd been on for years. The move was overdue, and the renaming is the easiest part of the story to tell. The interesting part is the redirector.
Why rename
Dailyhypervisor was a name from a different period of my writing. When I started it. I was writing about virtualization, hypervisor internals, the boring middle of the stack. That was honest at the time. It stopped being honest about three years ago. The writing kept going, but it went somewhere else. AI infrastructure, the cognition-as-IP threads, the vendor lock-in arguments, the self-hosted stack experiments, the personal essays. Calling all that "daily hypervisor" felt like wearing a uniform from a job I no longer worked.
Echoes of the Machine is what the writing is actually about. The patterns the systems we build leave behind. The traces. The reverberations. The name has been sitting in my head for a year. The migration is me finally acting on it.
What I didn't want to lose
The rename is cosmetic. The hard part is the URL contract. I have years of posts, a respectable amount of inbound traffic, references in other people's writing, citations in talks, links in old emails. Every one of those URLs points at a hostname I no longer control on a CMS path that might or might not survive the move. If I just flip the DNS and call it done, every external link to my writing is broken. The archive becomes invisible.
I care about that for two reasons. One is selfish, link equity is real, and search rankings live on the back of stable URLs. The other is the part I actually feel more strongly about: the writing should still be findable. If somebody clicks a five-year-old link to a post about hypervisor scheduling, the right answer is "here is that post, at its new home," not a 404 or a domain-parked page.
So the migration plan had three requirements: every old URL has to redirect to its correct new home, the redirect has to be a clean 301 so search engines update their indexes, and the system has to be cheap enough to leave running indefinitely. Indefinitely is the operative word. The old domain isn't going away. I'm keeping it. The redirect is permanent infrastructure.
Why a Cloudflare Worker
I considered three options.
The first was a static redirect, point dailyhypervisor.com at the new host with a wildcard 301. This breaks for any post whose URL slug changed during the migration, and several did, because the new CMS has different slug rules and a handful of posts got retitled. A wildcard rewrites every path identically, which only works if every path is identical, which isn't the case.
The second was an Nginx box. I could spin up a small VM, run Nginx with a long map directive of old-path → new-path, and call it done. This works. It's also a server I have to patch, a TLS cert I have to rotate, and a bill I have to keep paying for a machine whose only job is to serve 301s. For a single-purpose redirector, a whole VM is an unflattering ratio.
The third was a Cloudflare Worker. Cloudflare already fronts both domains. Workers run at the edge, scale to zero, cost essentially nothing at my traffic, and the deploy is a single command. The whole redirector is one TypeScript file and a JSON mapping table. I picked this one.
How it actually fits together
The worker has three jobs.
First, it handles the easy case: any path that exists identically on both old and new hosts gets redirected straight through. The vast majority of posts kept their slugs. For those, the worker takes the incoming path, prepends the new host, and returns a 301.
Second, it handles the renamed posts. There's a JSON map (about thirty entries) of old-slug to new-slug, embedded in the worker bundle. When a request comes in, the worker checks the map first. If it's a renamed post, the redirect goes to the new slug. If not, fall through to the straight-through case.
Third, it handles the things that didn't make it. A small number of posts from the old blog didn't survive the migration, drafts I never want to resurface, a few that aged badly enough that I'd rather they go quiet, one that had a factual error I never fixed and would rather retire than reissue. Those paths get redirected to a single archive-stub page on the new site that explains the post has been retired and points at related current writing.
The 404 case (a path that was never a real post on the old blog) returns an actual 404. I went back and forth on this. The kind option is to redirect everything to the homepage. The honest option is to return 404 for paths that genuinely never existed, because pretending otherwise pollutes the analytics and rewards the people probing for vulnerabilities. I picked honest.
There's one more thing the worker does that I added late. Bots and feed readers hitting the old RSS endpoint get a permanent redirect to the new feed, and the worker logs the user-agent on those for a few weeks so I can see who's actually still subscribed. That last part is the kind of thing you only notice you want after you've started running the thing.
Where to keep the map
The interesting design question was where to put the map. Three options: hardcoded in the worker, in a Cloudflare KV namespace, or fetched from the new blog's API on demand.
Hardcoded is fastest and cheapest. The map is small (about thirty entries), the worker bundle stays under 50KB, and there's no extra round trip. The downside is that adding a new mapping means redeploying the worker. For something that's going to change a few times a year at most, redeploying is fine.
KV would let me update the map without redeploying, but KV reads cost something and add a few milliseconds of latency, and I'd have to build a small admin UI to manage entries. For thirty entries, this is overkill.
Fetching from the blog API is the most flexible (the blog itself becomes the source of truth) but it adds a dependency on the new host's availability for the redirector to work. The whole point of the redirector is to be more reliable than the destination it's pointing at. If the new blog goes down, the redirector should still serve correct 301s, because 301s get cached aggressively by browsers and search engines and getting them wrong is worse than getting them slow.
Hardcoded won. The worker is self-contained.
What I learned
A few things came out of building this that I didn't expect.
The first is that the migration forced me to actually audit my old archive. I had to go through every post on the old blog and decide: keep, rename, retire, redirect-to-related. Some of those decisions were easy. Some of them, the ones where I had to look at a piece of my own writing from four years ago and decide whether it represented me well enough to bring forward, were genuinely useful. The migration ended up being an editing pass on my own back catalog. I'd recommend it as a practice independent of any actual hostname change.
The second is that 301s are sticky in a way I'd known about in theory but hadn't felt. The moment the worker went live, search results started updating within hours. Browsers that had ever visited the old URL learned the new one and stopped hitting Cloudflare entirely for those paths. The redirector's traffic is going to decay over months toward a long tail, because most of the people who'll ever follow an old link have already done it and their browser remembers.
The third is the one that surprised me. The old domain, dailyhypervisor.com, costs me almost nothing to keep, and the worker that fronts it costs me almost nothing to run. There is no economic reason to ever turn it off. So I won't. The old URLs will resolve forever, or at least for as long as I'm running infrastructure, which is a meaningful promise to make to anyone who linked to my writing in good faith. The cost of keeping that promise is roughly the cost of one cup of coffee per year. I should have made promises like this earlier.
The boring conclusion
If you have a blog or a personal site or any small piece of public-internet writing that you've moved or might one day move, build the redirector. It's a one-evening project. The Cloudflare Worker template for this kind of thing is short enough that I almost included the whole source in this post. The cost is negligible. The benefit is that every link anyone has ever made to your writing keeps working, which is the kind of small reliability that the open web used to take for granted and increasingly doesn't.
The rename was the headline. The redirector is the actual work. That's usually how migrations go, the new thing is the announcement, the old thing is the engineering.
Welcome to echoesofthemachine.com. If you got here from a dailyhypervisor link. That's the worker doing its job. If you didn't. That's the worker not needing to.