Services — Legacy Migration
Legacy .NET migration
The application built in 2009 that still runs something the business depends on. Moving it to a supported runtime without losing data, history or a weekend to an outage.
What gets migrated
.NET Framework to .NET 8+
The core case. Framework applications on an unsupported runtime, carrying dependencies that were current a decade ago and Windows-specific APIs with no direct successor. The work is dependency compatibility, configuration migration, replacing what has no modern equivalent, and a test and deployment strategy that proves the result behaves the way the original did.
WebForms applications
WebForms has no migration path to modern .NET, which makes this a genuine decision rather than an upgrade. The right answer depends on how much business logic is trapped in code-behind versus separable, and that assessment is worth doing carefully — the difference between the two paths is frequently a factor of three in cost.
Umbraco version upgrades
Multi-major-version Umbraco jumps where no supported upgrade path exists — Umbraco 7 through 13 and beyond. This includes the Minnesota Secretary of State's official state website, migrated from Umbraco 7 to 14 and .NET Framework to .NET Core. The hard parts are custom document types, property editors written against removed APIs, and content migration that preserves URLs and editorial history.
On-premises to Azure
Moving applications and SQL Server databases into Azure with the identity, networking and security configuration IT and compliance require before anything moves. Includes the operational setup — monitoring, deployment, backup — that determines whether the environment stays maintainable after handoff.
How the estimate gets built
Migration estimates go wrong in a consistent way: the runtime upgrade gets estimated and everything around it does not. The parts that actually drive the timeline are the third-party dependencies with no supported successor, the integrations nobody has a complete inventory of, and the test coverage that has to be built before anyone can tell whether the migrated system still behaves correctly.
So the estimate starts with an inventory rather than a guess. What the application depends on, what depends on the application, what the deployment path is, and what verification would have to look like for you to sign off on a cutover. That inventory is what separates a two-month migration from an eight-month one, and it's knowable up front.
A migration that compiles is not a migration that succeeded. The finish line is the system running in production, on a supported runtime, with your team able to deploy it.
What are you running?
Runtime version, roughly what the application does, and what's forcing the move — a security finding, a vendor end-of-life date, or a feature you can't build on it anymore.
Get in touch