As a Drupal site grows, it often accumulates a significant amount of digital debris. Every time a user uploads an image that is later replaced, or a module creates a temporary asset that isn't properly cleaned up, your server's storage fills with orphaned files. These are files that exist on your disk but are no longer linked to any node, entity, or CSS stylesheet.

Cleaning up these unused files is essential for maintaining a lean site, reducing backup sizes, and improving overall performance. In this guide, you will learn multiple methods to identify and safely remove these files, ranging from direct database queries to automated community modules.

Understanding the Drupal File System Architecture

Before you start deleting files, it is crucial to understand how Drupal tracks them. Drupal categorizes files into two main types: Managed and Unmanaged.

Managed files are those tracked in the file_managed database table. When a file is uploaded through a standard File or Image field, Drupal creates a record for it, assigning it a File ID (FID). The system also tracks where that file is used in the file_usage table. If a file exists in the file_managed table but has zero entries in the file_usage table, it is considered orphaned.

Unmanaged files, on the other hand, are files that exist on your server (like those in your theme folder or manually uploaded via FTP) but have no record in the Drupal database. Finding these requires a different approach, as the database has no knowledge of their existence.

Method 1: Using SQL Queries to Find Orphaned Managed Files

If you have access to your site's database via phpMyAdmin, Sequel Ace, or the command line, you can quickly identify managed files that are no longer associated with any content.

The following query looks for files in the file_managed table that are specifically supposed to be linked to nodes but no longer have a corresponding entry in the node table:

SELECT fm.*
FROM file_managed AS fm
LEFT OUTER JOIN file_usage AS fu ON (fm.fid = fu.fid)
LEFT OUTER JOIN node AS n ON (fu.id = n.nid)
WHERE fu.type = 'node' AND n.nid IS NULL;

How This Query Works

  1. SELECT fm.*: This selects all columns from the file_managed table so you can see the file name and path.
  2. LEFT OUTER JOIN: We join the usage table and the node table.
  3. WHERE n.nid IS NULL: This is the key logic. It filters the results to only show files where the usage record points to a node ID that no longer exists in the system.

Note: While this query is excellent for identification, be cautious. Some modules might store file usage data differently. Always back up your database and your files directory before manually deleting rows or physical files based on SQL results.

Method 2: Automating Cleanup with the Fancy File Delete Module

For a more user-friendly and automated approach, the Fancy File Delete module is an industry standard. It provides a robust interface for identifying and purging files that have lost their references.

This module is particularly powerful because it handles several different "orphan" scenarios:

  • Managed File View: It provides a list of all managed files with an option to force delete them via Views Bulk Operations (VBO).
  • Unmanaged Files: It can scan your public:// directory and compare the files on disk against the file_managed table. If a file exists on the server but not in the database, Fancy File Delete can identify and remove it.
  • Orphaned Files: It specifically targets files that are no longer attached to nodes or mentioned in the file_usage table.

To use it, simply install the module and navigate to the configuration page. You can choose to delete files manually by FID or run a bulk process to wipe out all unmanaged assets. Because it integrates with Drupal's internal API, it is generally safer than running raw SQL queries.

Method 3: Auditing with the File Checker Module

Sometimes the problem isn't just extra files; it's a synchronization issue. The File Checker module is designed to monitor the health of your file system and its relationship with the database.

In a standard Drupal setup, files have two statuses: Temporary (0) and Permanent (1). File Checker introduces a third status: Missing (2). This is incredibly useful for a multi-step cleanup strategy:

  1. Identify Missing Files: Run a verification process via Cron or Drush. This tells you which database records point to files that don't actually exist on the server.
  2. Reverse Identification: If you move all files out of a directory and then run File Checker, the module will flag every file that should be there. Any file left over in your temporary storage that the module doesn't complain about is likely unused.

This module is perfect for site administrators who want to ensure their filesystem and database are 100% synchronized before performing a major migration or high-stakes cleanup.

None of the database methods above will find unused images inside your theme folder (e.g., sites/all/themes/custom_theme/images). Since these are not "managed files," Drupal does not track their usage.

To find these, you should use a code-searching tool like grep, ack, or ag (The Silver Searcher). For example, to see if a specific image is used in your CSS or templates, run:

grep -r "image-name.jpg" sites/all/themes/custom_theme

If the search returns no results, the image is likely a legacy asset that can be safely removed.

Frequently Asked Questions

Is it safe to delete files directly from the /sites/default/files folder?

No, you should never delete files directly from the server without checking the database first. If Drupal expects a file to be there (a record exists in file_managed) and you delete it manually, you will trigger "File not found" errors and broken image icons across your site. Use a module like Fancy File Delete to handle the removal of both the file and the database record simultaneously.

Why does Drupal keep "Temporary" files?

Drupal marks files as temporary when they are uploaded but not yet attached to a piece of content. By default, Drupal will automatically delete these files during cron runs if they are older than a specific threshold (usually 6 hours). You can configure this in the File System settings.

Can I use these methods on Drupal 9 or 10?

Yes. While the original techniques were popularized in Drupal 7, the file_managed and file_usage architecture remains fundamentally the same in modern Drupal versions. The Fancy File Delete and File Checker modules both have versions available for Drupal 9 and 10.

Wrapping Up

Managing orphaned files in Drupal requires a mix of database knowledge and the right contributed modules. For quick identification of managed files, an SQL query is your best friend. For a comprehensive cleanup of the entire filesystem—including unmanaged files—the Fancy File Delete module is the most efficient tool for the job.

Before you perform any bulk deletions, remember to: 1. Create a full backup of your database and your files directory. 2. Test the process in a development or staging environment. 3. Verify your settings in the File System configuration to ensure temporary files are being cleared correctly by cron.

By keeping your file system clean, you ensure faster backups, lower hosting costs, and a more maintainable Drupal site.