How to Configure DNF for Faster Downloads (max_parallel_downloads, fastestmirror)

Configure DNF for faster downloads by enabling parallel downloads and the fastest mirror option in the configuration file.

You upgraded from Fedora 40 to 42 and the boot stops at the GRUB menu

You run sudo dnf upgrade after a long weekend. The dependency resolver finishes instantly. Then the download starts. One package. Two hundred kilobytes per second. You have a gigabit connection. The progress bar crawls. You wait twenty minutes for a kernel update that should take two.

This happens because DNF is conservative by design. It downloads packages sequentially to respect upstream mirror bandwidth and to keep transaction state predictable. The default max_parallel_downloads value is usually one or three. That works for a dial-up era or a busy university mirror. It does not work for modern broadband. The fastestmirror plugin attempts to fix the speed problem by pinging mirrors and picking the quickest one. It runs in the background, updates its cache, and hands DNF a ranked list. When both features are misconfigured or disabled, you get the slow crawl. Think of it like a grocery store with a single checkout lane. Adding more lanes speeds things up, but only if the store manager actually opens them.

What's actually happening

DNF relies on librepo and curl under the hood to fetch packages. By default, it opens a single TCP connection per repository and streams one file at a time. This prevents overwhelming the mirror, but it also leaves your bandwidth sitting idle. When you enable max_parallel_downloads, DNF spawns additional worker threads. Each thread opens its own connection and fetches a different package simultaneously. The package manager aggregates the streams and writes them to the cache directory.

The fastestmirror plugin operates independently. It maintains a local database of mirror response times. Every time you run a DNF command, the plugin sends lightweight HTTP requests to the mirrors in your mirrorlist. It measures latency, not throughput. A mirror in your city might respond in 5 milliseconds but be throttled to 1 megabit per second. A mirror three states away might respond in 45 milliseconds but deliver 100 megabits per second. The plugin picks the lowest latency by default. That is why you sometimes see fastestmirror select a slow server. The plugin optimizes for connection setup time, not sustained transfer rate.

Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/dnf/dnf.conf. Never edit /usr/lib/dnf/dnf.conf. Package updates will overwrite /usr/lib/ and erase your changes.

The fix

Here is how to configure the main DNF settings for parallel downloads and mirror selection.

[main]
# Allow DNF to fetch multiple packages at once. Start with 10.
max_parallel_downloads=10
# Enable the plugin that pings mirrors and ranks them by latency.
fastestmirror=true

Save the file and run sudo dnf clean all. This clears the metadata cache and forces DNF to re-evaluate the mirror list with your new settings. The fastestmirror plugin is usually enabled by default in modern Fedora, but explicitly declaring it prevents conflicts with third-party repositories that ship their own plugin overrides.

If you prefer user-level configuration, place the same block in ~/.config/dnf/dnf.conf. User config overrides system config for non-root operations. Root operations still read /etc/dnf/dnf.conf. Keep both in sync if you switch between sudo dnf and su -.

dnf upgrade --refresh is the normal weekly maintenance command. dnf system-upgrade is for crossing major Fedora releases. They are different commands. Don't conflate them.

Verify it worked

Here is how to confirm that DNF is actually using multiple connections and the correct mirror.

# Force a metadata refresh and start a dry-run upgrade to observe behavior
sudo dnf upgrade --refresh --downloadonly

Watch the terminal output. When parallel downloads are active, you will see multiple progress indicators updating simultaneously, or a single combined transfer rate that scales with your connection. The speed should jump significantly compared to the sequential default. If you only see one package downloading at a time, the configuration did not apply. Check for typos in /etc/dnf/dnf.conf. DNF is strict about indentation and spacing. A trailing space after max_parallel_downloads=10 will cause the parser to ignore the line.

You can also verify the active mirror by checking the repository list.

# Display the currently active mirror URLs for all enabled repos
dnf repolist --verbose | grep -i "mirror"

The output will show the exact URL DNF selected. If it points to a server you know is slow, run sudo dnf clean all again and wait for the plugin to re-rank the list. The cache lives in /var/cache/dnf/. Deleting it manually works, but dnf clean all is safer and updates the plugin state correctly.

Run the dry-run first. Watch the transfer rate before committing to a full upgrade.

Common pitfalls and what the error looks like

Setting max_parallel_downloads too high will trigger connection resets. Mirrors rate-limit aggressive clients. You will see curl error 28: Timeout was reached or Connection reset by peer in the terminal. The package manager will retry, but the retries consume more bandwidth than the actual download. Start with 10. Increase to 20 only if your connection is stable and you are downloading large updates.

The fastestmirror cache can get stale. If a mirror goes down mid-download, DNF falls back gracefully, but a stale cache forces it to retry the dead one first. Clear the cache with sudo dnf clean all. If you see [WARNING] fastestmirror plugin is not enabled during a transaction, your configuration file has a syntax error or the plugin package was removed. Reinstall it with sudo dnf install dnf-plugin-fastestmirror.

SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. DNF does not trigger SELinux denials for mirror selection, but custom proxy configurations or non-standard cache directories sometimes do. Stick to the default /var/cache/dnf/ path unless you have a specific reason to change it.

If you see Error: Cannot prepare internal mirrorlist: Curl error (6): Couldn't resolve host name the mirrorlist URL is malformed or your DNS is failing. Check /etc/resolv.conf and verify network connectivity before adjusting DNF settings. Network problems masquerade as DNF problems half the time.

Check the actual error message. Guessing the cause wastes more time than reading the output.

When to use this vs alternatives

Use max_parallel_downloads=10 when you have a stable broadband connection and want to saturate your bandwidth during large updates. Use fastestmirror=true when you are behind a restrictive firewall or a slow ISP that routes poorly to the default mirror list. Use dnf5 when you are on Fedora 39 or newer and want the rewritten C++ backend that handles parallel downloads natively without plugins. Use a custom mirrorlist or baseurl when you are running a local repository or a corporate proxy that requires explicit routing. Stay on the default settings when you are on a metered connection or a shared network where aggressive downloading impacts other users.

Where to go next