bpftop: a top-style view of running eBPF programs
bpftop provides a dynamic real-time view of running eBPF programs. It displays the average runtime, events per second, and estimated total CPU % for each program.
At a glance
- What is it?
- bpftop shows average runtime, events per second and estimated CPU percentage per loaded eBPF program, turning statistics collection on only while the tool runs. It is for Linux engineers who need to know what their BPF programs cost.
- Who is it for?
- Adopt bpftop if you already load eBPF programs on Linux 5.8 or later and want per-program runtime and CPU estimates without writing your own BPF_ENABLE_STATS wrapper. Skip it if you need per-request tracing, if you cannot get root, or if you are on a kernel old enough that only the procfs fallback applies.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 29 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 September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What bpftop measures, and who needs that number
Once a handful of eBPF programs are attached on a host, the usual question is which one is burning cycles. The kernel can answer that, but only if runtime statistics are enabled globally, and the README states that this is off by default to reduce performance overhead. bpftop is a terminal UI that turns that collection on, samples it, and renders the result per program: average runtime, events per second, and an estimated CPU percentage, alongside the program ID, type and name.
The audience is narrow and specific. It is for people who load eBPF programs and then have to justify or debug their cost: platform engineers running Cilium-style networking, observability teams shipping kprobe and tracepoint programs, anyone who has attached something with bpftrace or bcc-tools and wants to know what it now costs. It is not a tracing tool. It does not tell you why a program is slow or what it is doing; it tells you how much time it is taking relative to the other programs on the same machine.
The BPF_ENABLE_STATS mechanism and why the overhead is bounded
The design rests on one syscall command. bpftop calls BPF_ENABLE_STATS, which the README describes as the command that enables global eBPF runtime statistics gathering. The call returns a file descriptor, and that descriptor is the switch: while it is open, the kernel keeps the counters; when bpftop exits, it deletes the descriptor and collection stops.
That detail matters more than the interface. Statistics are a global kernel-side facility, not a per-program opt-in, so any tool that wants these numbers has to hold that descriptor open for as long as it wants data. bpftop's contribution is holding it only while the TUI is on screen. The README calls this "minimal overhead" and describes enabling statistics only while active. The consequence is that you cannot leave bpftop running in the background as a silent collector and expect a clean history. The tool samples once per second by default, computes average runtime, events per second and estimated CPU utilization for that sample period, and draws a top-like table. Press Enter on a row and it switches to time-series graphs of the same metrics, which is the only place the history exists, and it lives in memory.
The data flow is therefore short: enable global stats, read counters for every loaded program, diff against the previous sample, render, repeat. No agent, no daemon, no exported time series. The README notes that logging goes to the systemd journal when journald is available, with a graceful fallback otherwise, and that older kernels are supported through a procfs path.
Installing bpftop and reading your first sample
The project ships an install script that the README says downloads the latest release for x86_64 or aarch64, verifies its SHA-256 against the digest published by GitHub, and installs to ~/.local/bin, or /usr/local/bin when run as root. The script takes --version <tag> to pin a release and --bin-dir <path> to change the destination. Distribution packages exist for Fedora, Arch Linux and nixpkgs, and the README lists the exact commands.
curl -fsSL https://bpftop.sh/install | shIf you would rather not pipe a script into a shell, use a package manager. On Fedora the README gives:
sudo dnf install bpftopOn Arch Linux:
sudo pacman -S bpftopAnd with Nix:
nix profile install nixpkgs#bpftopThe binary is dynamically linked to libz and libelf, so those libraries must be present on the machine where you run it. Then start it with root privileges, because statistics collection requires them:
sudo bpftopYou should see a table of every loaded eBPF program with its ID, type and name, and columns for runtime, events per second and estimated CPU. If the list is empty, the README says that is normal when no eBPF programs are loaded; load one with bpftrace or bcc-tools and it appears. Press f to filter by name or type, s to sort, j and k or the arrow keys to move, and Enter to open the graphs for the selected row. To slow the refresh, pass a delay in seconds:
sudo bpftop --delay 5The valid range is 1 to 3600 seconds. A longer delay gives you a wider sample window and a coarser picture; the README does not say how the average is weighted within that window, so treat a 300-second delay as a different measurement, not the same one smoothed out.
Where bpftop stops being the right tool
The most obvious limitation is the one stated in the prerequisites: it requires sudo. That rules it out for a shared jump host where you do not hold root, and it means the tool is a diagnostic you run during an investigation rather than something embedded in an unprivileged workflow.
The second is that the statistics are global and transient. Because collection is tied to the lifetime of the descriptor, two people running bpftop on the same host are both holding that switch, and neither gets a private view. There is no documented way to export the samples, so the graphs disappear when you quit. If you need a historical record of eBPF runtime cost, bpftop is the wrong instrument; you would be re-running it and copying numbers out by hand.
The third is resolution. A one-second sample of average runtime per program cannot separate a program that runs a thousand times cheaply from one that runs twice and expensively. The events-per-second column is what lets you make that distinction, and the README does not describe any per-invocation latency distribution. For tail latency questions, this tool gives you a starting point and nothing more. Finally, kernel support: 5.8 or later is the documented baseline, with a procfs fallback for older kernels, but the README does not enumerate what the fallback loses, so on an old kernel you should verify the numbers against something else before trusting them.
How it differs from bpftrace and the bcc toolset
bpftrace and bcc-tools are the natural neighbours, and the difference is in what gets loaded. Both of those compile and attach their own eBPF programs to answer a question you write: a kprobe on a function, a tracepoint, an aggregation over a time window. You get exactly the data you asked for, and you pay for it with a program you just added to the system.
bpftop attaches nothing of its own. It reads the counters the kernel already keeps for the programs that are there, which is why it can show you every loaded program without knowing anything about them. The trade is expressiveness for coverage. bpftrace answers "how often is this function called and with what arguments"; bpftop answers "which of my programs is using CPU right now". A practical sequence is to spot the expensive program in bpftop and then write a bpftrace one-liner to find out why, rather than starting from a blank script. The README's own troubleshooting section points in that direction, suggesting bpftrace or bcc-tools as a way to load a program so bpftop has something to display.
Maintenance, licence and the cost of keeping it current
The repository is not archived, and the last push was on 2026-09-01. Releases are reasonably spaced: v0.9.0 on 2026-05-02, v0.8.0 on 2026-04-13, and v0.7.1 on 2025-09-02. The Cargo.toml pins a fairly large dependency surface for a TUI: libbpf-rs, libbpf-sys, crossterm, ratatui, clap, nix, tracing and tracing-journald. Those are the things that will force upgrades, particularly libbpf-sys, which tracks the C library and therefore the kernel-side API. A build from source needs clang, libbpf-dev or libbpf-devel, zlib and libelf headers; the README gives the apt and dnf lines, and the repository also ships a Nix flake with a pinned dev shell containing clang, libbpf and the Rust toolchain, which is the more reproducible path.
The licence is Apache-2.0, declared in both Cargo.toml and the repository's LICENSE file. That is a permissive licence with an explicit patent grant, which is normally uncomplicated for internal tooling and redistribution. This is not legal advice; if you plan to bundle the binary into a product image, have someone check the notice and attribution requirements, and note that the dynamically linked libz and libelf carry their own licences.
Editorial conclusion
Adopt bpftop if you already load eBPF programs on Linux 5.8 or later and want per-program runtime and CPU estimates without writing your own BPF_ENABLE_STATS wrapper. Skip it if you need per-request tracing, if you cannot get root, or if you are on a kernel old enough that only the procfs fallback applies. Before rolling it out, confirm on one host that sudo bpftop lists the programs you expect, that the estimate matches what you see in your own load numbers, and that the delay value you plan to use does not distort the sample you are reading.
Frequently asked questions
What is the difference between BPF and eBPF?
The README uses the term eBPF throughout and refers to the BPF_ENABLE_STATS syscall command for enabling runtime statistics. It does not draw a historical distinction between the older BPF packet filter and eBPF, and the tool targets eBPF programs specifically.
What is BPF used for in bpftop?
bpftop monitors eBPF programs that are already loaded, showing each one's average runtime, events per second and estimated CPU percentage. It does not load programs of its own; the README suggests using bpftrace or bcc-tools if nothing is loaded and the list is empty.
Does bpftop need root privileges?
Yes. The README states that bpftop requires sudo privileges to run, because eBPF statistics collection needs root access, and the troubleshooting section lists "This program must be run as root" as a common error.
Which Linux kernel versions does bpftop support?
The README lists Linux kernel 5.8 or later as a prerequisite, with older kernels supported through a procfs fallback. It does not describe which metrics the fallback path loses.
Does bpftop add overhead to the system it monitors?
The README says bpftop minimizes overhead by enabling performance statistics only while it is active, using BPF_ENABLE_STATS and deleting the returned file descriptor on exit. Statistics gathering is disabled by default in the kernel precisely to avoid that cost.
Official sources
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.
[](https://hysenlabs.com/projects/jfernandez-bpftop)