Diagnosing TempDB Contention in SQL Server: GAM, SGAM, PFS, and Multiple Data Files

Diagnosing TempDB Contention in SQL Server: GAM, SGAM, PFS, and Multiple Data Files

The previous lesson’s latch pattern shows up at system scale in one very specific, very common place: tempdb’s allocation pages, under heavy use of temp tables and table variables (yes — straight back to Course 2’s temp objects material).

TempDB allocation-page pileup(GAM / SGAM / PFS contention)BEFORE: one tempdb fileGAM / SGAM / PFSsingle hot pageT1T2T3T4the fixAFTER: 4 equal-size filesFile 1gets: T1, T5, T9…own GAM/PFS pageFile 2gets: T2, T6, T10…own GAM/PFS pageFile 3gets: T3, T7, T11…own GAM/PFS pageFile 4gets: T4, T8, T12…own GAM/PFS pageround-robin: each new temp object grabs the next file in rotationCommon mistake: adding extra tempdb fileswithout matching their SIZE. Proportional-fillfavors whichever file has the MOST free space —unequal sizes defeat round-robin completely. 📌

What’s Actually Being Contended

Every tempdb data file has special allocation-tracking pages: GAM (Global Allocation Map), SGAM (Shared GAM), and PFS (Page Free Space). Every session creating a temp table or table variable must touch these pages to claim space — under high concurrency, many sessions latch-wait on the same few physical pages.

Diagnosing It

-- High PAGELATCH waits specifically on tempdb pages is the signature
SELECT wait_type, wait_time_ms, waiting_tasks_count
FROM sys.dm_os_wait_stats
WHERE wait_type LIKE 'PAGELATCH%'
ORDER BY wait_time_ms DESC;

-- Confirm it's tempdb specifically
SELECT session_id, wait_type, resource_description
FROM sys.dm_os_waiting_tasks
WHERE resource_description LIKE '2:%'; -- database_id 2 = tempdb

The Standard Fix: Multiple Equally-Sized Data Files

One tempdb data file All sessions fight over the SAME GAM/SGAM/PFS pages Multiple equal-size files Round-robin allocation spreads contention across separate page sets

-- Common starting guidance: one tempdb data file per CPU core, up to ~8, all EQUAL size
ALTER DATABASE tempdb ADD FILE (NAME = tempdev2, FILENAME = 'D:tempdbtempdev2.ndf', SIZE = 1024MB, FILEGROWTH = 256MB);
-- Repeat with matching sizes for tempdev3, tempdev4...

Equal size matters: SQL Server’s proportional-fill allocation favors the file with the most free space, so unequal files defeat the round-robin benefit entirely — a genuinely common mistake when adding files without matching existing sizes.


Enjoyed this?

Subscribe to get every new lesson as soon as it’s published, and share it with a developer who’d find it useful.

📡 Subscribe via RSS  | 
Share on X  | 
Share on LinkedIn  | 
Share on Facebook

Want the full structured course with quizzes and hands-on labs? Check out SQL Server Performance Tuning, coming soon on this site.