US advertising platform · ~20-year-old codebase

Modernizing an 823,000-line monolith — no downtime, no big bang

A live .NET Framework 4.8 platform with 54 projects and 23,000 commits of history, modernized incrementally to .NET 10 — the old system keeps running while the new one takes over section by section. 19 sections with tests in about 8 days.

  • 823,000 lines of legacy code
  • 19 sections in ~8 days
  • SSO with zero changes to the old system
  • 175 tests from day one

The client

An American business directory and advertising platform operating for nearly two decades: consumers, merchants, resellers, payments, transaction disputes, ad network integrations. A living business with real revenue — and a codebase nobody dared to touch.

The challenge

The system: 823,000 lines of C# across 54 projects, .NET Framework 4.8, WebForms pages more than a decade old, 581 tables in the data model and over 23,000 commits of history. Everything flows through one central "hub" application that eight separate sites and services depend on.

The classic dilemma: a full rewrite is too risky and expensive, while maintaining the status quo gets costlier every year — the old technologies are out of support, new developers don't want to work with them, and every change is dangerous.

The approach

We chose incremental modernization ("strangler fig"): the new system grows next to the old one and takes over functionality page by page, while users notice nothing.

  • Inventory before code. All 123 admin pages were catalogued and prioritized. About 30 of them turned out dead or duplicated — we retired them without porting a line. Smaller scope, lower price.
  • An invisible transition. The new application runs on the same address, behind the same login. A user signs in to the old system and switches to the new pages without a second login — with zero changes to the old code.
  • Port only what's alive. For every page we trace the full business-logic call chain and port only what is actually used. Dead logic dies by simply not being ported.
  • Tests the same day. Every migrated section ships with automated tests in the same PR — including tests that compare the new code's behavior against the old one on identical data.
  • Decisions on paper. Around 1,800 lines of project documentation (migration playbook, dependency analysis, testing strategy) written before and alongside the code — so every decision can be re-verified tomorrow, by anyone.

The result

  • 19 admin sections — payments, disputes, packages, categories, reports — migrated in about 8 working days, with 175 automated tests.
  • Zero risk to the running business: the old system keeps serving everything not yet migrated; the transition is invisible to users.
  • A modern foundation (.NET 10) where new features take hours instead of weeks — and for which developers are easy to find.
  • Scope reduced before the start: the dead pages were not paid for a second time.

The speed comes from AI-accelerated development. The safety comes from the method: inventory, parity tests and a transition without a big bang. Neither works without the other.

Technology

.NET 10 · ASP.NET Core MVC · EF Core · nginx coexistence · xUnit + Playwright