A software company I worked with moved its customer portal to Azure SQL Database and picked the biggest, safest-sounding option for every environment. Dev, test, and production all ran on Business Critical. Three months later the finance team asked why a database serving 40 internal testers cost nearly as much as production. Nobody had matched the tier to the workload.
Choosing the wrong Azure SQL pricing tier is one of the easiest ways to overspend, and one of the easiest to fix. Azure SQL Database lets you change tiers online, so you can start small, measure, and adjust. But you need to know what each tier pays for first.
This guide compares the DTU and vCore models, explains General Purpose, Business Critical, Hyperscale, and serverless, and shows you how to deploy and resize a database with the CLI and Bicep. You will also learn how to secure it, monitor spend, and troubleshoot the surprises that raise the bill.
Azure SQL Pricing Tier Options Explained
Azure SQL Database has two purchasing models, which are the ways Azure measures and bills your database resources.
The DTU model bundles compute, memory, and I/O into one unit called a database transaction unit (DTU). You pick a service tier (Basic, Standard, or Premium) and a performance level. It is simple, and storage is bundled in. The trade-off is that you cannot scale CPU and storage separately.
The vCore model lets you choose virtual cores (vCores), memory, and storage independently. A vCore is a logical CPU. Microsoft recommends this model for new work, and it unlocks the most features.
| Feature | DTU model | vCore model |
|---|---|---|
| Resource control | Bundled | Compute and storage chosen separately |
| Service tiers | Basic, Standard, Premium | General Purpose, Business Critical, Hyperscale |
| Serverless compute | No | Yes (General Purpose and Hyperscale) |
| Azure Hybrid Benefit | No | Yes (not for new Hyperscale databases) |
| Reserved capacity | No | Yes (provisioned compute) |
| Best for | Simple, predictable workloads | Flexibility, control, and discounts |
If you are comparing deployment options before picking a tier, read the guide to Azure SQL Database deployment options. For a broader view of the tier families, see the explainer on Azure SQL Database service tiers. For a general pricing overview, check Azure SQL Database pricing.
I am not quoting dollar amounts in this article. Prices change by region, hardware, and offer type. Always price your exact configuration in the Azure pricing calculator before you commit.
Pro Tip: In my experience, new projects should start in the vCore model, even small ones. The DTU model is fine for simple apps, but it removes your best discount options later.
Compare the vCore Service Tiers
Within the vCore model, three service tiers determine your storage type, resilience, and price.
| Tier | Best for | Storage | Replicas | Size limit |
|---|---|---|---|---|
| General Purpose | Most business apps, budget-friendly | Remote premium storage | One replica | Up to 4 TB |
| Business Critical | High-transaction OLTP with low latency | Local SSD | Three replicas, one readable secondary | Up to 4 TB |
| Hyperscale | Large, fast-growing, or read-heavy databases | Decoupled storage with SSD cache | Configurable, up to 4 HA replicas | Up to 128 TB |
Here is how I explain the differences.
General Purpose is the default for most workloads. Compute and storage are separate, and Azure Blob storage protects your files. It suits line-of-business apps, internal portals, and APIs where a few milliseconds of storage latency do not matter.
Business Critical runs on local SSD storage with extra replicas for fast failover. Microsoft states that the additional replicas make it cost roughly 2.7 times as much as General Purpose. Choose it when you need very low I/O latency, fast recovery, or a free readable secondary for reports. Do not choose it just to feel safe.
Hyperscale separates compute and storage so each can scale on its own. You are billed for storage you actually allocate, and you can scale compute quickly. Microsoft calls it the recommended tier for many new workloads. Migrating a large database into it takes time because the move depends on data size. You can reverse-migrate to General Purpose only within 45 days, so test before you commit.
Provisioned vs. Serverless Compute
Inside the vCore model, you also choose how compute is billed.
- Provisioned compute reserves a fixed number of vCores and bills at an hourly rate whether or not anyone uses the database.
- Serverless compute scales within a vCore range you set and bills per second for what it uses. In General Purpose, it can also auto-pause when idle, so you pay only for storage during that time.
Serverless fits dev and test databases, internal tools, and new apps with unknown traffic. It does not fit steady production traffic, because the per-vCore rate is higher than provisioned and a paused database needs time to resume. A resume usually takes about a minute, and the first connection may fail with error 40613, so your app needs retry logic. Auto-pause for Hyperscale serverless is still in preview, so avoid it for production. Also remember that Azure Hybrid Benefit and reservations do not apply to serverless.
For a deeper walkthrough, read the Azure SQL Database serverless guide.
Elastic Pools and the Free Offer
An elastic pool shares one pool of resources across many databases. It works well for SaaS apps with one database per customer, where peaks happen at different times. You pay for the pool, not each database.
There is also a free offer for new databases. At the time of writing, each free database gets 100,000 vCore seconds of serverless compute plus 32 GB of data storage and 32 GB of backup storage per month, with up to 10 free databases per subscription. Microsoft says it has no service level agreement, so use it for learning and proof-of-concept work, not production. Connected tools like SSMS can keep the database awake and burn your free seconds, so disconnect when you are done.
Pro Tip: I keep a simple rule for tier approvals: General Purpose first, Business Critical only with a written latency or failover requirement, and Hyperscale only when size or read scale is the real bottleneck.
How to Choose the Right Azure SQL Pricing Tier
Follow these steps to match a tier to a real workload.
- Define the requirement. Write down database size, expected growth, peak hours, latency needs, and recovery goals. A 50 GB internal app and a 5 TB reporting platform need different tiers.
- Measure existing usage. If you are migrating, capture CPU, memory, and I/O from the source server for at least a full business cycle. Use Azure’s migration and sizing tools instead of guessing. A common mistake is mapping one on-premises core to one vCore. Azure vCores are logical threads, so under-sizing is likely.
- Pick the purchasing model. Use vCore unless you want bundled simplicity and have no license or reservation plans.
- Pick the service tier. Start with General Purpose. Move up only when metrics show a real limit.
- Pick provisioned or serverless. Choose serverless if the database sits idle for hours. Choose provisioned for steady traffic.
- Right-size and review. Start small, watch metrics for two to four weeks, and adjust.
Here are examples of how this plays out in real projects:
- Internal HR portal, 200 GB, business-hours traffic: General Purpose provisioned, small vCore count, with a reservation after usage stabilizes.
- Developer sandbox, used a few hours a day: General Purpose serverless with auto-pause. Dev and test environments should almost never match production size.
- Order processing system with strict latency needs: Business Critical, with zone redundancy where available.
- Analytics-heavy platform growing past 4 TB: Hyperscale, with named replicas for reporting.
- SaaS app with 300 small tenant databases: An elastic pool sized to combined peaks.
Remember that storage billing differs by tier. In General Purpose and Business Critical, you pay for the maximum data size you configure, and extra space for the log file is added automatically.
In Hyperscale, you pay for allocated storage, and you do not pay for log storage. Backup storage is billed on top, and by default you get backup storage equal to your maximum data size at no extra charge.
Pro Tip: I set the maximum database size close to real need plus growth headroom. Setting a 1 TB maximum “just in case” on a General Purpose database means paying for 1 TB every month.
Deploy and Resize an Azure SQL Database
Let’s build a cost-aware database. The scenario is a customer portal with a dev database that sits idle at night.
Create a resource group first. It is a logical container that holds related Azure resources. See how to create a resource group in Azure if you prefer the portal.
az group create \
--name rg-portal-dev \
--location eastus \
--tags owner=app-team costcenter=engineering environment=devThis creates rg-portal-dev in East US. The tags assign an owner and cost center, so you can trace spend later. Learn more about Azure tags.
Now create the logical server. It uses Microsoft Entra-only authentication, which means no SQL password exists to leak:
az sql server create \
--name <sql-server-name> \
--resource-group rg-portal-dev \
--location eastus \
--enable-ad-only-auth \
--external-admin-principal-type Group \
--external-admin-name <entra-admin-group-name> \
--external-admin-sid <entra-admin-group-object-id>Here is what the parameters do:
--enable-ad-only-authturns off SQL logins, so everyone signs in through Microsoft Entra ID.--external-admin-principal-type Groupmakes the administrator an Entra group instead of one person. When someone leaves, you remove them from the group.--external-admin-sidis the group’s object ID.
If Entra ID is new to you, start with the Microsoft Entra ID tutorial for beginners. For general creation steps, follow how to create an Azure SQL database.
Create a serverless dev database:
az sql db create \
--resource-group rg-portal-dev \
--server <sql-server-name> \
--name sqldb-portal-dev \
--edition GeneralPurpose \
--family Gen5 \
--compute-model Serverless \
--capacity 2 \
--min-capacity 0.5 \
--auto-pause-delay 60 \
--max-size 32GB \
--backup-storage-redundancy LocalHere