Part of the SQL Server Wait Types Library.
Related deep dive: IO_COMPLETION Wait Type.
PREEMPTIVE_OS_WRITEFILEGATHER is recorded when a thread calls the Windows WriteFileGather function and waits for it to return. In DBA practice this wait has one dominant source: zero-filling file space. When a data or log file grows (or is created or restored) and the new space must be zeroed, the thread doing the growth sits in this wait while Windows writes the zeros.
Like all PREEMPTIVE_ waits, the thread has left cooperative scheduling and shows as RUNNING while Windows does the work.
Is It a Problem?
Yes, when it shows up with real duration, because zero-filling happens synchronously inside operations users are waiting on. An autogrow during business hours freezes allocations in that file until the zeroing finishes; a 10GB growth on mid-range storage can take a minute or more. Restores and database creation pay the same cost up front.
Log files always zero-fill. Data files only zero-fill when instant file initialization is not enabled, which makes this wait a quick audit of that setting.
Common Causes
- Data file autogrowth without instant file initialization, zero-filling every increment.
- Log file growth, which zero-fills regardless of settings, made worse by percent-based growth on large logs.
- Database creation or restore writing out full-size files on an instance without IFI.
- Undersized tempdb growing under load after every restart.
What To Do
- Check whether instant file initialization is on:
SELECT instant_file_initialization_enabled FROM sys.dm_server_services WHERE servicename LIKE 'SQL Server (%';. Grant the service accountPerform volume maintenance tasksif not (an install-time checkbox since SQL Server 2016). - Pre-size data and log files so growth is rare, and use fixed growth increments sized for the file rather than percentages.
- Keep log growth increments moderate (say 512MB to 1GB); giant increments mean giant synchronous zeroing pauses.
- Correlate the wait’s spikes with autogrowth events from the default trace (our
Get-AutogrowthHistoryscript) to confirm the source before changing anything.
How To See It
Rank it against everything else with Get-WaitStatistics. Spikes of this wait lining up with autogrowth events are the confirmation; steady low-level noise from other WriteFileGather callers can be ignored.
Leave a Reply