Remove Unused Packages on Fedora

Reclaim disk space and keep your Fedora system lean by removing orphaned dependencies with `dnf autoremove` and explicitly uninstalling packages you no longer need.

You upgraded, you removed a tool, and the disk space never came back

You installed a development environment six months ago. You finished the project, ran sudo dnf remove <compiler>, and moved on to the next task. Today you run df -h and see the root partition sitting at 89 percent. You know you deleted the main program, but the supporting libraries, runtime headers, and build utilities are still sitting in /usr/lib and /usr/bin. The package manager did not clean them up. They are orphaned dependencies, and they are quietly consuming space, receiving security updates, and expanding the system attack surface.

How DNF tracks what you actually want

Fedora does not guess what you want to keep. It tracks every package installation through a transaction history database. When you explicitly ask for a package, DNF marks it with the @commandline tag. When DNF pulls in a library because another package requires it, it marks that library as an automatic dependency. The automatic packages stay installed even after the parent package is removed. This design prevents accidental breakage. If you remove a web server, DNF does not delete the TLS libraries that your email client also uses.

The tradeoff is accumulation. Over months of installing and removing software, the automatic packages pile up. They become orphans. The system does not delete them automatically because the package manager cannot distinguish between a library you genuinely need for a different project and a leftover from a finished task. You have to tell DNF to audit its own records and drop what is no longer anchored to an explicit install.

Run the audit before you guess. Blindly deleting files in /usr breaks the RPM database and forces a full system reinstall.

Audit the orphaned packages

You need a clear list before you start removing anything. The repoquery plugin reads the RPM database and cross-references it with the transaction history. It identifies packages that were installed automatically, are not currently required by any explicitly installed package, and are safe to drop.

Here is how to generate the list of orphaned packages on your system.

dnf repoquery --unneeded

The command prints one package name per line. The output can be long on systems that have hosted multiple development environments. Pipe it to less if you need to scroll through it. The list only contains packages that DNF considers safe to remove. It excludes packages marked as explicitly installed by you.

If you want to see the total disk space these orphans occupy, append the --qf flag to format the output with size information.

dnf repoquery --unneeded --qf "%{name} %{size}"

The size column shows the installed size in bytes. You can convert it to megabytes by dividing by 1048576, or just use ncdu on /usr for a visual breakdown. Knowing the exact footprint helps you decide whether to run the cleanup now or wait until the next maintenance window.

Review the list carefully. If you see a package you actually use, you will need to reinstall it explicitly after the cleanup.

Drop the orphans safely

Once you have verified the list, you can instruct DNF to remove the orphaned dependencies. The autoremove command reads the same transaction history that repoquery uses. It builds a transaction that deletes every package marked as automatic and currently unneeded.

Here is how to trigger the automatic cleanup.

sudo dnf autoremove
# WHY: reads the transaction history and flags automatic packages
# WHY: that are no longer required by any explicitly installed package
# WHY: prompts for confirmation before modifying the RPM database

DNF will print a transaction summary showing exactly which packages will be removed and how much disk space will be freed. Read the summary. Confirm with y when you are ready. The package manager handles dependency resolution automatically. It will not delete a package if another installed package still requires it.

If you want to skip the confirmation prompt for scripting or routine maintenance, add the -y flag. Only do this if you have already reviewed the output of repoquery --unneeded.

sudo dnf autoremove -y
# WHY: bypasses the interactive confirmation prompt
# WHY: executes the removal transaction immediately
# WHY: useful for scheduled maintenance or automated cleanup scripts

Run autoremove after every major software removal. Do not wait until the disk is full.

Remove explicit packages and their trailing dependencies

autoremove only touches automatic dependencies. It will not delete packages you explicitly installed. If you installed a language runtime, a database client, or a desktop application and no longer need it, you must remove it directly. DNF will automatically cascade the removal to any dependencies that become orphaned as a result.

Here is how to remove a specific package and let DNF handle the cascade.

sudo dnf remove golang
# WHY: marks the explicit package for removal
# WHY: calculates which dependencies become unneeded
# WHY: includes those dependencies in the same transaction

The transaction summary will show both the explicit package and the newly orphaned dependencies. This is normal behavior. DNF groups them into a single atomic transaction. If the transaction fails midway, the RPM database rolls back to the previous state. You do not need to manually track which libraries belonged to the removed package.

If you are unsure whether a package is safe to remove, check what currently requires it. An empty result means nothing on your system depends on it.

dnf repoquery --whatrequires <package-name>
# WHY: queries the RPM database for reverse dependencies
# WHY: lists every installed package that declares a dependency
# WHY: returns nothing if the package is already an orphan

