Azure IaaS assessments: sizing lift-and-shift honestly

Field notes on running an azure migration assessment before you commit to lift and shift sizing: measured load, right-sizing down, and what should stay put.

We closed out the year running an azure migration assessment for a 700-server enterprise estate whose board had already decided, before anyone measured anything, that Azure IaaS lift-and-shift was next year's project. That's the normal order of operations, and it's backwards. Lift and shift sizing is the actual argument of this post: size the destination to what a server measurably does, not to what a purchase order said it might need back in 2013, and the gap between those two numbers is where a lift-and-shift business case is won, lost, or quietly inflated.

This is our third such assessment this year, and the shape of the work is identical whether the client is a state agency or a private enterprise: an inventory pass, a measurement window, and then the uncomfortable conversation about what the numbers say versus what the steering committee was hoping to hear. We run this for government and enterprise clients alike, and the honest version of the conversation doesn't change between the two rooms.

This post is our field notes from that estate — anonymized, numbers rounded where rounding protects the client, otherwise unfiltered. It covers why the assessment discipline matters more than whichever tool executes it, how we measure real load instead of nameplate specs, what right-sizing actually buys you, what we told this client to leave exactly where it is, the networking that has to exist before a single VM lands in Azure, and the cost math a lift-and-shift slide deck usually skips.

Why the azure migration assessment matters more than the mover

Microsoft announced Azure Migrate at Ignite in September, and as of this month it's still in preview. It handles discovery and dependency mapping in one service, which is precisely the thing every assessment struggles with, and we'll take it seriously the day it's generally available and we can put it in a signed statement of work. Until then, the tool doing the actual work for us is the one with a decade of mileage: the Microsoft Assessment and Planning Toolkit for inventory, paired with 30-plus days of performance counters pulled from every candidate server. Inventory tells you what exists. Counters tell you what it does. Most thin assessments only collect the first kind of data and call it done.

Azure Site Recovery is the other tool in this conversation, and it's worth separating cleanly from the assessment itself: ASR replicates and moves; it does not judge. Point it at an over-provisioned sixteen-core VM and it will faithfully replicate an over-provisioned sixteen-core VM into Azure, on schedule, without complaint. Nothing in a replication tool asks whether the thing being replicated should be smaller. That question is the assessment's entire job, and skipping it is the most common way a lift-and-shift project inherits its on-premises sins at a higher hourly rate.

We've run this same measure-before-you-move discipline virtualizing more than 400 servers onto Hyper-V over the last couple of years, and the lesson transfers directly: a spec sheet was never a sizing document, on-prem or in Azure.

Measuring real load, not nameplate specs

Nameplate specs lie, not maliciously, just historically. A server specified in 2013 was sized against a three-year capacity forecast, a vendor's rule of thumb, and whatever the budget cycle allowed that quarter — not against the workload it eventually ran. Four years later the spec sheet and the workload have almost nothing to do with each other, and the spec sheet is usually the only document anyone hands us at kickoff.

This estate's SQL reporting server was the cleanest example this round: sixteen vCPUs, 64 GB of RAM, provisioned that way because "reporting servers need headroom" was somebody's honest belief in 2013. Thirty days of performance counters told a different story — 4 percent average CPU, 11 percent at its single monthly peak, a working set under 9 GB. It had been running comfortably for years on roughly an eighth of what it was allocated. That's not an unusual finding. It's close to the median one.

The collection itself is unglamorous, and that's the point — we're not looking for a clever number, we're looking for a boring, defensible one:

# 30 days of CPU and memory sampling across assessment candidates, logged for rollup
$servers = Get-Content .\assessment-candidates.txt
foreach ($server in $servers) {
  Get-Counter -ComputerName $server `
    -Counter "\Processor(_Total)\% Processor Time", "\Memory\Available MBytes" `
    -MaxSamples 1 |
    Select-Object -ExpandProperty CounterSamples |
    Select-Object Path, CookedValue, Timestamp |
    Export-Csv -Append -NoTypeInformation ".\perf-log-$server.csv"
}

Run that as a scheduled task every fifteen minutes for a month, across every candidate, and you have a dataset nobody can argue with in the sizing meeting — which is worth more than the script itself. The number of steering-committee arguments this avoids is the actual return on the exercise.

