YUM and DNF (RHEL/Fedora)

YUM and DNF are the package managers used on Red Hat-based Linux distributions — RHEL, CentOS Stream, Rocky Linux, AlmaLinux, and Fedora — the RPM-based counterparts to Debian's apt. They install, update, and remove software while automatically resolving dependencies, so you never have to hunt down libraries by hand. DNF ("Dandified YUM") is the modern successor to YUM: it has been Fedora's default since Fedora 22 (2015) and RHEL's default since RHEL 8. The two share almost identical command syntax, so learning one means you already know the other.

Overview / How YUM and DNF Work

Software on these distributions ships as RPM (Red Hat Package Manager) files — archives that bundle a program's files together with metadata: its name, version, and a list of other packages it depends on. The low-level tool that actually unpacks an RPM and records it in the system's package database (/var/lib/rpm) is rpm itself, but rpm does not know how to fetch packages over a network or resolve dependency chains. That is the job of YUM and DNF: they sit on top of rpm, talk to remote repositories (servers hosting collections of RPMs plus an index of what depends on what), and work out a consistent set of packages to install, upgrade, or remove.

YUM (Yellowdog Updater, Modified) was the original tool, written in Python, but its dependency resolver became slow and memory-hungry as repositories grew. DNF was built as its replacement: it uses libsolv, a fast SAT-based (satisfiability) solver — the same library used by openSUSE's zypper — to compute dependency solutions, and it exposes a stable API that other tools and plugins can build on. On RHEL 8+ and its clones, yum is literally a symlink to dnf, so old muscle memory keeps working even though DNF is doing the work underneath. On RHEL/CentOS 7 and older, only the original YUM exists.

Repositories

Each repository is defined by a .repo file under /etc/yum.repos.d/, an INI-style config listing a name, a URL (or mirror list) to fetch packages from, and whether GPG signature checking is required:

cat /etc/yum.repos.d/almalinux-baseos.repo

Output:

[baseos]
name=AlmaLinux $releasever - BaseOS
mirrorlist=https://mirrors.almalinux.org/mirrorlist/$releasever/baseos
baseurl=https://repo.almalinux.org/almalinux/$releasever/BaseOS/$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux
gpgcheck=1
enabled=1

DNF downloads and caches each enabled repository's metadata (package lists, dependency data, checksums) under /var/cache/dnf so it does not have to re-download it on every command. You can list what is currently enabled:

dnf repolist

Output:

repo id                                  repo name
appstream                                AlmaLinux 9 - AppStream
baseos                                   AlmaLinux 9 - BaseOS
epel                                     Extra Packages for Enterprise Linux 9 - x86_64

Note that epel (Extra Packages for Enterprise Linux) is a community repository with thousands of extra packages that is not enabled by default on RHEL and its clones — you have to install the epel-release package yourself, which is a common source of "package not found" confusion for newcomers.

Syntax

Both tools follow the same general form:

dnf <command> [options] <package-name>
Command Purpose
install Install one or more packages and their dependencies
remove (alias erase) Uninstall a package; also removes packages left with nothing depending on them if you follow up with autoremove
update / upgrade Upgrade installed packages to the latest available version (true synonyms in DNF; run with no package name to upgrade everything)
search Search package names and summaries for a keyword
info Show detailed metadata about a package
list installed / list available List packages already installed, or installable from enabled repos
provides Find which package provides a given file or command
history Show past transactions, and undo/redo them
clean all Delete cached package files and metadata
makecache Force-refresh repository metadata immediately
autoremove Remove packages that were pulled in as dependencies but are no longer needed
-y Assume "yes" to all prompts (needed for non-interactive scripts)

Examples

Example 1: Installing a package

sudo dnf install httpd

Output:

Last metadata expiration check: 0:12:34 ago on Tue Aug  4 09:15:02 2026.
Dependencies resolved.
================================================================================
 Package           Architecture   Version                Repository      Size
================================================================================
Installing:
 httpd              x86_64         2.4.57-2.el9           appstream      1.5 M
Installing dependencies:
 apr                x86_64         1.7.0-11.el9           appstream      125 k
 apr-util           x86_64         1.6.1-20.el9           appstream       97 k

