bpftrace: a high-level tracing language for Linux, and where it stops
High-level tracing language for Linux
At a glance
- What is it?
- bpftrace compiles an awk-like one-liner language into eBPF programs that attach to kprobes, uprobes, tracepoints and USDT markers. It is a strong fit for ad-hoc production diagnosis and a weak fit for anything that needs a stable ABI across kernel versions.
- Who is it for?
- Adopt bpftrace if you need to answer a specific question about a running Linux system today and you can install it from your distribution's package manager. Do not adopt it as the foundation of a shipped product or a long-lived daemon that must survive kernel upgrades without rework; the README points at the migration guide for a reason, and the language surface has moved between releases.
- 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 1 day 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 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem bpftrace solves, and who actually has that problem
Linux gives you several ways to observe a running kernel, and most of them force a choice. perf records events but its scripting surface is limited. Reading /proc and /sys gives you counters, not causality. Writing a kernel module to answer one question is disproportionate and unsafe on a production host. Historically the answer was DTrace on Solaris and SystemTap on Linux, and bpftrace borrows the shape of both: a small language where a probe and an action sit next to each other, compiled and attached at runtime.
The audience is narrower than the tagline suggests. bpftrace is for people who already know what a kprobe is and want to skip the boilerplate of writing one. The README describes it as a general purpose tracing tool and language for Linux, which is accurate but does not say who benefits. The realistic user is a systems engineer or SRE debugging a latency spike, a filesystem stall or an unexpected syscall pattern on a machine they cannot restart. It is also used interactively: you write a one-liner, look at the histogram, refine it, and throw it away. That throwaway quality is a feature. The repository ships a tools/ directory of canonical scripts, but the primary workflow is still typing a program at a shell prompt.
How the compiler pipeline turns a one-liner into eBPF
bpftrace is not an interpreter. The README states that it uses LLVM as a compiler backend and libbpf for interacting with the Linux BPF subsystem. That sentence describes the whole architecture in one line, and it matters for understanding failure modes.
When you run a program, bpftrace parses it, resolves the probe names you wrote against what the running kernel actually exposes, generates LLVM IR, and compiles that to BPF bytecode. libbpf then loads the bytecode into the kernel and attaches it to the probe points. Probes that cannot be resolved fail at this stage, not at runtime, which is why a typo in a function name gives you an error before anything executes.
The probe types listed in the README cover kernel dynamic tracing through kprobes and hardware and software perf events, user-level dynamic tracing through USDT and uprobes, and both regular and raw tracepoints. The language itself is described as inspired by awk, C, and predecessor tracers such as DTrace and SystemTap. That inheritance explains the syntax: a probe specification, a block, and map operations for aggregation. Because LLVM sits in the middle, the compiled program is real BPF bytecode with the verifier's constraints on it, which means loops and unbounded memory access are not available in the way they would be in a normal C program.
Installing bpftrace and running a first trace
The README's Quick Start says you can often install it using your distribution's package manager, and it lists commands per distribution. On Debian and Ubuntu the documented command is:
sudo apt install bpftraceFedora, CentOS and related systems use dnf, Alpine uses apk, Arch uses pacman, Gentoo uses emerge, openSUSE uses zypper, and nixpkgs provides it through nix-shell. The README also notes an AppImage nightly build. Building from source is documented separately in the development guide rather than in the Quick Start.
There is an important caveat in the README itself. It warns that when using a distribution package you should verify bpftrace --version when referencing documentation, because the packaged version may not match the documentation you are reading.
bpftrace --versionRun that before you trust any example. If the version is older than the documentation you are following, syntax may differ.
For a first real use, the README does not include a worked example. The homepage at bpftrace.org links to tutorials, documentation and hands-on labs, and the repository keeps reference material under the man/ and docs/ directories; the docs/developers.md file covers building from source. Start from those rather than from a pasted snippet, because the probe vocabulary you can use depends on which probe types your running kernel exposes.
Where bpftrace is the wrong tool
The compiler dependency is the first constraint. Because LLVM does the code generation, bpftrace carries a large build and runtime footprint compared with a hand-written BPF program. On a constrained container or an embedded target that is a real cost, and the README's own installation table is a list of full distributions, not minimal images.
The second constraint is version drift. The README links a migration guide under docs/ for people moving from older versions, which is an admission that the language has changed in ways that break existing programs. A one-liner you paste from a blog post written against an older release may not compile against a newer one. For interactive debugging that is an annoyance. For a monitoring script checked into a repository and run by a cron job, it is a maintenance liability you have to budget for.
The third is that bpftrace is a tracing tool, not a profiler with a stable output format. It prints to a terminal. There is no documented stable machine-readable output contract in the README, so building a pipeline that parses bpftrace output and feeds it into a metrics system couples you to the human-facing format. If your goal is continuous production telemetry with a schema, you are looking at the wrong layer.
Finally, the probe types are Linux-specific by construction. kprobes, uprobes, USDT and tracepoints are kernel interfaces. Nothing in the README suggests portability beyond Linux, and the topics list confirms the scope.
bpftrace against bcc, perf, strace and the DTrace lineage
The closest comparison is bcc, which appears in the repository's own topics list. Both compile to eBPF and both attach to the same kernel probe types. The difference is the interface. bcc is a library with Python and C++ front ends, so you write a program that embeds a BPF snippet and handles the output yourself. bpftrace is a language and a command-line tool, so the program is the whole artifact. If you need to integrate tracing into an existing application or emit structured data, bcc gives you the seams. If you need an answer in the next two minutes, bpftrace is faster to write.
perf overlaps on hardware and software perf events, which the README lists among the supported probe types. perf is a general event sampling and recording tool with a mature data file format; bpftrace is a scripting layer that can attach to perf events among others. Choose perf when you want to record and analyse later, and bpftrace when you want to aggregate in the kernel and print a summary.
strace sits one level down. It intercepts syscalls for a single process, which is exactly what a syscall tracepoint in bpftrace can also do, but strace requires no kernel BPF support and no elevated compilation step. For a single process on a system where BPF is unavailable, strace is the simpler answer. bpftrace wins when you need system-wide aggregation or probes that are not syscalls, such as a uprobe inside a user-space function.
The DTrace and SystemTap comparison is about lineage rather than competition. The README states the language is inspired by awk, C, and predecessor tracers such as DTrace and SystemTap. If you have DTrace experience, the mental model transfers directly; what does not transfer is the probe vocabulary, because the underlying kernel interfaces are different.
Maintenance, releases and what the Apache-2.0 licence implies for redistribution
The repository is not archived and the last push was on 2026-09-20, one day before the date of writing, so the project is under current development. The release cadence visible in the release list is roughly quarterly: v0.26.0 on 2026-05-26, v0.26.1 on 2026-06-02, and v0.27.0 on 2026-09-10. The 0.x version numbers are worth reading literally. A minor version bump can carry language changes, which is consistent with the existence of a migration guide in docs/.
Upgrade cost therefore falls unevenly. If you use bpftrace interactively, upgrading is close to free: you install the new package and older one-liners either work or fail loudly at compile time. If you maintain a set of scripts, each upgrade is a review pass over those scripts against the migration guide. The tools/ directory in the repository is the project's own answer to this, shipping canonical scripts that presumably track the current language, but the README does not document a compatibility guarantee for them.
The licence is Apache-2.0, and the README displays the badge accordingly. Apache-2.0 is a permissive licence that includes an explicit patent grant and requires attribution and retention of notices when you redistribute. If you copy scripts out of tools/ into your own repository, the licence obligations follow those files. This is a description of what the licence text does, not legal advice; if redistribution is part of your plan, read LICENSE and your organisation's policy.
Editorial conclusion
Adopt bpftrace if you need to answer a specific question about a running Linux system today and you can install it from your distribution's package manager. Do not adopt it as the foundation of a shipped product or a long-lived daemon that must survive kernel upgrades without rework; the README points at the migration guide for a reason, and the language surface has moved between releases. Before you commit, verify three things on your own machine: the output of bpftrace --version, since the README warns that distribution packages lag and documentation may not match; that your kernel exposes the probe types you intend to use, by listing kprobes and tracepoints on the target host; and the licence obligations you inherit if you redistribute the canonical tools from the tools/ directory alongside the binary.
Frequently asked questions
What is bpftrace?
It is a general purpose tracing tool and language for Linux that uses eBPF to attach to kernel and user-space probe points. The README describes the language as inspired by awk, C, and predecessor tracers such as DTrace and SystemTap.
How do I install bpftrace?
The README says you can often install it with your distribution's package manager, for example sudo apt install bpftrace on Debian and Ubuntu, sudo dnf install bpftrace on Fedora and CentOS, or sudo pacman -S bpftrace on Arch. It also warns that you should verify bpftrace --version when referencing documentation, because distribution packages may lag.
How do I use bpftrace?
You write a program consisting of a probe specification and an action, then run it. bpftrace parses it, compiles it through LLVM to BPF bytecode, and libbpf loads and attaches it to the probe points, so an unresolvable probe name fails at compile time. The homepage at bpftrace.org links to tutorials, documentation and hands-on labs.
What does bpftrace do?
It attaches eBPF programs to kernel dynamic tracing through kprobes and perf events, user-level dynamic tracing through USDT and uprobes, and regular or raw tracepoints, then runs the actions you wrote against the events. The README frames the goal as efficient tracing with minimal overhead.
What is the difference between bpftrace and bcc?
Both compile to eBPF and attach to the same kernel probe types, but bcc is a library with Python and C++ front ends where you embed a BPF snippet in a larger program, while bpftrace is a language and command-line tool where the program is the whole artifact. bcc gives you integration seams; bpftrace is faster to write for a one-off question.
How does bpftrace compare with strace?
strace intercepts syscalls for a single process and needs no BPF support, which makes it the simpler choice on a system where BPF is unavailable. bpftrace can also trace syscalls through tracepoints, but adds system-wide aggregation and probe types that are not syscalls, such as uprobes inside user-space functions.
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/bpftrace-bpftrace)