Azure SQL Performance Troubleshooting: When High Latency Is Not High CPU
When an Azure SQL Database experiences performance issues, simply checking CPU utilization is insufficient. Queries may spend most of their time waiting rather than executing, even with healthy resource metrics. The crucial question is where the elapsed time is being spent, not just how much CPU is being used. Resource utilization should be the initial checkpoint, and a query on sys.dm_db_resource_stats can identify if CPU, Data IO, Log IO, memory, or worker limits are being approached. If resources are not saturated, then analysis of wait statistics is necessary.Wait patterns, like PAGELATCH_* for in-memory contention or LCK_M_* for blocking, indicate areas to investigate further. PAGEIOLATCH_* waits are linked to physical I/O, while PAGELATCH_* waits concern synchronization on pages already in memory and can be caused by high concurrency on a single hot page. The frequency of query executions also significantly impacts performance, not just individual query cost. Query Store is vital for tracking query execution history, allowing comparison of durations, CPU usage, and wait behaviors over time.If a query has a long elapsed time but low CPU usage, investigate waits such as ASYNC_NETWORK_IO, which often indicates the client application is not consuming results quickly enough. Measuring time to the first row versus time to the last row can help differentiate database response time from result consumption time. Persistent blocking, where sessions wait for another transaction, can also cause perceived slowness even with low CPU. Scaling a database can mask the root cause by improving general resource availability rather than addressing the underlying performance bottleneck. A practical workflow involves defining incident windows, checking resources, comparing CPU to elapsed time, identifying dominant waits, checking blocking, using Query Store, inspecting execution plans, and investigating the application. Ultimately, effectively troubleshooting Azure SQL performance requires understanding where time is spent, rather than just how busy the database appears.