Server Setup

Fixing DNF annoyances in CentOS/RHEL: usability or bandwidth. Choose your destiny

by , , revisited on

We have by far the largest RPM repository with NGINX module packages and VMODs for Varnish. If you want to install NGINX, Varnish, and lots of useful performance/security software with smooth yum upgrades for production use, this is the repository for you.
Active subscription is required.

Have you ever noticed that dnf is very slow and refreshes repodata almost any time you use it? Then this post is for you.

DNF and repository metadata

What is the slowest thing that drags DNF performance down to the extent that you want to throw the workstation/server out of the window when you tried to install something?
It’s repository metadata. Whenever DNF needs to install a specific package, it first needs to have a complete list of packages, which is located in remote index files.

Those index files make up repository metadata, which, despite being compressed is the immensely large download for large repositories like EPEL.
Luckily, DNF caches those metadata files locally.
With a few repositories enabled on a system, you can easily expect a DNF metadata cache averaging 100 MB in size.

Any time DNF must refresh metadata (which is by default considered fresh for 6 hours), the evil metadata refresh kicks in and you are likely to download those megabytes all over again.
Again, and again.

There are two edge choices here to make. If you are a frequent DNF user, with unlimited bandwidth, you don’t want to be annoyed and wait while DNF refreshes metadata when you dnf install something

Contrary, if the bandwidth is metered, you will absolutely want to disable any metadata refreshes to preserve megabytes.

Speeding up DNF

Our first scenario is unlimited bandwidth. We want to speed up DNF in a way that it becomes not painful to use!

There is a shameful “configuration bug” that comes by default in at least CentOS/RHEL 8.
It wasn’t hard to notice. I’m an avid DNF user, and using dnf command once in a while I saw metadata refresh kick in just way too often.

There is, of course, dnf-makecache service/timer, and you should enable it: systemctl enable --now dnf-makecache.timer
But I’m here to tell you things beyond that 🙂

Even with dnf-makecache set up, and verifying the timers via systemctl list-timers showing to run fine every 1 hour, you will still just keep getting the annoying metadata refresh,
almost every time.

I started investigating by systemctl cat dnf-makecache.service which yields, among other things:

ExecStart=/usr/bin/dnf makecache --timer

The dnf-makecache.service is of type oneshot and it fires up every 1 hour, according to dnf-mackecache.timer.

So what is the magic –timer switch? man says:

dnf [options] makecache –timer
Like plain makecache, but instructs DNF to be more resource-aware, meaning it will not do anything if running on battery power and will terminate immediately if it’s too soon after the last successful makecache
run (see dnf.conf(5), metadata_timer_sync).

And, here’s a bummer:

time in seconds

The minimal period between two consecutive makecache timer runs. The command will stop immediately if it’s less than this time period since
its last run. Does not affect simple makecache run. Use 0 to completely disable automatic metadata synchronizing. The default corresponds to
three hours. The value is rounded to the next commenced hour.

So, putting all things together, metadata refresh is set to run every hour, but the default setting of metadata_timer_sync causes it to actually run only once in every 3 hours.

This considered, plus the mentioned default metadata expiration for most of the repositories, make dnf-makecache timer quite useless!

So I went ahead and edited /etc/dnf/dnf.conf:


And what do you know, ever since then, I never had metadata refresh annoyance when running dnf commands.

Preserving the bandwidth

The opposite edge scenario is when you don’t want any background service wasting precious metered bandwidth and CPU cycles.
You will accept the inconvenience of slower updates, but you will save resources that matter to you.

Easier done than said (c):

systemctl disable dnf-makecache.timer
# additionally, for Gnome users, disable PackageKit updates:
gsettings set download-updates false

Then you can set metadata_expire=-1 in every repository definition to prevent metadata refreshes.

When you are sure you need to update, run dnf clean cache first.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: