Introduction

Azure SQL elastic pools share DTU/vCore resources among multiple databases. When one or a few databases consume most resources, other databases in the pool experience performance degradation and throttling.

Symptoms

Pool resource exhausted:

```bash $ az sql elastic-pool show \ --name my-pool \ --server my-server \ --resource-group my-rg \ --query '{DTU:sku.capacity,Used:dtuUsage,DatabaseCount:databaseCount}'

{ "DTU": 400, "Used": 395, # Pool nearly exhausted "DatabaseCount": 15 } ```

Database throttling:

json
{
  "error": {
    "code": "ResourceLimitExceeded",
    "message": "The elastic pool has reached its DTU limit"
  }
}

Imbalanced usage:

sql
-- One database using most pool resources
Database A: 350 DTU (87.5% of pool)
Database B: 30 DTU
Database C: 15 DTU
...

Common Causes

  1. 1.No per-database limits - Databases can consume all pool resources
  2. 2.Mixed workloads - Heavy workload database mixed with light ones
  3. 3.Insufficient pool capacity - Pool too small for combined workload
  4. 4.Single heavy database - One database dominates resource usage
  5. 5.Burstable databases - Databases with occasional high spikes
  6. 6.Missing monitoring - No visibility into per-database consumption

Step-by-Step Fix

Step 1: Check Pool Resource Usage

```bash # Check pool overall usage az sql elastic-pool show \ --name my-pool \ --server my-server \ --resource-group my-rg \ --query '{Name:name,Sku:sku,DTUUsage:dtuUsage,StorageUsage:storageUsage}'

# Monitor pool metrics az monitor metrics list \ --resource /subscriptions/SUB/resourceGroups/my-rg/providers/Microsoft.Sql/servers/my-server/elasticPools/my-pool \ --metric "dtu_usage" \ --query 'value[].timeseries[].data[].average' ```

Step 2: Analyze Per-Database Usage

```sql -- Query per-database resource consumption sqlcmd -S my-server.database.windows.net -d master -U admin -P password -Q " SELECT d.name as database_name, slo.edition, slo.service_objective, slo.elastic_pool_name, ravg.avg_cpu_percent, ravg.avg_data_io_percent, ravg.avg_log_write_percent FROM sys.databases d JOIN sys.database_service_objectives slo ON d.database_id = slo.database_id CROSS APPLY ( SELECT TOP 1 AVG(avg_cpu_percent) as avg_cpu_percent, AVG(avg_data_io_percent) as avg_data_io_percent, AVG(avg_log_write_percent) as avg_log_write_percent FROM sys.dm_db_resource_stats WHERE database_id = d.database_id AND end_time > DATEADD(hour, -24, GETDATE()) ) ravg WHERE slo.elastic_pool_name = 'my-pool' ORDER BY ravg.avg_cpu_percent DESC "

-- Identify databases with high resource usage ```

Step 3: Set Per-Database DTU Limits

```bash # Set max DTU per database az sql db update \ --name heavy-db \ --server my-server \ --resource-group my-rg \ --elastic-pool my-pool \ --max-capacity 50 # Limit to 50 DTU max

# Set min DTU to guarantee resources az sql db update \ --name critical-db \ --server my-server \ --resource-group my-rg \ --elastic-pool my-pool \ --min-capacity 25 # Guaranteed 25 DTU minimum

# Check current per-database limits az sql db show \ --name my-database \ --server my-server \ --resource-group my-rg \ --query '{Min:minCapacity,Max:maxCapacity}' ```

Step 4: Move Heavy Database to Single Database

```bash # If one database dominates pool, move it out az sql db update \ --name heavy-db \ --server my-server \ --resource-group my-rg \ --elastic-pool "" # Remove from pool

# Assign dedicated SKU az sql db update \ --name heavy-db \ --server my-server \ --resource-group my-rg \ --sku Standard \ --capacity 200

# Or create new dedicated pool for heavy databases az sql elastic-pool create \ --name heavy-pool \ --server my-server \ --resource-group my-rg \ --sku Premium \ --capacity 500

az sql db update \ --name heavy-db \ --server my-server \ --resource-group my-rg \ --elastic-pool heavy-pool ```

