High-volume systems on SQL Server often suffer from hidden performance issues that do not appear in normal query tuning discussions. One such major issue is memory spills to TempDB. These spills silently degrade performance, increase I/O pressure, worsen concurrency, and make predictable query performance nearly impossible.
This article explains how to detect, analyse, and fix memory spills to TempDB using practical examples, real execution plan interpretation, and production-ready solutions. It is written for senior developers and DB engineers who want deeper performance stability in OLTP or hybrid workloads.
Understanding What Memory Spills Are
SQL Server allocates memory for query operations such as:
Sorting
Hashing
Aggregations
Joins (especially Hash Joins)
When SQL Server cannot allocate enough query workspace memory, the engine is forced to spill the intermediate data to TempDB.
This happens during operators like:
Sort
Hash Match (Build)
Hash Aggregate
Window Spool
Index Spool
These operators require memory grants, and if the estimated memory is insufficient, a spill occurs.
Why Memory Spills Are Dangerous
Memory spills are not just small inefficiencies. They can seriously impact system stability.
Key Effects
Slow Query Execution
Disk I/O is far slower than in-memory operations.TempDB Overload
The biggest cause of TempDB contention in large systems.Unpredictable Latency
SQL Server performs well until memory pressure hits, then becomes extremely slow.Blocked Or Deadlocked Workloads
Heavy TempDB I/O causes resource waits that block other sessions.
How SQL Server Allocates Memory Grants
SQL Server extends workspace memory through a component called the Query Memory Grant Framework.
Simplified:
Query Request
|
+-- Memory Grant Estimate (based on row estimates + stats)
|
+-- If memory available:
| Grant memory
| Execute normally
|
+-- If memory NOT available:
Spill to TempDB
An incorrect memory estimate is the root cause of spills.
Visual Diagram: How Memory Spills Occur
+---------------------------+
| Query Starts Execution |
+-------------+-------------+
|
v
+----------+-----------+
| Memory Grant Needed |
+----------+-----------+
|
+-------------+-------------+
| Enough Memory Available? |
+------+------+-------------+
| Yes | No
| |
v v
+-----------+---------+ +--------+---------+
| Process In Memory | | Spill To TempDB |
+----------------------+ +------------------+
How To Detect Memory Spills
SQL Server provides multiple ways to detect spills:
Execution plans
Actual execution plan warnings
sys.dm_exec_query_stats
sys.dm_db_session_space_usage
sys.dm_exec_query_memory_grants
Extended Events
We deep-dive into each.
Method 1: Detecting Spills In Execution Plans
When a spill occurs, SQL Server marks the operator with a yellow warning symbol.
The Actual Execution Plan will show:
Hash Warning
Sort Warning
Spill Level
Example Warning
Warning: Operator used tempdb to spill data during execution.
Spill level: 2.
Example Plan Snippet
Hash Match (Aggregate)
Actual Number of Rows: 12000000
Estimated Number of Rows: 10000 <-- Bad estimate
Number of Hash Spills: 8
A tell-tale sign is:
EstimatedRows << ActualRows
This mismatch triggers under-estimated memory grants.
Method 2: Using sys.dm_exec_query_stats
This DMV provides information on memory grants and spills.
SELECT
qs.total_spills,
qs.last_spills,
qs.execution_count,
qs.total_worker_time,
qs.last_worker_time,
qs.plan_handle
FROM sys.dm_exec_query_stats qs
ORDER BY qs.total_spills DESC;
Method 3: Checking sys.dm_exec_query_memory_grants
This shows waiting or granted memory.
SELECT
session_id,
requested_memory_kb,
granted_memory_kb,
used_memory_kb,
max_used_memory_kb,
is_next_fetch,
wait_time_ms
FROM sys.dm_exec_query_memory_grants
ORDER BY wait_time_ms DESC;
If used_memory_kb > granted_memory_kb, spilling is likely.
Method 4: Monitoring TempDB Usage During Execution
SELECT
session_id,
internal_objects_alloc_page_count,
internal_objects_dealloc_page_count
FROM sys.dm_db_session_space_usage;
Internal object allocations spike during spills.

Join the conversation! Your thoughts help the community grow.