Understanding DNF History: Tracking Package Installations and Removals

understanding dnf history

Understanding dnf history for tracking, auditing, and undoing package installs and removals on Fedora/RHEL. CLI examples, tables, best practices included.

Table of Contents

🔈Introduction

In the world of Red Hat–based Linux distributions (Fedora, RHEL, CentOS Stream, AlmaLinux, Rocky Linux), dnf is the go‑to package manager. As system administrators and DevOps engineers, visibility into package installations and removals is crucial. That’s where dnf history shines—offering transparency, auditability, and repair capabilities.

In this blog post, we’ll dive deep into DNF history, explaining how to track transactions, analyze them, undo mistakes, and integrate insights into system monitoring. Each section is crafted with an SEO strategy: headings with target keywords, practical examples, tables, and structured data.


What is dnf history and why it matters 

dnf history is a subcommand of DNF that tracks package management transactions in a database located in /var/lib/dnf/history.sqlite. It records installs, updates, removals, and more, along with metadata like timestamps, user, duration, and exit status.

✅ Benefits:

  • Audit trail: Who performed what and when.
  • Troubleshooting: Diagnose breakages after updates.
  • Rollback ability: Restore states with dnf history undo or rollback.
  • Compliance: Track changes for security policies.

How dnf history works under the hood 

DNF keeps a lightweight SQLite DB of transactions. Each transaction record includes:

ColumnDescription
idInternal transaction ID
dateTimestamp of transaction
userUID of invoking user
commandExact command invoked
rpmsNumber of packages involved
durationTime taken
stateSuccess/failed status

Listing Transactions

				
					sudo dnf history
				
			
dnf history tracking

Photo by admingeek from Infotechys


📊  dnf history output breakdown

FieldMeaning
IDUnique history ID
CommandWhat command triggered the transaction (install/update/remove)
Date and timeWhen it occurred
Action(s)Install, Erase, Update, Downgrade
AlteredNumber of packages affected

Inspecting a specific transaction in depth

To unpack a specific transaction:

				
					dnf history info 31
				
			
				
					Not root, Subscription Management repositories not updated
Transaction ID : 31
Begin time     : Fri 20 Jun 2025 07:19:53 PM EDT
Begin rpmdb    : 2230462844fe98a91a27511d3abc7012d950d993d6d9448e36e0f5b2ef11ad79
End time       : Fri 20 Jun 2025 07:19:57 PM EDT (4 seconds)
End rpmdb      : be2fc89b97b2340ed0d3f6df1d81b2066770e9d40134c93b0514fc39a341580d
User           :  <webapp1>
Return-Code    : Success
Releasever     : 9
Command Line   : install postgresql
Comment        : 
Packages Altered:
    Install postgresql-13.20-1.el9_5.x86_64              @repository.dev.naijalabs.net_rhel-9-for-x86_64-appstream-rpms
    Install postgresql-private-libs-13.20-1.el9_5.x86_64 @repository.dev.naijalabs.net_rhel-9-for-x86_64-appstream-rpms
				
			

This provides clear insight into all package-level changes.


Reverting transactions

🔄 Undo a single transaction

				
					sudo dnf history undo 31 
				
			
				
					Updating Subscription Management repositories.
Unable to read consumer identity

This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register.

Last metadata expiration check: 3:39:15 ago on Mon 23 Jun 2025 03:20:04 PM EDT.
Dependencies resolved.
============================================================================================================================================================
 Package                           Architecture     Version                  Repository                                                                Size
============================================================================================================================================================
Removing:
 postgresql                        x86_64           13.20-1.el9_5            @repository.dev.naijalabs.net_rhel-9-for-x86_64-appstream-rpms           5.8 M
Removing dependent packages:
 postgresql-private-libs           x86_64           13.20-1.el9_5            @repository.dev.naijalabs.net_rhel-9-for-x86_64-appstream-rpms           335 k

Transaction Summary
============================================================================================================================================================
Remove  2 Packages

Freed space: 6.2 M
Is this ok [y/N]: 

				
			

Reverses installation, removal, or upgrades from transaction 31.

🧠 Rollback multiple transactions

Suppose you want to rollback the last 2 transactions (IDs 31 and 30):

				
					sudo dnf history rollback 29 
				
			

This returns the system to the snapshot at history ID 29.

⚠️Warning: Some rollbacks may fail if dependencies changed since.


Searching DNF History

You may be interested in when a specific package was installed, updated, or removed (sudo dnf history list <package> or sudo dnf history <package>):

				
					sudo dnf history neovim
				
			
				
					...omitted for brevity...
ID     | Command line                              | Date and time    | Action(s)      | Altered
------------------------------------------------------------------------------------------------
    16 | install neovim                            | 2024-10-04 22:24 | Install        |   10 
				
			

Action vs dnf history subcommands

TaskCommand
Show all historydnf history
View details of one entrydnf history info <ID>
Undo a transactiondnf history undo <ID>
Rollback multiple entriesdnf history rollback <ID>
Search for package activitydnf history list <package>

✅Best practices: auditing, logging, alerts 

To leverage "dnf history" in production:

  • Automated dumps: Cron a weekly dump via:
				
					dnf history > /var/log/dnf-history-$(date +%F).log
				
			
  • Integrate with syslog: Log rotate and secure permissions.
  • Alert on anomalies: Use AIDE or tripwire to detect unexpected dnf history changes.
  • Monitor via SIEM: Feed history logs into ELK, Splunk, or OSSEC.
  • Backup DB: Periodically copy /var/lib/dnf/history.sqlite.

Performance & housekeeping tips

  • Clean the history DB if it gets bloated (>10K entries):
				
					sqlite3 /var/lib/dnf/history.sqlite "DELETE FROM transaction WHERE id < 50000;" # Repack with .vacuum
				
			
  • Avoid history on container builds by passing --setopt=history_record=false.
  • Restrict retention by pruning entries older than X days.

🏁 Conclusion

dnf history is an indispensable tool for system transparency, auditability, troubleshooting, and even security. By mastering it, you can detect, document, and reverse package-level changes with precision.

Whether you’re a Linux system administrator, DevOps engineer, or security professional, understanding how and when packages were installed, updated, or removed is critical to maintaining a stable and secure system. With dnf history, you not only gain insight into the state of your environment but also the power to correct unintended changes quickly and reliably.

Moreover, integrating dnf history into your routine monitoring and reporting workflows helps meet compliance requirements, simplifies incident response, and ensures change control is enforced across environments. When combined with tools like log analyzers, cron jobs, and version control of configurations, dnf history becomes part of a larger ecosystem of infrastructure intelligence.

Did you find this article helpful? Your feedback is invaluable to us! Feel free to share this post with those who may benefit, and let us know your thoughts in the comments section below.


Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *