Skip to content

eBPF Developer Tutorial vs libbpf-bootstrap vs bpftrace

Canonical comparison across three entries in the modern eBPF ecosystem. They are frequently weighed against each other but occupy different layers of the workflow; the practical question is which layer you need.

TL;DR

bpf-developer-tutorial libbpf-bootstrap bpftrace
What it is 57+-lesson hands-on curriculum with runnable tool examples Scaffold/template repository for bespoke C eBPF applications High-level tracing language and CLI for one-liner and script probing
Primary output Learning path ending in self-written tools Empty project you fill in (Makefile, vmlinux skeleton, user/loader split) Immediate trace output from .bt scripts or -e one-liners
Code surface C kernel side + C/Go/Rust user space per lesson C throughout (kernel + user loader) bpftrace DSL (bt), compiles through LLVM
Best for Structured skill acquisition from zero to frontier topics Starting your next production tool Ad-hoc "what is my kernel doing right now" questions
Stars / activity (2026-08) ~4.25k, pushed 2026-07-26 ~1.5k, pushed 2026-08-25 ~10.3k, pushed 2026-08-24
License MIT BSD-3-Clause Apache-2.0

Layer Mapping

Forcing the three into explicit infrastructure layers resolves most confusion:

flowchart TB
    subgraph Observation["Interactive observation layer"]
        BT["bpftrace<br/>scripts / one-liners<br/>operator on-call usage"]
    end
    subgraph Development["Application development layer"]
        LB["libbpf-bootstrap<br/>project scaffold<br/>bespoke tools"]
    end
    subgraph Education["Learning curriculum layer"]
        TUT["bpf-developer-tutorial<br/>57+ lessons, CO-RE<br/>multi-framework exposure"]
    end
    KERNEL["Linux kernel: verifier / JIT / hooks"]

    BT -->|"bpf() syscalls via libbpf + bcc backends"| KERNEL
    LB -->|"generated skeletons -> libbpf"| KERNEL
    TUT -.teaches.-> BT
    TUT -.produces projects shaped like.-> LB
    LB --> KERNEL

They compose rather than compete: the tutorial's own lesson 0 prescribes a path that runs bpftrace's one-liners first (~1h), then reads a libbpf-bootstrap example, then works through the curriculum itself. The tutorial repository even vendors both worlds — a bpftrace tutorial port under src/bpftrace-tutorial, and org starter templates that play the same role as libbpf-bootstrap (libbpf-starter-template, libbpf-rs-starter-template).

Profiles

bpftrace — the observation instrument

A high-level tracing language for Linux; LLVM compiles scripts into eBPF bytecode while it interacts with the kernel BPF subsystem via libbpf and bcc. Probes are addressed by name patterns — tracepoint:syscalls:sys_enter_open*, kprobe:tcp_*, wildcards included — and discovery is built in (bpftrace -l 'tracepoint:*'). Scripts read like awk with probe triggers:

tracepoint:syscalls:sys_enter_openat {
    printf("%-6d %-16s %s\n", pid, comm, str(args.filename));
}

Strengths: minutes-to-answer latency, no build system, no user-space program to maintain. Limits: everything stays inside one script; complex state machines, network data paths, or long-lived daemons quickly exceed what a tracing DSL wants to express. Runtime compilation means LLVM/bcc presence on target hosts unless using AOT mode.

libbpf-bootstrap — the development harness

The libbpf project's official scaffold: clone it and you get a ready *.bpf.c + user-space loader pair, generated skeleton headers, vmlinux.h for CO-RE relocations, and a Makefile wiring clang/llvm correctly. It intentionally contains few complete examples — its purpose is the empty starting point your real application grows inside. Depth beyond scaffolding (how to architect event plumbing, multi-language loaders, packaging/distribution) is out of scope by design; you bring the systems knowledge.

bpf-developer-tutorial — the curriculum

Where the other two are instruments, this is instruction. Each directory is a finished small tool (opensnoop variant, memleak tracer, XDP load balancer...) with its README explaining design choices, walking the same libbpf machinery bootstrap scaffolds — plus ranges neither covers: sched_ext scheduling classes, HID driver fixups, LSM enforcement, GPU/CUDA tracing, Android targets, and CI-verified per-lesson minimum-kernel documentation. Weakness mirrors its strength: as teaching material it optimizes legibility over production hardening, and early lessons favor the org's ecc/ecli pipeline before transitioning to plain libbpf workflows.

Dimension Comparison

Dimension bpf-developer-tutorial libbpf-bootstrap bpftrace
Time to first result ~1-2h (lesson 1 end-to-end) ~30min if clang env already correct minutes
Compile model AOT (CO-RE objects); some lessons AOT-packaged to OCI/Wasm AOT CO-RE at project build JIT default; AOT available
User-space program required yes (taught progressively, C → Go → Rust) yes (C, provided harness) no
Production-suitability path teaches toward it (ring buffers, filters, loaders) is the production starting point edge persistence/AOT only
Kernel baseline documented per-lesson matrix, 4.8 → 7.0 follows libbpf requirements (5.x+) requires BTF & modern probes; BTF-optional fallback modes exist upstream
Multi-language exposure C, Go (cilium/ebpf), Rust (libbpf-rs) none (C) bt DSL only

Distribution delta

Only the tutorial stream teaches you how artifacts leave the machine: OCI-image execution (ecli run ghcr.io/...) and Wasm modules feature in its material because the same org maintains those distribution runtimes (bpftime, wasm-bpf).

Decision Matrix

Weighted for "a platform team wants sustainable in-house eBPF capability":

Criterion (weight) Curriculum Bootstrap bpftrace
Skill building (35%) 5 2 2
Answer speed today (25%) 1 1 5
Production trajectory (25%) 4 5 2
Maintenance breadth C/Go/Rust (15%) 5 2 1
Weighted total 3.7 2.6 2.6

Primary recommendation: chain them — bpftrace for immediate operational questions (and to teach the team probe concepts cheaply), then this tutorial as the structured learning track, graduating teams onto libbpf-bootstrap or the org starter templates for their first maintained tool. The three slots are complementary rather than substitutable; budget drives allocation, not choice.

Fallback recommendation: if only one can be adopted now, adopt the tutorial alone — it self-introduces enough bpftrace (vendored port) and scaffold-shaped builds (lessons 11 onward) to delay both other adoptions without blocking anything.

Sources

Questions

  • Does bpftrace's AOT mode change the maintenance answer for air-gapped fleets where runtime LLVM is unacceptable?
  • Are the eunomia-bpf starter templates converging functionally with libbpf-bootstrap enough to justify their own comparison note?