Lift and shift sizing: right-sizing before you migrate

Once the counters are in, sizing is arithmetic, not opinion. We map each server's measured peak — peak, not average, with headroom on top — against the current Azure compute families: general-purpose Dv3 for most of the estate, memory-optimized Ev3 for the handful of workloads that are genuinely memory-bound rather than compute-bound, F-series where something is truly CPU-hungry and light on memory, and the older Dv2 and A-series only where a client's existing reserved pricing or a compatibility need already anchors them there. Hyperthreading on the v3 families changes the vCPU-to-physical-core math versus the hardware these servers came from, which is one more reason a straight core-count translation from on-prem to Azure is the wrong method.

The reporting server above landed on a D2s v3 — two vCPUs, 8 GB — with tempdb moved onto its own Premium-tier managed disk, because its real bottleneck, once we stopped staring at CPU, was disk latency during month-end batch jobs, not compute. That's a common pattern: the nameplate spec oversizes compute and undersizes the one disk that actually matters. Managed Disks, generally available since February, make this kind of per-workload tuning simple — pick a performance tier per disk, attach it, done. On the old unmanaged-disk model this exercise came with a spreadsheet mapping VMs to storage accounts to stay under the per-account IOPS ceiling; that spreadsheet doesn't need to exist anymore, and we don't miss it.

The estate's sizing rolled up like this:

On-prem nameplate30-day measured peakRight-sized Azure VM
16 vCPU / 64 GB (SQL reporting)11% CPU, 9 GB working setD2s v3 + Premium disk for tempdb
8 vCPU / 32 GB (file server)6% CPU, IO-bound not compute-boundD2s v3, disk tier upsized instead
4 vCPU / 16 GB x 6 (app tier)45% CPU during business hoursD4s v3, no downsizing headroom
2 vCPU / 8 GB (print server)under 1% CPU, 400-plus days uptimeRetired, not migrated

Three of those four rows shrink. One doesn't — the app tier was correctly sized on-prem already, which happens often enough that "right-size" has to mean both directions, or it isn't measurement, it's a haircut.

What stays on-prem

Every assessment produces a refusal list, and it's the least popular deliverable we write, because it looks like failure to a steering committee that wanted a 100 percent migration slide. It isn't failure. Forcing the wrong workload into Azure IaaS to hit a completion percentage produces exactly the kind of outage that ends careers.

This estate's refusal list, and the reasoning behind each line, because the reasoning is the reusable part:

  • The chatty two-tier app. An inventory system with an app server and its SQL Server talking constantly — small transactions, high frequency, synchronous calls, tens of thousands of round trips an hour. We test-moved the app server alone into a pilot subscription, left the database on-premises, and the application was unusable within an hour. Round-trip latency that's sub-millisecond on the same LAN segment becomes single-digit milliseconds over a VPN, and an application built assuming the first number falls over at the second. The fix isn't "don't use Azure," it's "move both tiers together or move neither," and we're now sizing the second option.
  • The SQL Server 2008 R2 box under extended support. Its licensing has mobility rules that need resolving with the client's Microsoft licensing rep before anyone commits a migration date, not after. License Mobility through Software Assurance can move some server application licenses into Azure; whether this one qualifies is a phone call, and we insist that call happens before the cost model gets built.
  • Anything with a hardware dongle or a proprietary card. One application here is licensed against a physical USB dongle, and the vendor has no cloud-compatible answer for it. We've refused this category before on Hyper-V projects for the same reason we refuse it here: no passthrough story is worth the operational fragility it buys you.
  • The DR replication target. This one isn't a refusal so much as a redirect — lifting an on-premises DR pattern into Azure IaaS unchanged just relocates the same architecture to a more expensive rack. Azure Site Recovery replacing that DR pattern outright is a better use of the same budget, so we scoped it as a separate line item instead of folding it into the lift-and-shift count.

The Azure networking you need first

