Open-source project
Irqbalance/irqbalance avatar
Irqbalance/irqbalance

irqbalance spreads interrupt load across CPUs and keeps caches warm

The irqbalance source tree - The new official site for irqbalance

674 stars147 forksCGPL-2.0

At a glance

What is it?
irqbalance is a C daemon that watches which interrupts are busiest on a Linux system and pins each one to a single CPU, spreading load across the processor set while trying to keep handlers close to the CPUs that need them. It suits a systems engineer tuning a busy multi-core box, and it is the wrong tool for a system where the kernel already does the job.
Who is it for?
irqbalance is worth running on a multi-socket or many-core Linux machine whose interrupt load is uneven, because the mechanism of pinning a busy IRQ to one CPU is something most administrators never tune by hand. It is the wrong tool for a laptop, a virtual machine with a small fixed CPU set, or any system where a distribution already ships a different implementation under the same name, and it is a poor substitute for firmware-level interrupt routing.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 24 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the daemon actually does with the interrupt table

The readme gives the definition in two sentences, and it is precise enough to tell you whether you need it. Irqbalance is a daemon to help balance the CPU load generated by interrupts across all of a system's CPUs. It identifies the highest volume interrupt sources and isolates each of them to a single unique CPU, so that load is spread as much as possible over an entire processor set, while minimising cache miss rates for IRQ handlers. Two separate goals are being pursued at once, and the second one is the more interesting. Simply spreading interrupts evenly across CPUs would be easy and would make the scheduler's job harder, because a handler that runs on a CPU far from the data it touches pays for the move. Pinning instead means a given device's interrupts always land on the same CPU, so the caches holding that device's data stay warm on that core. The source tree confirms the model. The file names describe the pipeline: procinterrupts.c reads the kernel's interrupt accounting, irqlist.c tracks the per-device interrupt objects, classify.c sorts them into categories, cputree.c builds a model of the processor hierarchy, and placement.c is where the decision of which CPU an interrupt should go to is made. numa.c handles node-aware behaviour, thermal.c accounts for thermal constraints, and bitmap.c with cpumask.h and non-atomic.h implement the CPU mask arithmetic the placement code needs.

Two build systems, and a source tree you can read in an afternoon

irqbalance is plain C with a conventional autotools build, and the documented sequence is short:

bash
./autogen.sh
./configure [options]
make
make install

The autogen.sh step generates the configure script from configure.ac, which is why the option placeholder is written as configure [options] rather than a fixed flag list, and the readme does not enumerate them. What is notable is that the tree also carries a meson.build and a meson_options.txt, so a second, more modern build system is available alongside Makefile.am. Distribution packaging can therefore take either route. The source layout is flat and readable, with the algorithm split across small files rather than hidden in one translation unit, and the top level entries show where the boundaries fall. There is a separate ui/ directory, which matches the man page named irqbalance-ui.1 sitting next to irqbalance.1, so the project ships a user interface program as well as the daemon. There is a misc/ directory and a tests/ directory, an AUTHORS file, a COPYING file, and the .github directory for issue and pull request work. The readme notes the project is currently hosted on github, with developers welcome to use the issue and pull request infrastructure there.

A bug report has to carry five specific pieces of evidence

The readme's bug reporting section is the most practically useful part of the document, because it tells you exactly what a maintainer needs to make progress. Your report should include the irqbalance version you have been using, or the commit hash. It should include the output of /proc/interrupts, which is the kernel's own per-CPU interrupt accounting and the raw data the daemon acts on. It should include the output of irqbalance --debug, which shows the daemon's own reasoning about placement decisions. It should include the content of the smp_affinity files, which is the kernel's current affinity mask per IRQ, obtainable by iterating over the /proc/irq entries. And it should include your hardware hierarchy, for example the output of lstopo-no-graphics, which describes the machine's CPU, NUMA and cache topology. That list is a good summary of what the daemon actually consumes: interrupt counts, the current affinity state, the CPU topology and the thermal picture. When you compare it with the source file names, the picture is consistent. The daemon's inputs are the interrupt table from procinterrupts.c, the topology from cputree.c, the thermal data from thermal.c, and the placement decision it writes back through activate.c, which is the file that presumably applies the affinity change to the kernel.

The files tell you what the daemon is trying to reason about

