Migrating 30 servers from DigitalOcean to Hetzner without downtime
Two months of planning, one weekend of cutover, ~$5,000/month saved. The order of operations that kept 99.97% uptime through a full-fleet infrastructure swap.
Laravel one morning, Django the next, a Node service in the afternoon, React on top, Postgres under all of it. Twelve years of this. Claude lives in my terminal now, so I move faster. The job hasn't changed though: writing software someone can still read in two years.
I picked PHP first because the agencies in 2014 paid for it. Then Laravel, because the PHP I was writing deserved better bones. Then Python and Django because data work was creeping in. Node because the frontend kept asking for a real backend. React because everyone's frontend is React now. Twelve years later, I'm not loyal to a stack. I'm loyal to the right tool for the job, the one the client can still hire for later.
Postgres for anything serious, MySQL when I've inherited it, Redis when something has to be fast. Hosting depends on the budget: Hetzner when money's tight, a managed cloud when compliance asks, Kubernetes only once the scale actually earns the headache.
The new layer is AI. Claude, Gemini and the OpenAI APIs are in my daily flow. Not something I'm selling you, just how the work actually gets done now. If you haven't worked out where they fit yet, I'll tell you what's real and what's marketing.
Toptal-vetted. Async-friendly. Hate meetings that could have been a PR description.
Lead engineer on a tenanted learning platform serving regulated industries across the Nordics. Owns the full stack: backend services, the data layer, and the infrastructure under it. Planned and ran a full DigitalOcean → Hetzner fleet migration; wired Claude into tier-one support triage.
Foundation phase of a multi-tenant SaaS: tenant isolation, REST APIs, payments, and the unglamorous data migrations nobody else wanted. ~144 commits across the engagement.
Etsy-style social-commerce marketplace. Architected REST APIs for the mobile client and the AWS autoscaling profile that backed them. Stripe billing edges, Instagram-linked discount workflows, the works.
Long engagement, deep codebase. Bespoke integrations across LMS, billing and membership platforms; WP-CLI tooling for bulk migrations across multiple managed hosts. The work that taught me what "maintainable" actually means.
Built the tooling that bulk-updated 120 production Auth0 tenant connections during a platform migration. Caught a shallow-merge bug pre-flight that would have silently wiped 120,000 user logins. Dry-run preview, deep merge, then a production cutover in 84 seconds wall-clock. The kind of job that lives or dies on whether someone built the dry-run first.
Took a managed-host monthly bill and cut ~$5k/mo off it without breaking anything. Capacity model, Ansible-managed Hetzner boxes, tuned Postgres + Redis, observability done properly. 99.97% uptime through the cutover; 5–20× perf gains on the routes that mattered.
A small, sharp set of services backing a mobile-first social-commerce app. Stripe billing edges, autoscaling profile tuned to actual traffic, sane defaults that survived contact with real users.
Years of engagements where the answer was "no marketplace plugin will fit." Custom flows across LearnDash, LifterLMS, WooCommerce, Restrict Content Pro and Stripe, wired the way the client actually needed instead of the way the docs assumed.
Two months of planning, one weekend of cutover, ~$5,000/month saved. The order of operations that kept 99.97% uptime through a full-fleet infrastructure swap.
A near-miss with an Auth0 fleet migration tool, and how a dry-run mode caught a bug that would have silently wiped 120,000 user logins.
Email's the fastest way. I read every message myself and usually reply within a working day, in plain English, with a clear yes / not-now / not-a-fit. If you want a call, send a short brief first. It makes the call ten times more useful.