None of the sizing work matters if the network underneath it is an afterthought, which is exactly what a rushed lift-and-shift schedule tries to make it. The sequence that actually works puts networking first and migration second:

  1. Virtual network design before any server exists in Azure. Address space that doesn't collide with on-premises ranges, subnets that mirror the tiering you actually operate — web, app, data, management — and a naming convention someone can still explain in a year.
  2. Network Security Groups doing the job your on-prem VLAN ACLs used to do. Built from the traffic the assessment actually measured, not from a guess — if the dependency mapping shows the app tier only ever talks to the database tier on 1433 and the web tier on 443, the NSG says exactly that and nothing wider.
  3. Site-to-Site VPN as the default connection, ExpressRoute where the numbers justify it. A S2S VPN is fast to stand up and fine for most estates' initial footprint. ExpressRoute earns its cost when egress volume, latency sensitivity, or a compliance requirement demands a private circuit instead of an encrypted tunnel over the internet — and the chatty two-tier app above is exactly the workload that will eventually force that conversation here.
  4. Availability Sets before the first production VM, not after the first outage. Every workload that isn't explicitly disposable goes into a set spanning multiple fault domains and update domains from day one, because retrofitting availability after go-live means a maintenance window and a change request for something that should have been free at the start.

Skip this part of the plan and you'll still demo a lift-and-shifted server successfully on day one — demos always work. You find out the networking was an afterthought a month later, during the first platform update or the first ExpressRoute conversation nobody had, and by then it's an incident instead of a design decision.

The cost math nobody wants to hear

Here's the sentence every lift-and-shift slide deck buries in a footnote: moving a server unchanged into Azure IaaS often costs the same or more than running it on-premises, because a subscription bill itemizes compute, storage, and egress separately and continuously, where a fully depreciated on-prem server mostly just sits there. We're known for a 35 percent average infrastructure cost reduction across our migration programs, and clients naturally want that number attached to this project. It's an honest number, but it doesn't come from lift-and-shift — it comes from workloads that leave the server tier entirely: mailboxes moving to Office 365 (we've taken more than 15,000 of them there), farms retired outright, storage tiers that stop growing. Lift-and-shift IaaS is a smaller, different lever, and the only way it saves anything is the right-sizing this whole post is about. Move the nameplate spec one-for-one and you've bought the cloud version of your existing waste, on a meter.

Two numbers this estate's business case had never modeled:

Egress. Every gigabyte leaving Azure to the internet or back to your own datacenter over a VPN is billed, and backup traffic is usually the line item nobody remembers to count.

Nightly differential backup egress, this estate's file and SQL tiers combined:
  1.2 TB changed data/night x 30 nights = 36 TB/month
  First 5 GB/month free, remainder at roughly $0.087/GB, pay-as-you-go, this region
  36,000 GB x $0.087 = about $3,132/month in backup egress alone
  A Site-to-Site VPN or ExpressRoute doesn't remove this cost -
  it just makes the bandwidth predictable and private instead.

Reserved capacity. Reserved VM Instances, generally available as of last month, let you prepay a one- or three-year compute commitment against a specific VM size and region, and the discount against pay-as-you-go is substantial enough that we now model every sizing recommendation twice — once on-demand, once reserved — before a client signs anything. The catch is in the word "specific": committing to a size for one to three years turns an unmeasured guess into a much more expensive mistake than it ever was on-demand. It's the strongest argument we have for finishing the assessment properly before anyone calls procurement.

The honest business case models all of it — compute at the right size, storage at the tier the workload needs, egress at measured volumes, reserved against on-demand — before it reaches a steering committee. The dishonest version multiplies a nameplate server count by a list price and calls it a migration plan.

If you're facing this

If a lift-and-shift is on next year's roadmap and nobody has pulled performance counters yet, that's the one phone call worth making before the business case gets locked. We run this assessment for government and enterprise estates from a handful of servers to several hundred, we'll tell you plainly which workloads should stay exactly where they are, and we'd rather lose the lift-and-shift line item than watch a client discover the honest numbers after the migration instead of before it. Get in touch.

// related notes
// still relevant?

Facing a migration, platform, or AI build like this one?

This note is part of an archive spanning a decade of infrastructure work. The playbook evolved; the discipline didn't. Tell us what you're trying to ship — we reply within one business day.

Start a project →

← Back to notes