Transaction Summary
================================================================================
Install  3 Packages

Total download size: 1.7 M
Installed size: 4.6 M
Is this ok [y/N]: y
Running transaction
  Preparing        :                                                    1/1
  Installing       : apr-1.7.0-11.el9.x86_64                            1/3
  Installing       : apr-util-1.6.1-20.el9.x86_64                       2/3
  Installing       : httpd-2.4.57-2.el9.x86_64                          3/3
  Verifying        : httpd-2.4.57-2.el9.x86_64                          1/3

Installed:
  httpd-2.4.57-2.el9.x86_64  apr-1.7.0-11.el9.x86_64  apr-util-1.6.1-20.el9.x86_64

Complete!

DNF resolved httpd's two dependencies automatically, showed a transaction summary with download and install sizes, waited for confirmation, then downloaded and installed all three RPMs. To actually start the web server and have it launch on boot, you would follow up with sudo systemctl enable --now httpd.

Example 2: Searching, inspecting, and removing a package

dnf search "text editor"

Output:

============================ Name & Summary Matched: text, editor ============================
nano.x86_64 : A small text editor
vim-enhanced.x86_64 : A version of the VIM editor which includes recent enhancements
emacs.x86_64 : GNU Emacs text editor
dnf info nano

Output:

Installed Packages
Name         : nano
Version      : 6.2
Release      : 1.el9
Architecture : x86_64
Size         : 803 k
Source       : nano-6.2-1.el9.src.rpm
Repository   : @System
Summary      : A small text editor
URL          : https://nano-editor.org
License      : GPLv3+
Description  : GNU nano is a small and friendly text editor.
sudo dnf remove nano

Output:

Dependencies resolved.
================================================================================
 Package     Architecture    Version        Repository            Size
================================================================================
Removing:
 nano         x86_64          6.2-1.el9      @System               803 k

Transaction Summary
================================================================================
Remove  1 Package

Is this ok [y/N]: y
Running transaction
  Preparing        :                                                    1/1
  Removing         : nano-6.2-1.el9.x86_64                              1/1
  Verifying        : nano-6.2-1.el9.x86_64                              1/1

Removed:
  nano-6.2-1.el9.x86_64

Complete!

dnf search matches keywords in package names and summaries, dnf info shows full metadata for a specific package, and dnf remove uninstalls it — DNF only removes what you asked for here, since nothing else on the system depends on nano.

Example 3: Reviewing and undoing a transaction

sudo dnf history

Output:

ID     | Command line             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
     4 | remove nano              | 2026-08-04 09:32 | Removed        |    1
     3 | install nano             | 2026-08-04 09:20 | Install        |    1
     2 | update                   | 2026-08-04 08:55 | Update         |   14
     1 | install httpd            | 2026-08-04 08:40 | Install        |    3
sudo dnf history undo 4

Output:

Transaction ID : 4
Begin time     : 2026-08-04 09:32
Begin rpmdb    : ...
End time       : 2026-08-04 09:32
End rpmdb      : ...
User           : root
...
Install  1 Package

Is this ok [y/N]: y
Complete!

Every transaction DNF performs is logged with an ID. dnf history undo <ID> reverses exactly that transaction — here it reinstalls nano, the package removed in transaction 4 — which is far safer than trying to manually remember and redo commands after a mistake.

How DNF Resolves and Applies a Transaction, Step by Step

When you run sudo dnf install httpd, several things happen in order:

  1. Metadata freshness check: DNF checks whether the cached repository metadata under /var/cache/dnf is older than the configured expiry (commonly a few hours); if it is stale, it re-downloads the package lists and dependency data from each enabled repo.
  2. Candidate lookup: DNF searches all enabled repositories for packages named (or matching) httpd, along with the versions of everything already installed on the system.
  3. Dependency solving: The candidates and the currently-installed package set are handed to the libsolv SAT solver, which computes a consistent set of packages to add, upgrade, or remove that satisfies every dependency and conflict constraint — this is what pulls in apr and apr-util automatically.
  4. Transaction summary and confirmation: DNF prints the packages it plans to touch along with download and installed sizes, and waits for a y/N answer (skipped entirely if you passed -y).
  5. Download and verification: The chosen RPM files are downloaded into the cache and their GPG signatures are checked against imported keys, unless gpgcheck=0 is set in the repo file (not recommended).
  6. RPM install: Control passes to the underlying rpm library, which unpacks each package's files onto the filesystem, runs any pre/post-install scriptlets (e.g. creating a system user, reloading systemd), and records the package in the RPM database at /var/lib/rpm.
  7. History logging: The whole transaction is written to DNF's history database so it can be reviewed or undone later with dnf history.

