Previously: we migrated this database from Azure SQL Managed Instance to Azure SQL Hyperscale — not because of its size at the time, but because we could see it growing, and growing faster ahead. We wanted to break the dependency between storage and compute before it started making us overpay. This part is about the compute side itself.

After the migration, the database kept growing — and over the year or two that followed it was scaled up to 32 vCores, step by step. It wasn't that we only ever threw hardware at the problem — there was optimization and refactoring along the way too — but the system kept expanding, and sometimes the simplest immediate answer was to add a little more power. That kept things running, but adding capacity is the kind of quick answer that quietly adds up on the bill — and the added power wasn't about average load anyway; it was about surviving peaks. That distinction turned out to be the whole story.

A note on how I'll talk about load

Throughout this series I use vCores as a simple, visible proxy for how hard the database is working — it's easy to reason about and easy to show. But it's only a proxy: CPU is rarely the only thing that can become a bottleneck. On Hyperscale, data IO and IOPS, transaction-log throughput, and worker or connection limits can each become the real constraint. vCores are the headline number here, not the whole picture.