Looking at the module list gives a better picture of the problem domain than any summary. activate.c handles enabling and disabling the balancing for a given configuration, which is how a policy or a script turns the daemon's behaviour on and off. classify.c contains the categorisation logic, so it is where the decision about what counts as a shared, a managed or an excluded interrupt lives. constants.h holds the tunables and the default policy names. types.h and irqbalance.h define the shared structures. procinterrupts.c parses /proc/interrupts, and it is worth knowing that parsing is separate from the accounting because the kernel's file format has changed across versions and a parser is where version-specific breakage shows up. thermal.c and thermal.h are the least obvious files for a newcomer, since the readme never mentions thermals, and they exist because a CPU that is throttling should not be handed a share of the interrupt load. numa.c and cputree.c work together to know which NUMA node a CPU belongs to and how the hierarchy is shaped, which is what makes the cache-miss minimisation goal achievable rather than merely an aspiration. For a reader evaluating the project, this file naming is a good map of the design.

What irqbalance does not do, and the alternative paths

The clearest limit is in what the readme does not claim. There is no configuration reference, no list of policies or their names, no documentation of the interface to the kernel's own irqbalance capability, and no guidance on containers or virtual machines. The tool describes itself as a daemon for Linux systems, and the entire conversation is about a physical processor set with a real hierarchy, caches and thermal zones, so a virtual machine with a handful of virtual CPUs is not the environment it was designed for. There is also a genuine alternative that is not another program but a different layer of the same problem. Interrupt routing is first a firmware and hardware decision, expressed through PCI interrupt remapping and the I/O APIC, and a daemon running in the operating system can only work within what the firmware has already told it about. A second alternative is manual pinning through the smp_affinity interface in sysfs, which is what the bug report instructions ask you to collect, and that approach is more predictable for a machine whose load is stable, at the cost of being manual and per device. A third path is manual affinity tuning at boot or through kernel interfaces, and irqbalance sits above that level: it makes the choice itself with a fuller model of the topology.

Maintenance, releases and the licence

The project is under active development by the standards of a long-running system daemon. The last push was on 2026-09-29, inside the last six months, and the release history shows a recent burst after a quiet spell. v1.9.3 is dated 2023-11-10, v1.9.4 is dated 2024-03-19, and v1.9.5, described as a bug fix and feature release, is dated 2025-12-08. The gaps between those dates are long by modern standards for a C project, which tells you the release cadence is event driven rather than scheduled, and that the most recent tag is roughly ten months old even though commits have continued since. The licence is GPL-2.0, with the COPYING file at the repository root, which matters if you intend to redistribute a modified binary rather than simply install it. The homepage is the project site at irqbalance.github.io, and the .travis.yml file at the root points to the older Travis CI service for the build status badge in the readme, while the .github directory holds the issue and pull request workflow that the readme tells contributors to use.

Editorial conclusion

irqbalance is worth running on a multi-socket or many-core Linux machine whose interrupt load is uneven, because the mechanism of pinning a busy IRQ to one CPU is something most administrators never tune by hand. It is the wrong tool for a laptop, a virtual machine with a small fixed CPU set, or any system where a distribution already ships a different implementation under the same name, and it is a poor substitute for firmware-level interrupt routing. Verify first what your distribution ships under the irqbalance package, whether the SMP affinity of your busiest devices is already correct, and whether your distribution's irqbalance setup is already active. The last push was on 2026-09-29 and the newest release is v1.9.5 from 2025-12-08.

Frequently asked questions

What does irqbalance actually do on a Linux system?

It identifies the interrupt sources with the highest volume and isolates each one to a single unique CPU, so load spreads across the processor set while cache miss rates for IRQ handlers stay low. It is a daemon written in C.

How do I build irqbalance from source?

Run ./autogen.sh, then ./configure with any options, then make and make install. The repository also carries a meson.build and meson_options.txt, so a meson build is available as an alternative to the autotools path.

What should I include in an irqbalance bug report?

The version or commit hash, the /proc/interrupts output, the irqbalance --debug output, the contents of the smp_affinity files under /proc/irq, and your hardware hierarchy such as the lstopo-no-graphics output.

Is irqbalance still being developed?

The last push was on 2026-09-29 and the newest release is v1.9.5 from 2025-12-08, so commits are landing on the master branch. The tags themselves are spaced widely apart, with v1.9.3 from 2023-11-10 and v1.9.4 from 2024-03-19.

What licence is irqbalance released under?

GPL-2.0, with the COPYING file at the repository root. The project is hosted on github and the readme directs developers to the issue and pull request infrastructure there.

Official sources

  1. Irqbalance/irqbalance on GitHub
  2. License: GPL-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/irqbalance-irqbalance.svg)](https://hysenlabs.com/projects/irqbalance-irqbalance)

Was this useful?