Why deleted files still use disk space on Linux
When df says a filesystem is full but du cannot find the bytes, an open deleted file is a prime suspect. Confirm the descriptor, identify its owner, and release it through the application.
Reviewed by the Terminaster editorial team · Updated
What you will take away
- Deleting a pathname removes a directory entry; an open file can remain allocated until its last reference is closed.
- A large gap between df and du can point to open deleted files, but reserved blocks, mount boundaries, and snapshots can cause similar symptoms.
- Use lsof +L1 or Linux /proc/PID/fd to identify the holding process and descriptor.
- Prefer a graceful application restart or supported log-reopen mechanism over truncating a live descriptor.
Deletion removes a name, not every reference
On a Unix-like filesystem, unlink removes a directory entry that associates a pathname with an inode. If a process still has the file open, the kernel keeps the underlying file object and its data blocks available to that descriptor. The pathname can disappear immediately while the storage remains allocated.
The filesystem can reclaim the inode and blocks after the link count reaches zero and the final open reference is closed. This behavior lets a process continue reading or writing a file that was renamed or deleted beneath it, but it can surprise operators when a large active log is unlinked.
Reproduce the behavior safely in a temporary directory
demo=$(mktemp -d)
exec 9>"$demo/held.log"
printf 'still open\n' >&9
rm "$demo/held.log"
ls -la "$demo"
readlink "/proc/$$/fd/9"
exec 9>&-
rmdir "$demo"Understand why df and du can disagree
df asks the filesystem for allocated and available block counts. du walks reachable pathnames and adds the blocks associated with files it can see. A deleted file has no reachable pathname for du to visit, while df continues counting its allocated blocks.
Open deleted files are not the only explanation. Files hidden beneath a mount point, filesystem snapshots, reserved blocks, permissions, sparse-file accounting, and checking different filesystem boundaries can also produce differences. First confirm that df and du refer to the same mounted filesystem.
Compare one filesystem without crossing mounts
target=/var
findmnt --target "$target"
df -h "$target"
sudo du -xhd1 "$target" 2>/dev/null | sort -hFind the process holding a deleted file open
On Linux, lsof +L1 selects open files whose link count is below one, which usually means deleted regular files. Look at the process name, PID, descriptor, file size, and mount before deciding what to do. Some output may require elevated permission.
You can confirm one result through /proc/PID/fd. A descriptor symlink ending in “(deleted)” identifies the open unlinked object, fdinfo supplies position and flags, and stat can distinguish logical length from allocated blocks. Do not rely on lsof’s SIZE/OFF column alone: sparse files and filesystem accounting can make logical size very different from allocated space.
- Record the command and PID so you can find the owning service or container.
- Check whether the descriptor is still growing and whether it belongs to a log, database, temporary file, or executable.
- Confirm the file is on the full filesystem; a deleted file elsewhere is unrelated.
- If evidence may be needed, arrange collection before restarting the process.
Locate and confirm deleted descriptors
sudo lsof +L1
pid=1234
fd=17
sudo ls -l "/proc/$pid/fd" | grep -F '(deleted)'
sudo stat -Lc 'logical=%s bytes; allocated=%b blocks of %B bytes' \
"/proc/$pid/fd/$fd"
sudo cat "/proc/$pid/fdinfo/$fd"Release the descriptor through its owner
The safest remedy is application-specific: ask the process to reopen logs, rotate them using its supported mechanism, stop the responsible job, or restart the service gracefully. Once the last descriptor closes, the filesystem can reclaim the blocks automatically.
Writing to or truncating /proc/PID/fd/N can alter the live file object and interfere with the process’s file offset, buffering, or data guarantees. It is an emergency technique with application-specific risk, not a routine cleanup command. Likewise, killing a database merely to free space can create a larger incident.
- 1Identify the filesystem, process, descriptor, and approximate retained size.
- 2Check the application’s documented log-reopen, rotation, shutdown, or restart procedure.
- 3Preserve evidence or recover needed contents before closing the final reference.
- 4Release the descriptor through the supported procedure.
- 5Verify that df reports reclaimed space and that the service resumes normally.
Prevent log rotation from unlinking a live writer
A common cause is external rotation that renames or deletes a log while the application keeps writing through its original descriptor. Configure rotation to signal the application to reopen its log, or use the application’s native rotation support.
Copy-and-truncate rotation keeps the pathname but has race and data-loss tradeoffs, so it is not a universally safer substitute. Test the selected method under real write volume, monitor filesystem free space, and alert on open deleted files that continue growing.
Verify after a controlled reopen or restart
sudo lsof +L1
df -h /var
# Then confirm the service is healthy with its normal status and checks.Common questions
Frequently asked questions
Why does rm not immediately free space for an open file?
rm normally unlinks a pathname. If a process still holds the file open, the kernel preserves the inode and data blocks until the final open reference closes.
Can I recover a deleted file through /proc?
On Linux, a readable /proc/PID/fd/N entry may provide access while the descriptor remains open. Recovery is permission- and application-dependent, and the file may still be changing, so copy it to another filesystem only with adequate capacity and an incident-safe plan.
Does every df and du mismatch mean an open deleted file?
No. Mount boundaries, snapshots, reserved blocks, hidden mounted-over files, permissions, and accounting details can also differ. Use lsof or /proc to confirm an open deleted file on the affected filesystem.
Keep learning
Sources and next steps
Related mental models
File descriptor
A file descriptor is a non-negative integer that indexes an entry in one process's descriptor table. That entry refers to a kernel-managed open resource such as a file, pipe, socket, terminal, or device.
Inode and file metadata
In an inode-based Unix filesystem, an inode represents a filesystem object and stores metadata such as its type, permissions, ownership, timestamps, link count, size, and data-location information. Filenames live in directory entries that map names to inode numbers.
Hard link
A hard link is a directory entry that maps an additional pathname to an existing inode. All hard-linked names are peers for the same filesystem object; removing one name does not remove the object while another link or open reference remains. Ordinary hard links target non-directory objects because directory hard links are normally prohibited or tightly restricted to preserve filesystem structure.