
Azure SQL DatabaseAuthorCloudBrum editorial teamLast reviewedReading time~12 minLevelBeginner to advanced
Microsoft Azure · Databases · Managed SQL Server database
SQL Server as a service, one database at a time. Azure SQL Database runs the latest SQL Server engine for you, patched and backed up, and bills you for the database rather than for a server. You choose between a pay-per-second serverless option that can pause when idle and provisioned tiers for steady load, and between several ways to protect and replicate the data. It isn’t a full SQL Server instance: the things that live outside one database, such as SQL Agent jobs and cross-database queries, work differently or need another service.
On this page (17 sections)
Mind map: Azure SQL Database at a glance
Free to share. The downloaded image includes the CloudBrum link.
Key features (summary)
- The SQL Server engine, managedYou get current SQL Server behaviour and T-SQL, with no patching, no installation and no hardware. Compatibility levels let an older application keep its old behaviour while it still runs here.
- Serverless that pausesServerless compute scales between a minimum and maximum number of vCores, bills per second of use, and can pause when no one is connected. Storage is billed while it’s paused. It suits development databases and spiky workloads.
- Three vCore tiersGeneral Purpose is the default for most applications. Business Critical keeps local SSD storage and replicas for low latency and fast failover. Hyperscale separates compute from storage so the database can grow very large and add read replicas quickly.
- Elastic poolsSeveral databases share one pool of resources, which works well when many small databases each peak at different times, as in a multi-tenant product.
- Backups you can browse back in timeBackups run automatically, and point-in-time restore builds a new database at a moment inside the retention window (7 days by default, up to 35). Long-term retention keeps selected backups for up to ten years.
- Geo-replication and failover groupsReplicate a database to another Region and fail over by hand, or group databases so the whole set fails over together behind stable listener names.
- Security built around the databaseData is encrypted at rest by default, connections use TLS, and you can add Entra-only sign-in, private endpoints, Defender for SQL, auditing, data masking, row-level security and Always Encrypted.
- Tuning helpQuery Store records query history, and automatic tuning can add or remove indexes and force a known good plan when a new plan runs worse.
Basic concepts
- Logical server
- A name and a set of settings (firewall, admins, authentication) that databases hang off. It isn’t a machine, and it holds no data itself.
- Single database
- One database with its own resources and its own bill.
- Elastic pool
- A shared allotment of resources for a group of databases on the same logical server.
- vCore model
- You choose the number of virtual cores and a tier, then storage separately. It’s the model that supports serverless, Hyperscale, reservations and Azure Hybrid Benefit.
- DTU model
- An older bundled measure of compute, memory and I/O sold as Basic, Standard and Premium. Simple to buy, harder to size.
- Serverless
- A vCore compute option with an automatic range and a pause delay. Paused databases bill for storage only.
- Zone redundancy
- Replicas spread over Availability Zones in the Region, so a zone failure doesn’t take the database down.
- Active geo-replication
- An asynchronous readable copy of a database in another Region that you fail over by command.
- Failover group
- A set of databases that fail over together, with read-write and read-only listener endpoints that keep their names.
- Point-in-time restore
- Creates a new database from the backups at a chosen moment. The original isn’t overwritten.
- Long-term retention (LTR)
- A policy that keeps weekly, monthly or yearly backups for up to ten years.
- Query Store
- A built-in history of queries, plans and runtime statistics that helps you see regressions.
- Private endpoint
- A private IP in your virtual network for the logical server, with traffic staying on Microsoft’s network.
- Microsoft Entra-only authentication
- A server setting that turns off SQL logins, so everyone signs in through Entra ID.
How to create & configure it
Create a serverless database in the Azure portal
- Pick a Region and decide on private accessStart with the Region (Central India for many Indian teams) and with whether the logical server will be private, since that’s far easier to design in than to retrofit.
- Create the databaseSearch for Azure SQL, choose SQL databases, then Create. Pick a resource group and a database name, and create a new server or choose an existing one.
- Set authentication on the serverChoose Use Microsoft Entra-only authentication, and set an Entra user or group as the server administrator. This avoids a shared SQL admin password.
- Choose the computeSelect General Purpose and Serverless for development or spiky load, with a minimum of 0.5 vCores and an auto-pause delay of an hour. For steady production load, pick provisioned compute instead.
- Pick the backup redundancyChoose how the backups are stored: locally, across zones, or across Regions. Zone or geo storage costs more and can’t always be changed freely later.
- Set the networkingOn the Networking tab choose Private endpoint, select the virtual network and subnet, and turn off public access. Add a private DNS integration so the server name resolves to the private address.
- Check security optionsLeave transparent data encryption on, and consider enabling Microsoft Defender for SQL and auditing to a Log Analytics workspace.
- Create users and testConnect from a machine in the network, run CREATE USER [name] FROM EXTERNAL PROVIDER for each application identity, and grant only the roles it needs.
- Set limits and watch costsSet the maximum size, check the backup retention (7 days by default), and set a budget alert. Test a point-in-time restore to a new database.
Tip: after you’ve seen the portal flow, record the same choices as code (the Azure CLI, Bicep or Terraform, see the code references), so that reviews catch things like Entra-only sign-in, backup redundancy and public access.
Common issues after configuration
| Symptom | Likely cause | What to check / fix |
|---|---|---|
| Error 40615: client IP is not allowed to access the server | The firewall doesn’t list your address, or the server is private and you came in from the internet | Add your address as a server firewall rule for a public server, or connect from inside the virtual network through the private endpoint. |
| Login failed for a token-identified principal | The Entra identity has no user in the database, or the token was issued for the wrong resource | Create the user with CREATE USER ... FROM EXTERNAL PROVIDER while signed in as the Entra admin, and ask for a token for https://database.windows.net/. |
| Error 40613: database is not currently available | A serverless database is resuming from auto-pause, or a failover is in progress | Retry with a short back-off. The first connection after a pause can take several seconds to a minute, and the client should expect it. |
| Errors 40197, 40501 or 49918 and friends | Transient faults while the service rebalances, patches or throttles | Treat these as retryable. Use the driver’s built-in retry logic or a retry policy with exponential back-off, and keep transactions short and idempotent. |
| Error 10928 or 10929: resource limit reached | Too many concurrent workers or sessions for the compute size | Find the heavy queries in Query Store, reduce parallel connections, add pooling, and scale up only after tuning. |
| Error 40544: the database has reached its size quota | Data and log growth hit the configured maximum | Raise the maximum size (or tier), clean up large tables and indexes, and set an alert at 80 per cent of the size. |
| The serverless database never pauses | Something keeps a session open or CPU busy | Close idle connections from tools such as SSMS, check background jobs and monitoring probes, and keep the pause delay realistic. |
| Msg 40515: reference to a database in another database isn’t supported | Cross-database queries aren’t available between single databases | Put the tables in one database, use elastic query, or use SQL Managed Instance if you rely on cross-database work. |
| The application can’t find the database after a failover | It connects to the primary server’s name instead of the failover group listener | Use the failover group’s read-write listener in connection strings, and keep the secondary server’s firewall and network rules in step. |
| A new query plan makes things slower | Plan regression after a statistics update, a new index or a version change | Open Query Store, compare plans, force the previous plan or turn on automatic plan correction, then fix the underlying cause. |
| A restore made a new database and the app still uses the old one | A restore never overwrites; it produces another database | Repoint the application (or rename the databases) after you’ve checked the restored data. |
Use cases: when and where to use it
Good fit
- New applications built on SQL Server and T-SQL that want no database administration
- Moving a single SQL Server database to the cloud when it doesn’t depend on server-level features
- Multi-tenant SaaS products with many small databases, using elastic pools
- Development and test databases that should cost nothing while idle, using serverless
- Very large operational databases that need quick scale and restore, using Hyperscale
- Applications that need Regional resilience with failover groups
Consider something else
- A near-complete SQL Server instance, with SQL Agent, cross-database queries and linked servers → Azure SQL Managed Instance
- Full control of the operating system or a specific SQL Server version → SQL Server on Azure Virtual Machines
- PostgreSQL applications → Azure Database for PostgreSQL, and MySQL applications → Azure Database for MySQL
- Globally distributed, schema-flexible data → Azure Cosmos DB
- The same job on other clouds → compare Amazon RDS for SQL Server and Cloud SQL for SQL Server
Pros: why consider it?
Why teams choose it
- The newest SQL Server engine with no patching, backups or hardware to manage
- Serverless lets a database cost very little while nobody uses it
- Hyperscale handles very large databases and fast restores
- Strong built-in security, with Entra-only sign-in and private endpoints
- Geo-replication and failover groups for Regional disaster recovery
- Tuning features such as Query Store and automatic plan correction are built in
Trade-offs to weigh
- It isn’t a full SQL Server instance: no SQL Agent, linked servers or cross-database queries between databases
- Pricing has several models and options, and it takes effort to compare them
- Serverless adds a delay on the first connection after a pause
- Some choices, such as backup redundancy and tier changes, have conditions
- Compute limits throttle a database sharply when it hits its resource ceiling
- Moving to another cloud means changing the database engine or running SQL Server yourself
Common threats, vulnerabilities & risks
| Risk | Severity | Why it matters | Mitigation |
|---|---|---|---|
| A server whose firewall lets in too much | High | Allowing Azure services or large address ranges exposes the database to far more than your own application. | Disable public access, use a private endpoint, and review firewall rules if any remain. |
| Shared SQL logins and stored passwords | High | A SQL admin password in configuration is hard to rotate and easy to leak. | Use Entra-only authentication with managed identities, and grant database roles to identities rather than people. |
| No tested restore | High | A backup nobody has restored is only a guess about recovery. | Restore into a fresh database on a schedule, inspect the data and note how long it took. |
| Backups kept in the wrong place | Medium | Local redundancy won’t survive the loss of a zone or Region. | Choose zone or geo-redundant backup storage to match your recovery needs, and set long-term retention where regulations require it. |
| Failing over without a plan | Medium | Applications that use the primary’s name or hold stale connections break at the worst moment. | Use failover group listeners, retry logic and a practised failover drill. |
| Hitting the size quota | Medium | The database goes read-only for writes, and raising the size takes time. | Alert at 80 per cent, plan growth and clean up large tables and logs. |
| Over-privileged application users | Medium | An application with db_owner can drop tables as easily as read them. | Create separate roles for migration and runtime access, and grant the minimum. |
| Plan regressions after changes | Low–Med | A new plan can multiply query times without anyone changing the code. | Keep Query Store on, review regressions after each release, and use automatic plan correction. |
| Unwatched cost from over-provisioning | Low–Med | Provisioned vCores bill every hour whether or not they’re used. | Use serverless for spiky or idle databases, review utilisation monthly and use reservations for steady ones. |
Performance optimisation
- Size by measurement: CPU, workers, log I/O and data I/O in the portal. Add vCores or move tier when a limit is the problem, not by guessing.
- Find expensive queries in Query Store and Query Performance Insight, and fix missing indexes before scaling up.
- Turn on automatic tuning for plan correction, and review index suggestions before accepting them in production.
- Use connection pooling and keep connections short, since each tier has a worker and session ceiling.
- Build retry logic into the application for transient errors. It’s part of how this service is meant to be used.
- Use read scale-out (Business Critical and Hyperscale) or named replicas (Hyperscale) to send reporting reads away from the primary.
- Keep the application in the same Region as the database, and use failover group listeners for cross-Region setups.
- Choose Hyperscale when databases are large and restores, scale-up or replica creation must be quick.
Reduce monthly cost
FinOps is the habit of managing cloud spend together with engineering. These are the FinOps checks that matter most for Azure SQL Database.
- Use serverless with auto-pause for development and spiky databases, and choose the shortest pause delay that your users can tolerate.
- Check whether a database qualifies for the free offer, which gives a monthly allowance of serverless compute and storage per database.
- Put many small databases in an elastic pool instead of sizing each one for its own peak.
- Use Azure Hybrid Benefit if you own SQL Server licences with Software Assurance, and reservations for steady provisioned compute.
- Pick the tier honestly. Business Critical costs substantially more than General Purpose, so use it only when you need the latency and replicas.
- Keep short-term retention to what you need (7 days is the default) and long-term retention to compliance requirements, as backup storage beyond the free allowance bills.
- Delete restored copies, old replicas and test databases when you’re done with them.
- Right-size by checking utilisation, and drop a size or a vCore when graphs are flat.
- Choose backup storage redundancy deliberately. Zone and geo-redundant storage cost more than local.
- Label databases with owner and environment, and add budgets and alerts through Cost Management.
What you see here are samples of Microsoft's published prices and offers. Tier, compute model, Region and date all move them, so check the live figures first (see Pricing).
Security optimisation
- Turn on Microsoft Entra-only authentication on the logical server, set an admin group, and give applications managed identities.
- Disable public network access and use a private endpoint with a private DNS zone. If you keep public access, list specific addresses only.
- Require TLS 1.2 as the minimum, and connect with encryption mandatory and server certificate validation on.
- Leave transparent data encryption on, and use customer-managed keys in Key Vault where policy requires it.
- Turn on auditing to a Log Analytics workspace or storage account, and Microsoft Defender for SQL for threat detection and vulnerability assessment.
- Grant database roles and schema permissions to application identities, and avoid db_owner for runtime access.
- Use dynamic data masking, row-level security and Always Encrypted for sensitive columns where they fit.
- Use the ledger feature for tables that need tamper-evidence.
- Apply Azure Policy to require Entra-only authentication, private access and auditing, and add resource locks to production servers.
- Review who holds the roles that can change firewall, authentication and backup settings, and use Privileged Identity Management for them.
Governance & compliance
Guardrails
- Policy that requires Entra-only authentication, disabled public access, auditing and TLS 1.2 on every server
- A template (Bicep or Terraform) for databases with backup redundancy, retention and diagnostics already set
- A tagging rule (owner, environment, data class, cost centre) and a budget for each subscription
- A rule that production databases are created only by the deployment pipeline
Policies and checks worth automating (Azure Policy, Defender for Cloud)
- A policy that audits or denies logical servers without Microsoft Entra-only authentication
- A policy that audits servers with public network access enabled
- A policy that audits databases without auditing or transparent data encryption turned on
- A check that geo-redundant or zone-redundant backup is set where recovery targets need it
- A custom report of non-production databases that have been provisioned for longer than a set time
To see who changed a server or database, read the Activity log and Azure Monitor. Azure Policy applies the rules above, Defender for Cloud reports posture, and Microsoft Purview can catalogue and classify data. Compliance reports sit in the Service Trust Portal. The split is the usual one: Microsoft runs the platform, engine patching and backups, and you are accountable for the data, the schema, the permissions, the network exposure and your recovery tests.
Reduce carbon footprint
- Use serverless for databases that sit idle, so compute isn’t running while no one connects.
- Right-size provisioned databases, because spare vCores draw power all day.
- Delete test databases, old replicas and restored copies when they’ve done their job.
- Tune queries and indexes so the same database does more work with fewer resources.
- Keep retention to what you actually need, since every extra backup occupies storage.
- If the work doesn’t have to sit in a particular place, a Region on a cleaner grid is an option, data rules permitting.
- Emissions Impact Dashboard figures come per subscription; check what they include for databases before you cite one.
Pricing
Purchase options
Provisioned compute Per vCore-hour
You pay for the vCores you’ve chosen every hour, by tier. Business Critical costs more than General Purpose, and Hyperscale prices compute and storage separately.
Serverless compute Per vCore-second used
Billed for the compute actually used between your minimum and maximum, per second. A paused database bills only for storage, and a monthly free allowance is available per database.
DTU bundles Per database-hour
A simple bundle of compute, memory and I/O in Basic, Standard and Premium. Easier to buy, but less flexible than vCore.
Storage and backups Per GB-month
Data storage is billed by the size you reserve. Backup storage up to the size of the database is free, and long-term retention and extra backups are charged.
What you actually pay for
- Compute: vCore-hours (provisioned) or vCore-seconds (serverless), or DTUs
- Data storage, by the maximum size you set
- Backup storage beyond the free allowance, plus long-term retention
- Geo-replicas and named replicas, billed like databases
- Network egress between Regions, Defender for SQL and Log Analytics ingestion
Prices vary by Region, tier, compute model and licence option, and change over time. Microsoft documents a free offer that gives each database a monthly allowance of serverless compute and storage, up to a set number of databases per subscription, so check whether it fits. Use the official Azure SQL Database pricing page and the Azure pricing calculator for current figures, and the Azure SQL Database free offer page for its terms.
Important code references
The orders database on Azure SQL Database: a serverless General Purpose database on a private, Entra-only server, 14 days of point-in-time restore, weekly long-term backups and a failover group to a second Region. Build it from the CLI or Terraform tab. The Python and C# tabs sign in with a Microsoft Entra token over encrypted connections and insert an order, retrying the transient errors that serverless and failovers produce. Server names, the Entra administrator and the subscription are placeholders. The T-SQL samples weren’t run against a real SQL Server in my checks, so test them on a development database first.
# Names are examples; a server name must be unique across Azure.
RG=rg-orders-sql
LOCATION=centralindia
PARTNER_LOCATION=southindia
SERVER=orders-sql-001
PARTNER=orders-sql-002
ADMIN_ID=00000000-0000-0000-0000-000000000000 # object ID of the Entra group that administers the servers
az group create --name $RG --location $LOCATION
# A logical server with Entra-only sign-in, no public access and TLS 1.2 as the minimum
# (the CLI marks --enable-public-network as a preview argument, so it may print a warning)
az sql server create --resource-group $RG --name $SERVER --location $LOCATION \
--enable-ad-only-auth --external-admin-principal-type Group \
--external-admin-name orders-db-admins --external-admin-sid $ADMIN_ID \
--enable-public-network false --minimal-tls-version 1.2
# A serverless General Purpose database: 0.5 to 2 vCores, pauses after an hour of silence
az sql db create --resource-group $RG --server $SERVER --name orders \
--edition GeneralPurpose --family Gen5 --compute-model Serverless \
--capacity 2 --min-capacity 0.5 --auto-pause-delay 60 \
--max-size 32GB --backup-storage-redundancy Zone
# 14 days of point-in-time restore, and weekly backups kept for four weeks, monthly for a year
az sql db str-policy set --resource-group $RG --server $SERVER --name orders --retention-days 14
az sql db ltr-policy set --resource-group $RG --server $SERVER --name orders \
--weekly-retention P4W --monthly-retention P12M --week-of-year 1
# A private endpoint for the logical server (a private DNS zone makes the normal server name resolve to it)
az network vnet create --resource-group $RG --name vnet-orders --address-prefixes 10.30.0.0/16 \
--subnet-name snet-data --subnet-prefixes 10.30.1.0/24
SQL_ID=$(az sql server show --resource-group $RG --name $SERVER --query id --output tsv)
az network private-endpoint create --resource-group $RG --name pe-orders-sql \
--vnet-name vnet-orders --subnet snet-data \
--private-connection-resource-id $SQL_ID --group-id sqlServer --connection-name orders-sql
az network private-dns zone create --resource-group $RG --name privatelink.database.windows.net
az network private-dns link vnet create --resource-group $RG --zone-name privatelink.database.windows.net \
--name orders-sql-link --virtual-network vnet-orders --registration-enabled false
az network private-endpoint dns-zone-group create --resource-group $RG --endpoint-name pe-orders-sql \
--name default --private-dns-zone privatelink.database.windows.net --zone-name sql
# A second server in the paired Region and a failover group, so the whole database can move together
az sql server create --resource-group $RG --name $PARTNER --location $PARTNER_LOCATION \
--enable-ad-only-auth --external-admin-principal-type Group \
--external-admin-name orders-db-admins --external-admin-sid $ADMIN_ID \
--enable-public-network false --minimal-tls-version 1.2
az sql failover-group create --resource-group $RG --name orders-fog \
--server $SERVER --partner-server $PARTNER --add-db orders \
--failover-policy Automatic --grace-period 1
# Practise the restore: a new database from the backups, at a time you choose (UTC)
az sql db restore --resource-group $RG --server $SERVER --name orders --dest-name orders-restore-test \
--time "2026-10-29T08:30:00Z"
# Assumes azurerm provider 4.x. The private endpoint is for the primary server; add a second server and
# azurerm_mssql_failover_group in the paired Region for cross-Region failover.
provider "azurerm" {
features {}
}
variable "admin_object_id" { type = string } # Entra group that administers the server
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "orders" {
name = "rg-orders-sql"
location = "centralindia"
}
resource "azurerm_mssql_server" "orders" {
name = "orders-sql-001"
resource_group_name = azurerm_resource_group.orders.name
location = azurerm_resource_group.orders.location
version = "12.0"
minimum_tls_version = "1.2"
public_network_access_enabled = false
azuread_administrator {
login_username = "orders-db-admins"
object_id = var.admin_object_id
tenant_id = data.azurerm_client_config.current.tenant_id
azuread_authentication_only = true
}
}
resource "azurerm_mssql_database" "orders" {
name = "orders"
server_id = azurerm_mssql_server.orders.id
sku_name = "GP_S_Gen5_2" # General Purpose, serverless, 2 vCores maximum
max_size_gb = 32
min_capacity = 0.5
auto_pause_delay_in_minutes = 60
storage_account_type = "Zone"
short_term_retention_policy {
retention_days = 14
}
long_term_retention_policy {
weekly_retention = "P4W"
monthly_retention = "P12M"
week_of_year = 1
}
tags = { owner = "orders-team" }
}
resource "azurerm_virtual_network" "orders" {
name = "vnet-orders"
location = azurerm_resource_group.orders.location
resource_group_name = azurerm_resource_group.orders.name
address_space = ["10.30.0.0/16"]
}
resource "azurerm_subnet" "data" {
name = "snet-data"
resource_group_name = azurerm_resource_group.orders.name
virtual_network_name = azurerm_virtual_network.orders.name
address_prefixes = ["10.30.1.0/24"]
}
resource "azurerm_private_dns_zone" "sql" {
name = "privatelink.database.windows.net"
resource_group_name = azurerm_resource_group.orders.name
}
resource "azurerm_private_dns_zone_virtual_network_link" "sql" {
name = "orders-sql-link"
resource_group_name = azurerm_resource_group.orders.name
private_dns_zone_name = azurerm_private_dns_zone.sql.name
virtual_network_id = azurerm_virtual_network.orders.id
}
resource "azurerm_private_endpoint" "sql" {
name = "pe-orders-sql"
location = azurerm_resource_group.orders.location
resource_group_name = azurerm_resource_group.orders.name
subnet_id = azurerm_subnet.data.id
private_service_connection {
name = "orders-sql"
private_connection_resource_id = azurerm_mssql_server.orders.id
subresource_names = ["sqlServer"]
is_manual_connection = false
}
private_dns_zone_group {
name = "default"
private_dns_zone_ids = [azurerm_private_dns_zone.sql.id]
}
}
# pip install pyodbc azure-identity (and install "ODBC Driver 18 for SQL Server" from Microsoft)
# One-off, as the Entra admin: CREATE USER [orders-app] FROM EXTERNAL PROVIDER;
# ALTER ROLE db_datareader ADD MEMBER [orders-app]; ALTER ROLE db_datawriter ADD MEMBER [orders-app];
import struct
import time
import pyodbc
from azure.identity import DefaultAzureCredential
SERVER = "orders-sql-001.database.windows.net" # with a private endpoint this name resolves to a private address
DATABASE = "orders"
SQL_COPT_SS_ACCESS_TOKEN = 1256 # the ODBC attribute that carries an Entra access token
TRANSIENT = {"40613", "40197", "40501", "49918", "49919", "49920"}
credential = DefaultAzureCredential()
def connect():
"""Open an encrypted connection. The Entra token replaces a password, and the driver sends it in a struct."""
token = credential.get_token("https://database.windows.net/.default").token.encode("utf-16-le")
packed = struct.pack(f"<I{len(token)}s", len(token), token)
return pyodbc.connect(
f"Driver={{ODBC Driver 18 for SQL Server}};Server=tcp:{SERVER},1433;Database={DATABASE};"
"Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30",
attrs_before={SQL_COPT_SS_ACCESS_TOKEN: packed})
def place_order(conn, customer_id, total_cents):
"""Insert one order in a transaction and return its id (OUTPUT hands the new key back)."""
cursor = conn.cursor()
try:
cursor.execute(
"INSERT INTO dbo.orders (customer_id, total_cents) OUTPUT INSERTED.id VALUES (?, ?)",
customer_id, total_cents)
order_id = cursor.fetchone()[0]
conn.commit()
return order_id
except Exception:
conn.rollback()
raise
finally:
cursor.close()
def is_transient(error):
return any(code in str(error) for code in TRANSIENT)
def with_retry(action, attempts=5):
"""A serverless database that is resuming, or a failover, answers with a transient error. Back off and try again."""
delay = 2
for attempt in range(attempts):
conn = None
try:
conn = connect()
return action(conn)
except pyodbc.Error as error:
if attempt == attempts - 1 or not is_transient(error):
raise
time.sleep(delay)
delay *= 2
finally:
if conn is not None:
conn.close()
if __name__ == "__main__":
print("New order:", with_retry(lambda c: place_order(c, 42, 129900)))
// Program.cs: sign in with Microsoft Entra, retry transient errors, and insert an order
// NuGet package: Microsoft.Data.SqlClient
using Microsoft.Data.SqlClient;
var builder = new SqlConnectionStringBuilder
{
DataSource = "tcp:orders-sql-001.database.windows.net,1433",
InitialCatalog = "orders",
Authentication = SqlAuthenticationMethod.ActiveDirectoryDefault, // managed identity, developer sign-in or environment credentials
Encrypt = SqlConnectionEncryptOption.Mandatory,
ConnectTimeout = 30
};
// Built-in retry logic: a serverless database that is resuming, or a failover, produces transient errors
var retry = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(new SqlRetryLogicOption
{
NumberOfTries = 5,
DeltaTime = TimeSpan.FromSeconds(2),
MaxTimeInterval = TimeSpan.FromSeconds(30),
TransientErrors = new[] { 40613, 40197, 40501, 49918, 49919, 49920 }
});
await using var conn = new SqlConnection(builder.ConnectionString) { RetryLogicProvider = retry };
await conn.OpenAsync();
await using var tx = (SqlTransaction)await conn.BeginTransactionAsync();
await using var cmd = new SqlCommand(
"INSERT INTO dbo.orders (customer_id, total_cents) OUTPUT INSERTED.id VALUES (@customer, @total)", conn, tx);
cmd.Parameters.AddWithValue("@customer", 42L);
cmd.Parameters.AddWithValue("@total", 129900);
var id = (long)(await cmd.ExecuteScalarAsync())!;
await tx.CommitAsync();
Console.WriteLine($"Created order {id}");
Best videos to explore
Short walkthrough videos for this service are being prepared. They will appear here and load only when you press play. Until then, follow CloudBrum on YouTube for new videos.
Interview questions
BasicWhat is Azure SQL Database?
It’s Microsoft’s managed database service built on the SQL Server engine. You create a database on a logical server, choose how much compute it gets, and Azure handles patching, backups and high availability. It’s billed per database rather than per machine.
BasicWhat is the difference between Azure SQL Database and Azure SQL Managed Instance?
SQL Database gives you one database (or a pool of them) with the engine managed for you, and lacks server-level features such as SQL Agent and cross-database queries between separate databases. Managed Instance is a near-complete SQL Server instance in your virtual network, which suits migrations of applications that depend on those server features, at higher cost.
BasicWhat is serverless compute, and when would you use it?
A compute option where the database scales between a minimum and maximum number of vCores, bills per second for what it uses, and can pause when nobody is connected. It suits development databases and spiky or intermittent workloads. It isn’t ideal for latency-sensitive production traffic, because the first connection after a pause is slow.
IntermediateHow do backups and restores work?
Azure takes full, differential and log backups automatically. Point-in-time restore creates a new database at a moment inside the retention window, which is 7 days by default and configurable up to 35. Long-term retention policies keep weekly, monthly or yearly backups for up to ten years. Restores never overwrite the original database.
IntermediateHow do you remove SQL passwords from an application?
Turn on Microsoft Entra-only authentication for the server, give the app a managed identity, create a database user for it with CREATE USER ... FROM EXTERNAL PROVIDER, and grant roles. The app then asks Entra for a token for the SQL Database resource, or uses the Active Directory Default option in the driver, and no secret is stored.
IntermediateWhat do you do about transient errors?
Expect them. Errors such as 40613 (database not available), 40197 and 40501 happen during failovers, patching, throttling and when a serverless database resumes. Use the driver’s retry logic or a back-off retry loop, keep transactions short and make operations safe to repeat.
AdvancedCompare active geo-replication with failover groups.
Both replicate a database to another Region asynchronously, so some recent data can be lost on a forced failover. Active geo-replication works per database, you fail over by command, and connection strings must change. Failover groups manage a set of databases together, offer automatic failover and provide read-write and read-only listener names that stay the same after a failover, so applications usually need no change.
AdvancedWhen would you choose Hyperscale?
When databases are very large, or when fast scale-up, quick restores and quick creation of read replicas matter. Hyperscale separates compute from a distributed storage layer, supports named replicas for read scale-out, and allows sizes far above the other tiers. It’s priced differently, so test cost for your workload, and check the current limits and any features that differ.
AdvancedA serverless database stays running all night. How do you find out why?
Auto-pause needs zero sessions and zero CPU for the whole delay. Look for open connections from tools such as SSMS or Data Studio, applications that poll or hold pooled connections, monitoring probes and scheduled jobs. Query the sessions and request DMVs, check metrics for vCore use, and either close or move the offenders, or choose provisioned compute if it genuinely needs to be up.
AdvancedDesign a plan to survive the loss of a whole Region.
Create a secondary logical server in the paired Region, set up a failover group for the databases, and choose geo-redundant backup storage. Make sure the secondary has matching firewall, private endpoint and authentication settings, use the listener names in connection strings, and run failover drills. State the RPO and RTO honestly, since replication is asynchronous.
Similar or alternative services on other clouds
| Capability | AWS | Azure | Google Cloud |
|---|---|---|---|
| Service | Amazon RDS for SQL Server | Azure SQL Database | Cloud SQL for SQL Server |
| What you buy | An instance with a licence option | A database (or pool), on the vCore or DTU model | An instance, by edition and machine tier |
| Pausing when idle | Stop an instance for up to seven days | Serverless compute pauses automatically | Instances can be stopped through the activation policy |
| Very large databases | Up to 64 TiB of storage per instance, with limits by engine | Hyperscale for databases far larger than the other tiers | Up to 64 TB per instance |
| Passwordless sign-in | Active Directory integration for SQL Server | Microsoft Entra authentication, with Entra-only mode | Managed Microsoft AD or SQL logins |
| Cross-Region resilience | Cross-Region read replicas and snapshot copies | Active geo-replication and failover groups | Cross-Region read replicas |
| Server-level features (Agent, linked servers) | Supported on RDS for SQL Server | Not in SQL Database; use SQL Managed Instance | More limited in Cloud SQL for SQL Server; check its supported-features list |
| Private networking | VPC subnet groups and security groups | Private endpoint with private DNS | A private address in your VPC (private services access) |
For applications that depend on server-level SQL Server features, Azure SQL Managed Instance or SQL Server on a virtual machine is the closer fit than SQL Database. The open-source engines have their own services: Azure Database for PostgreSQL and Azure Database for MySQL. Applications that use the database often run on Azure Functions or Azure Virtual Machines.
Did you find this article helpful?
Your answer helps us improve this page for the next reader.
Sources and further reading
CloudBrum wrote this page in its own words, using the provider’s public documentation listed below as the reference. Features, limits, names and prices change, so confirm anything that matters on the provider’s own pages before you decide.
- What is Azure SQL Database?Microsoft
- vCore purchasing model overviewMicrosoft
- Azure SQL Database free offerMicrosoft
- Hyperscale service tierMicrosoft
- Automated backups in Azure SQL DatabaseMicrosoft
- Long-term retention overviewMicrosoft
- Active geo-replication overviewMicrosoft
- Auto-failover groups overviewMicrosoft
- An overview of Azure SQL Database security capabilitiesMicrosoft
- Azure SQL Database pricingMicrosoft
- Terraform azurerm: mssql_databaseHashiCorp