Step 5: Scale Pool Capacity

```bash # Increase pool DTU if multiple databases need more resources az sql elastic-pool update \ --name my-pool \ --server my-server \ --resource-group my-rg \ --capacity 800 # Increase from 400 to 800 DTU

# For vCore pools az sql elastic-pool update \ --name my-pool \ --server my-server \ --resource-group my-rg \ --capacity 8 \ --family Gen5

# Check available capacities az sql elastic-pool list-editions \ --location eastus \ --query "[?name=='Standard'].{Name:name,Capacities:capacity}" ```

Step 6: Split Databases into Multiple Pools

```bash # Create separate pools by workload type

# Production pool az sql elastic-pool create \ --name prod-pool \ --server my-server \ --resource-group my-rg \ --sku Standard \ --capacity 400

# Dev/test pool az sql elastic-pool create \ --name dev-pool \ --server my-server \ --resource-group my-rg \ --sku Standard \ --capacity 100

# Move databases to appropriate pool az sql db update \ --name prod-db-1 \ --server my-server \ --resource-group my-rg \ --elastic-pool prod-pool

az sql db update \ --name dev-db-1 \ --server my-server \ --resource-group my-rg \ --elastic-pool dev-pool ```

Step 7: Monitor Pool Balance

```bash # Query pool balance metrics az monitor metrics list \ --resource /subscriptions/SUB/resourceGroups/my-rg/providers/Microsoft.Sql/servers/my-server/elasticPools/my-pool \ --metric "dtu_usage,database_storage_used" \ --query 'value[].{Name:name.localizedValue,Values:timeseries[].data[]}'

# Create alert for pool exhaustion az monitor metrics alert create \ --name pool-dtu-alert \ --resource-group my-rg \ --scopes /subscriptions/SUB/resourceGroups/my-rg/providers/Microsoft.Sql/servers/my-server/elasticPools/my-pool \ --condition "avg dtu_usage > 90" \ --window-size 5m ```

Step 8: Implement Database-Level Monitoring

```sql -- Track per-database usage over time sqlcmd -S my-server.database.windows.net -d master -U admin -P password -Q " -- Create table for historical tracking CREATE TABLE dbo.PoolUsageHistory ( LogTime datetime DEFAULT GETDATE(), DatabaseName nvarchar(128), AvgCpuPercent decimal(5,2), AvgIoPercent decimal(5,2), AvgLogPercent decimal(5,2) )

-- Populate with current stats INSERT INTO dbo.PoolUsageHistory (DatabaseName, AvgCpuPercent, AvgIoPercent, AvgLogPercent) SELECT d.name, AVG(r.avg_cpu_percent), AVG(r.avg_data_io_percent), AVG(r.avg_log_write_percent) FROM sys.databases d CROSS APPLY sys.dm_db_resource_stats r WHERE d.database_id > 4 -- Exclude system databases GROUP BY d.name " ```

Step 9: Optimize Heavy Queries

```sql -- In heavy databases, find expensive queries sqlcmd -S my-server.database.windows.net -d heavy-db -U admin -P password -Q " SELECT TOP 10 qs.query_hash, qs.execution_count, qs.total_worker_time / qs.execution_count as avg_cpu, qs.total_elapsed_time / qs.execution_count as avg_duration, SUBSTRING(st.text, qs.statement_start_offset/2 + 1, (CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2 + 1) as query_text FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st ORDER BY qs.total_worker_time DESC "

-- Optimize identified queries to reduce database load ```

Step 10: Configure Pool Auto-Scaling

```bash # For vCore pools, enable auto-scaling (serverless) az sql elastic-pool update \ --name my-pool \ --server my-server \ --resource-group my-rg \ --capacity 2 # Min vCores

# Set auto-pause for dev/test databases az sql db update \ --name dev-db \ --server my-server \ --resource-group my-rg \ --elastic-pool my-pool \ --auto-pause-delay 60 # Pause after 60 minutes inactivity ```

