Quick Scan Report – Low Disk Space

What this check looks for

Free space per drive, from xp_fixeddrives where the login can run it, and from sys.dm_os_volume_stats joined to sys.master_files where the DMV is available. A drive with less than 5 percent free is reported.

sys.dm_os_volume_stats is the better source, because it understands mount points and reports the volume each database file genuinely sits on rather than a drive letter.

This check shares a page with Low Disk Space, issue 91, which is the same measurement at a less severe threshold. This one is the point at which it stops being a planning matter.

Why it matters

A full disk is the one storage problem that stops everything at once, and it takes the tools you would use to fix it down with it.

When the drive fills:

  • Data files cannot grow. Error 1105, “could not allocate space for object, the filegroup is full”. Every insert into an affected database fails.
  • Log files cannot grow. Error 9002. Every transaction fails, including the rollback of the one that filled it.
  • If it is the system drive, Windows itself is in trouble. The page file cannot extend, event logs cannot write, and administrators cannot log in to fix it.
  • Recovery is harder than prevention. Under pressure the instinct is to shrink a database, which is slow, fragments every index, and gives back space the database is about to take again. The next instinct is to delete backups, which is exactly the wrong thing to do at the moment corruption becomes most likely.

Below 5 percent, the time you have left is not a percentage, it is a rate. A drive at 4 percent of 200 GB has 8 GB, which one index rebuild or one large log backup consumes. The number to act on is how fast it is falling, not how much is left.

How to confirm it yourself

The volumes SQL Server’s own files are on, which is the honest view:

SELECT DISTINCT
       vs.[volume_mount_point],
       vs.[logical_volume_name],
       CAST(vs.[total_bytes]     / 1073741824.0 AS DECIMAL(12,1)) AS [total_gb],
       CAST(vs.[available_bytes] / 1073741824.0 AS DECIMAL(12,1)) AS [free_gb],
       CAST(vs.[available_bytes] * 100.0 / NULLIF(vs.[total_bytes], 0) AS DECIMAL(5,1)) AS [free_pct]
  FROM sys.master_files AS mf WITH (NOLOCK)
 CROSS APPLY sys.dm_os_volume_stats(mf.[database_id], mf.[file_id]) AS vs
 ORDER BY [free_pct];

What is on each volume, and how much of it is free space inside the files rather than on the drive:

SELECT DB_NAME(mf.[database_id])                          AS [database_name],
       mf.[name]                                          AS [logical_name],
       mf.[type_desc],
       CAST(mf.[size] * 8.0 / 1024 / 1024 AS DECIMAL(10,2)) AS [size_gb],
       vs.[volume_mount_point],
       mf.[physical_name]
  FROM sys.master_files AS mf WITH (NOLOCK)
 CROSS APPLY sys.dm_os_volume_stats(mf.[database_id], mf.[file_id]) AS vs
 ORDER BY mf.[size] DESC;

Free space inside a data file is not a problem. A 500 GB file that is 60 percent used is a database with room to work in. What matters is space on the volume.

How to fix it

Buy time first, then fix the cause. In this order, because the first three are safe and reversible and the ones people reach for are neither.

  1. Move or delete what should not be there. Old backup files on a data drive, trace files, memory dumps, setup logs. This is usually where the quickest safe gigabytes are.
  2. Check the transaction logs. A log that grew because truncation was blocked is often the single largest recoverable item. Fix the reason, take a log backup, and the space inside the log becomes reusable without shrinking anything. See the log truncation check.
  3. Look for one oversized table, particularly an audit or history table with no retention policy. Archiving is a real fix where shrinking is not.
  4. Then add space. Extend the volume, add a file on another volume, or move a database. Adding a second data file on a different drive is online and is often the fastest genuine fix.

What not to do in a hurry:

  • Do not delete backups. A full disk raises the chance of corruption, which is exactly when you need them.
  • Do not shrink a database as a routine response. It is slow, it fragments every index, and the space comes back. If you do shrink after a genuine one-off cleanup, rebuild the indexes afterwards.

Then stop it recurring. Set the file sizes and growth deliberately, keep backups off the data drives, and use the Disk Space Forecast report to see when each volume runs out at its current rate, so the next one is a planned change rather than an incident.

How long it takes

About half an hour to reclaim immediate space and understand the rate. Adding storage or moving a database is a separate change.


Report Why you would go there
Disk Space Forecast When each volume runs out at the current rate.
Disk Space Free space per volume right now.
Files Every file, its size, and which volume it is on.
File Utilization How much of each file is genuinely used.
Databases By Size Which database is consuming the volume.
Large Tables The table inside it that is doing so.
File Size Over Time Whether this is steady growth or a recent event.
Check
Low Disk Space The same measurement before it becomes urgent.
A data or log file cannot grow any further A ceiling on the file rather than on the drive.
Log truncation is blocked The usual reason a log file is consuming the volume.
Not enough free space to restore databases Whether you could restore onto this server at all.
TempDB on the C: drive A common reason the system drive is the one filling.

Frequently asked questions

The drive is large, so 5 percent is still plenty. Possibly, and the number that matters is the rate rather than the percentage. Use the Disk Space Forecast report; a slow trickle on a large volume is a planning item, a nightly job consuming it is not.

The check reports a drive with no database files on it. xp_fixeddrives reports every fixed drive, so a full drive elsewhere on the server shows up too. Still worth knowing about, since the operating system shares it.

Can I shrink a database to get the space back? It works and it costs you index fragmentation and a repeat performance. Use it after a genuine one-off reduction in data, not as a response to a full disk.

Nothing is reported but I know a drive is nearly full. The check needs either permission on xp_fixeddrives or sys.dm_os_volume_stats, and it only sees volumes SQL Server has files on through the DMV path.