Common Mistakes

Mistake 1: Leaving a wildcard unquoted

Wrong:

dnf install httpd*

Bash expands httpd* against files in your current directory before DNF ever sees it. If a file named httpd.conf happens to be sitting in your working directory, you might end up asking DNF to install a package literally called httpd.conf, which fails or does the wrong thing. Quote the argument so DNF's own glob matching against repository package names is used instead:

sudo dnf install "httpd*"

Mistake 2: Bypassing DNF with raw rpm commands

Wrong:

sudo rpm -e httpd

rpm -e removes a package directly from the low-level database without DNF's dependency resolution. If something else on the system depends on httpd, this can leave the system in a broken, inconsistent state (or simply refuse to run, depending on the dependency). Let DNF handle removal so it can work out the full, correct set of changes:

sudo dnf remove httpd

Mistake 3: Assuming every package is in the base repos

Wrong:

sudo dnf install btop

Output:

No match for argument: btop
Error: Unable to find a match: btop

Many popular packages (like the btop system monitor) live in the community-maintained EPEL repository, which is not enabled by default on RHEL and its clones. Enable it first, then install:

sudo dnf install epel-release
sudo dnf install btop

Best Practices

  • Always let dnf (not raw rpm) handle installs and removals so dependencies stay consistent.
  • Read the transaction summary before confirming, especially the list of packages being removed — a dependency conflict can sometimes pull in more removals than you expect.
  • Keep gpgcheck=1 in every repo file; disabling signature checking removes a real security guarantee.
  • Use dnf history to audit what changed on a system and dnf history undo <ID> to cleanly reverse a bad transaction instead of trying to manually reinstall or remove packages.
  • Run dnf clean all or dnf makecache if metadata seems stale (e.g. a package you know exists isn't showing up in search).
  • Enable epel-release explicitly rather than guessing why an install fails with "no match".
  • Run dnf autoremove periodically to clear out orphaned dependency packages left behind by earlier removals.
  • In scripts, use -y deliberately and sparingly — know exactly what a command will do before automating away the confirmation prompt.
  • For scheduled, unattended updates, use the dedicated dnf-automatic package rather than a cron job that blindly runs dnf update -y.

Practice Exercises

  • Install the nginx package with DNF, then use systemctl status nginx to check whether it is running. If it isn't, start and enable it.
  • Search for a package related to "json" processing, view its full details with dnf info, then remove it again once you've confirmed what it does.
  • Run dnf history to see your last few transactions, pick one, and practice undoing it with dnf history undo <ID>. Then check dnf history again to confirm the undo itself was logged as a new transaction.

Summary

  • YUM and DNF are the package managers for RPM-based distributions (RHEL, CentOS, Rocky, AlmaLinux, Fedora); DNF is the modern successor and yum is a symlink to it on RHEL 8+.
  • Repositories are defined in /etc/yum.repos.d/*.repo files; DNF caches their metadata locally and refreshes it periodically.
  • Core commands: install, remove, update/upgrade, search, info, list, history.
  • DNF uses the libsolv SAT solver to compute a consistent set of packages before showing a transaction summary and asking for confirmation.
  • Every transaction is logged and can be reversed with dnf history undo <ID>.
  • Common pitfalls: unquoted wildcards being expanded by the shell, bypassing DNF with raw rpm commands, and assuming a package is available without enabling EPEL.
  • Prefer DNF over rpm directly, keep GPG checking on, and use dnf-automatic instead of hand-rolled cron scripts for unattended updates.