Our host sent us a warning I’d summarize like this: your dedicated servers are so old that if a part breaks, we can’t promise we can fix them. Not “upgrade recommended.” Can’t promise parts.

That sentence moved “migration” from my wish list to my risk register. Production is running on hardware with an unknown timer, and the timer starts when something snaps.

Here’s the decision that follows from it: we’re moving, and Classic ASP is coming with us, as-is.

the rewrite tax, already paid once

Every engineer’s instinct, including mine, says a forced migration is the natural moment to modernize. New box, new stack, clean slate. I have a specific reason to distrust that instinct: I’ve paid the rewrite tax before, and I have the receipts.

The one time we bet years on building something big and new, our team’s throughput dropped to roughly a third of its peak and stayed there for three years. Three years of the core product limping while the future got built. The business shrank while we did it. Whatever a modern stack would have eventually saved, the building of it cost more than the debt it was supposed to clear. A third of peak across twelve straight quarters is the number I’d want a skeptic to hold me to, and it’s the reason “just modernize” stopped sounding free.

Classic ASP is unfashionable and it is also not the problem. It serves paying customers every day, the team knows every inch of it, and with AI agents in the loop we ship faster in this “legacy” codebase than we ever have. New tech is development overhead until proven otherwise, and overhead doesn’t generate profit by default. Results do.

decoupling the two problems

The insight that unlocked the plan: the hardware problem and the technology problem are different problems, and only one of them has a deadline.

The hardware problem is urgent, physical, and non-negotiable. The technology question is discretionary, and it deserves to be judged on economics, with the adrenaline of a crisis kept out of the math.

So the sequence is:

First, Cloudflare in front of the server. Every domain, every pointer, every customer DNS setting now resolves to the edge instead of straight to the old box. This was months of work, mostly a long tail of customer-managed domains, and it’s the enabling move: it means what comes next is invisible to customers.

Second, the hardware move, now reduced to an infrastructure swap behind a stable layer. Database over, app over, flip Cloudflare to the new origin. No customer touches anything. No mass email campaign. The blast radius of the scariest step got shrunk before the step.

Third, nothing. The stack stays. If a piece of it ever earns a rebuild, it’ll be because the numbers say so, module by module, on a track that can be interrupted any time revenue work needs the capacity.

the juggle is the real story

None of this pauses the business. The same months this migration ran, we shipped product releases, because the migration work rides in the gaps. The edge cutover alone stretched across those months, a long tail of customer-managed domains chased down a few at a time, never a sprint that froze the roadmap. I work with AI agents running several tasks in parallel; infrastructure grinds forward in the background while revenue features hold the critical path. Five years ago this juggle wasn’t possible for a team our size, and “urgent infrastructure versus income” would have been a brutal either-or. Now it’s a scheduling problem.

So I wrote down what the hardware deadline actually requires, and nothing else earned a spot on the list. Everything that tried to sneak on was discretionary work borrowing the deadline’s urgency, and left unchecked it quietly converts an infrastructure crisis into a rewrite.

The edge layer is done. The hardware move still isn’t, and the timer the host started is still running. I’m spending the months before it fires shipping product releases. The stack replacement can wait for a deadline that actually asks for it. If that turns out to be the wrong call, at least this time it’s wrong in a way I can point to on a spreadsheet, instead of three years of throughput I only understood in the rear-view mirror.