Check the reverse dependencies before you delete. Accidentally removing a core library breaks unrelated applications.

Clear the download cache and stale metadata

Removing packages frees space in /usr, but DNF also stores downloaded RPM files and repository metadata in /var/cache/dnf. This cache speeds up future installs and allows you to reinstall packages without re-downloading them. It also grows steadily. On a system that receives weekly updates, the cache can easily consume several gigabytes.

Here is how to wipe the entire DNF cache.

sudo dnf clean all
# WHY: deletes all cached RPM packages in /var/cache/dnf
# WHY: removes repository metadata files and GPG keys
# WHY: forces DNF to fetch fresh metadata on the next run

Use this command when you want to reclaim maximum space or when you suspect corrupted metadata is causing resolution errors. The next dnf command you run will automatically re-download the repository metadata. This takes a few seconds on a fast connection.

If you want to keep the metadata but only delete the downloaded RPM files, use the packages target instead.

sudo dnf clean packages
# WHY: removes only the cached RPM binaries
# WHY: preserves repository metadata and GPG keys
# WHY: keeps dependency resolution fast without storing large files

Fedora's release cadence is six months. The N-2 release goes end-of-life when N+1 ships. Running dnf clean all after a major release transition prevents stale metadata from pointing to dead mirrors.

Clear the cache after major upgrades. Stale metadata causes phantom dependency errors.

Handle packages from dead repositories

Sometimes you install software from a third-party repository, a COPR project, or a temporary testing channel. Later you disable or remove that repository from /etc/yum.repos.d. The packages you installed from it remain on the system, but DNF can no longer find updates for them. They show up as extras.

Here is how to list packages that are installed but no longer available in any enabled repository.

sudo dnf list extras

The output shows package names and their versions. These packages are not broken. They simply lack a configured source for future updates. Review the list. Remove anything you do not recognize or no longer need.

sudo dnf remove <extra-package-name>
# WHY: removes the package and its orphaned dependencies
# WHY: cleans up software that no longer receives security patches
# WHY: reduces the attack surface by eliminating unmaintained binaries

If you want to keep the package but restore updates, re-enable the original repository or find a maintained replacement. Leaving extras installed is safe, but it means you are responsible for manually verifying their security status.

Audit extras quarterly. Unpatched third-party software is the most common vector for desktop compromises.

Verify the cleanup

You need to confirm that the disk space actually returned and that the system remains stable. Check the root partition usage first.

df -h /

Compare the available space to your pre-cleanup measurement. The difference should match the transaction summary from autoremove plus the cache size you cleared. If the numbers do not align, check /var/log or /tmp for large leftover files. Package removal does not clean user data or application logs.

Run a quick dependency check to ensure the RPM database is consistent.

sudo rpm -Va --nofiles --nodigest

The command verifies package metadata against the RPM database. A clean run produces no output. If you see lines printed, they indicate modified configuration files or mismatched checksums. This is normal after manual edits in /etc. It does not mean the cleanup failed.

Reboot before you debug. Half the time the symptom is gone.

Common pitfalls and recovery

The most common mistake is running autoremove without reviewing the transaction summary. DNF will happily delete development tools, language runtimes, and desktop components if they were installed as dependencies and are no longer required by an explicitly marked package. If you see a package you actually need in the removal list, abort the transaction with n. Reinstall the package explicitly afterward to anchor it back to the @commandline tag.

sudo dnf reinstall <package-name>
# WHY: re-adds the package to the transaction history
# WHY: marks it as explicitly installed again
# WHY: prevents future autoremove runs from deleting it

If you accidentally confirm a removal that breaks your workflow, DNF keeps a full transaction history. You can reverse the last operation without re-downloading anything.

sudo dnf history undo last
# WHY: reads the most recent transaction ID
# WHY: calculates the inverse operation to restore packages
# WHY: reinstalls files and updates the RPM database atomically

The undo command works for both remove and autoremove transactions. It is your safety net. Do not panic if you delete something important. Check the history and reverse it.

Trust the package manager. Manual file edits drift, snapshots stay.

Choose the right cleanup command

Use dnf repoquery --unneeded when you want to preview orphaned packages before committing to removal. Use sudo dnf autoremove when you are ready to delete automatic dependencies that are no longer required. Use sudo dnf remove <package> when you want to delete an explicitly installed program and cascade the cleanup to its trailing dependencies. Use sudo dnf clean all when you need to reclaim cache space or resolve corrupted metadata. Use sudo dnf list extras when you are auditing software installed from disabled or removed repositories. Use sudo dnf history undo last when a removal transaction breaks your workflow and you need to restore the previous state.

Run the audit first. Confirm the summary. Execute the cleanup.

Where to go next