Elastic Pool Sizing Guide

ScenarioRecommended PoolPer-DB Limits
10+ light databasesStandard 100-200 DTUMax 25 DTU each
Mixed workloadsStandard 400-800 DTUSet max per DB
One heavy databaseMove to single DBN/A
Production + DevSeparate poolsDifferent limits

Verification

```bash # After adjusting pool configuration az sql elastic-pool show \ --name my-pool \ --server my-server \ --resource-group my-rg \ --query '{Name:name,DTU:sku.capacity,Databases:databaseCount}'

# Monitor for 24 hours az monitor metrics list \ --resource /subscriptions/SUB/resourceGroups/my-rg/providers/Microsoft.Sql/servers/my-server/elasticPools/my-pool \ --metric "dtu_usage" \ --start-time "2024-01-15T00:00:00Z" \ --end-time "2024-01-15T23:59:59Z" \ --interval PT1H

# Should show: # - Average DTU usage < 70% # - No individual database exceeding max DTU # - No throttling errors in applications ```

Prevention

To prevent Azure SQL elastic pool imbalance issues from recurring, implement these proactive measures:

1. Monitor Pool DTU Usage

yaml
groups:
- name: azure-sql-pool
  rules:
  - alert: AzureSQLElasticPoolImbalanced
    expr: |
      azure_sql_elastic_pool_dtu_usage_percent > 90
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "Azure SQL elastic pool DTU usage exceeds 90%"

2. Implement Database Tiering

```bash # Group databases by resource usage az sql db create --name light-app-db --resource-group my-rg --server my-server --elastic-pool my-light-pool --service-objective elasticPool az sql db create --name heavy-app-db --resource-group my-rg --server my-server --elastic-pool my-heavy-pool --service-objective elasticPool

# Create separate pools based on workload type az sql elastic-pool create --name my-light-pool --resource-group my-rg --server my-server --edition Standard --dtu 50 az sql elastic-pool create --name my-heavy-pool --resource-group my-rg --server my-server --edition Standard --dtu 200 ```

3. Configure Database Limits

```bash # Set min/max DTU per database az sql db update --name my-db --resource-group my-rg --server my-server --elastic-pool my-pool --min-capacity 5 --max-capacity 50

# Prevent single database from consuming all pool resources ```

Best Practices Checklist

  • [ ] Monitor pool DTU usage
  • [ ] Implement database tiering
  • [ ] Configure database min/max limits
  • [ ] Review database workload patterns
  • [ ] Scale pool before peak usage
  • [ ] Monitor individual database usage
  • [Fix Azure SQL Database DTU Limit](/articles/fix-azure-sql-database-dtu-limit)
  • [Fix Azure SQL Database Geo-Replica Lag](/articles/fix-azure-sql-database-geo-replica-lag)
  • [Fix Azure SQL Database Deadlock](/articles/fix-azure-sql-database-deadlock)
  • [Technical troubleshooting: Fix Azure Aks Pod Crashloopbackoff Issue in Azure](azure-aks-pod-crashloopbackoff)
  • [Technical troubleshooting: Fix Azure Api Management Policy Expression Runtime](azure-api-management-policy-expression-runtime-error)
  • [Technical troubleshooting: Fix Azure App Configuration Feature Flag Not Refre](azure-app-configuration-feature-flag-not-refreshing)
  • [Technical troubleshooting: Fix Azure App Service 503 Always On Disabled Issue](azure-app-service-503-always-on-disabled)
  • [Technical troubleshooting: Fix Azure Application Gateway Err SSL Unrecognized](azure-application-gateway-err-ssl-unrecognized-name-alert)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Azure SQL Elastic Pool Imbalanced", "description": "Troubleshoot Azure SQL elastic pool resource imbalance. Adjust per-database limits, move databases, or scale the pool.", "url": "https://www.fixwikihub.com/fix-azure-sql-elastic-pool-imbalanced", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-03T18:22:07.470Z", "dateModified": "2026-04-03T18:22:07.470Z" } </script>