Every term you meet in the lessons, defined in plain language for someone
new to kernels — one to three sentences each, plus a one-liner on why it matters or where you run into it.
Terms are alphabetized; each has an #id anchor so the lessons can deep-link straight to it.
Tags mark bpftrace items and the one out-of-scope term.
A
Aggregation
Summarizing many events into a compact result inside the kernel — a count, sum, average, min/max,
or histogram — instead of shipping every raw event to user space. In bpftrace you aggregate into a map, e.g.
@bytes = sum(args.count) or @[comm] = count().
Why it matters: aggregation is what makes tracing cheap enough for production — the kernel
does the math, so you read a tidy table, not a firehose.
argsbpftrace builtin
A struct holding the named arguments of the probed event — the fields of a tracepoint,
or the typed arguments of a kernel/user function. You read them by name, e.g. args.filename
or args.count.
Where you meet it:tracepoint:syscalls:sys_enter_openat { printf("%s\n", str(args.filename)); }
— far friendlier than positional arg0..argN.
arg0 … argNbpftrace builtin
The raw, positional arguments of a probed function as 64-bit values: arg0 is the first
argument, arg1 the second, and so on. Used with kprobes/uprobes,
where there is no type info to give you named args.
Heads-up: they're untyped integers — you often wrap them, e.g. str(arg0)
to read a string pointer, and you must know the function's signature yourself.
B
BCC (BPF Compiler Collection)
A toolkit (project iovisor/bcc) with a large collection of ready-made tracing tools plus
C and Python interfaces for building your own. You write the kernel half in C and the user-space orchestration in
Python (the Python front-end is now de-emphasized in favor of libbpf-style C).
Where you meet it: Brendan Gregg's guidance — "bcc is ideal for complex tools and daemons";
reach for it when a bpftrace one-liner isn't enough.
BEGIN / END probes bpftrace
Special probes that fire once at program start (BEGIN) and once at program exit
(END), not tied to any kernel event. Use BEGIN to print a header or
initialize state, and END to print final results.
Where you meet it:END { print(@); } — by default bpftrace already prints
maps on exit, but END lets you control or format the summary.
BPF (classic BPF / cBPF) & the name
BPF originally stood for Berkeley Packet Filter, a tiny in-kernel virtual machine from 1992 for
filtering network packets (e.g. for tcpdump). That original form is now called classic
BPF or cBPF to distinguish it from the modern eBPF.
Why it matters: it explains the name's history — eBPF kept the "BPF" letters but long outgrew
packet filtering, so today "BPF" and "eBPF" are used interchangeably and no longer stand for anything.
ebpf.io
BPF bytecode
The low-level, machine-independent instruction format the kernel expects an eBPF program to be loaded as. A
compiler (or bpftrace) turns your high-level source into this bytecode, which the kernel then verifies and runs.
Why it matters: bytecode is the universal "shipping format" — it's what the
verifier checks and what the JIT turns into native CPU instructions.
bpf() syscall
The single Linux system call through which all eBPF operations flow: loading a program, creating and reading/writing
maps, attaching programs, and more — selected by a command argument.
Where you meet it: you rarely call it by hand — bpftrace, BCC, and libbpf call bpf()
for you — but it's the kernel doorway every eBPF tool uses.
bpf(2)
BPF virtual machine
The abstract instruction-set "machine" that eBPF bytecode targets: a small set of registers and instructions the
kernel knows how to validate and execute. It's a sandbox model, not a real CPU — programs run inside it under the
kernel's control.
Why it matters: the VM abstraction is what lets the same bytecode be verified for safety and
then JIT-compiled to whatever real CPU you're on.
bpftrace the course's anchor tool
A high-level tracing language and front-end for eBPF: you write short, awk-like scripts (probe /filter/ { action })
and bpftrace compiles, loads, and runs them for you. Created by Alastair Robertson; ideal for ad-hoc one-liners and
short scripts.
Why it matters: it's the fastest way to ask the running kernel a question — "if you want to program your own, start with bpftrace."
BTF (BPF Type Format)
A metadata format that encodes type and debug information (struct layouts, function signatures, source lines) about
BPF programs and the kernel itself. Modern kernels ship their own BTF so tools can learn the exact shape of kernel
data structures at runtime.
Why it matters: BTF is the foundation of CO-RE — it's how a program written
once can correctly find a struct field even on a kernel whose layout differs.
docs.kernel.org/bpf
Builtin bpftrace
A read-only variable bpftrace provides automatically inside a probe, giving context about the current event —
such as comm, pid, nsecs, cpu,
retval, or kstack.
Where you meet it: builtins are the nouns of a bpftrace one-liner — you reference them directly,
no setup required.
C
CAP_BPF / CAP_PERFMON
Fine-grained Linux capabilities (since kernel 5.8) that grant just the privileges eBPF needs, instead of
full root (CAP_SYS_ADMIN). CAP_BPF allows loading programs and creating maps;
CAP_PERFMON allows the performance-monitoring side (perf events and tracing programs).
Why it matters: together they let a tracing tool run without giving it the entire kernel — the
least-privilege way to permit bpftrace. In practice many setups still just use sudo.
capabilities(7)
commbpftrace builtin
The name of the current process (its "command" — the short executable name, e.g. nginx or
node).
Where you meet it: grouping by who's responsible — @[comm] = count() tells
you which programs are hitting a probe most.
CO-RE (Compile Once – Run Everywhere)
A technique that lets a single compiled eBPF program run unchanged across many kernel versions, even when internal
struct layouts differ. The compiler records what fields the program needs; using BTF, the loader
"relocates" those field accesses to match the kernel actually running.
Why it matters: CO-RE killed the old pain of recompiling a tool against each machine's kernel
headers — it's why portable eBPF tools (libbpf-based) ship as one binary.
cpubpftrace builtin
The ID of the logical CPU (processor) on which the probe is currently firing.
Where you meet it: spotting CPU imbalance or per-core behavior — e.g. @[cpu] = count().
curtaskbpftrace builtin
A pointer to the kernel's task_struct for the currently running thread — the kernel's big
bookkeeping record for a task.
Where you meet it: advanced scripts that read scheduler or process fields directly from the
task struct; most one-liners never need it.
D
Dynamic vs static tracing
Dynamic tracing instruments any function on the fly with no prior planning (kprobes,
uprobes) — flexible, but the function names/arguments can change between versions.
Static tracing uses instrumentation points the developers deliberately placed and named
(tracepoints, USDT) — fewer, but a stable contract.
Rule of thumb: prefer a static tracepoint when one exists; fall back to a dynamic probe to reach
anywhere else.
E
eBPF
A Linux-kernel technology that runs small, sandboxed programs in a privileged context (inside the kernel) in
response to events, safely and without changing kernel source or loading a module. "eBPF" is now a standalone term —
it no longer stands for anything (see BPF for the history).
Why it matters: it's the whole foundation — eBPF is how bpftrace can watch what the kernel and
your programs are doing, live, with near-zero overhead.
ebpf.io
eBPF program
The actual unit of code that runs in the kernel: event-driven, attached to a hook, and executed
whenever that hook is reached. It's loaded as bytecode, checked by the
verifier, and usually JIT-compiled.
Where you meet it: each bpftrace probe action becomes one eBPF program behind the scenes — you
write the script, bpftrace produces the programs.
Event
Something happening in the system that an eBPF program can react to — a function being entered or returning, a
syscall, a timer tick, a tracepoint firing. eBPF is fundamentally event-driven: no event, no execution.
Why it matters: framing tracing as "run this tiny program every time event X happens" is the
core mental model for everything in the course.
F
Flame graph
A visualization of sampled stack traces: each box is a function, its width is how often
that function (and its callees) appeared in the samples, and depth shows the call stack. Invented by Brendan Gregg.
Where you meet it: the standard way to read CPU profiles — the widest
boxes are where time is going.
brendangregg.com
funcbpftrace builtin
The name of the function the current probe is attached to.
Where you meet it: one probe spanning many functions (wildcards) — printf("%s\n", func)
tells you which one actually fired.
H
Helper function
A predefined kernel function that an eBPF program is allowed to call — a small, stable, allow-listed API. Helpers do
things a sandboxed program can't do directly: read/write maps, get the current time, fetch the pid,
copy memory safely, capture a stack, and so on.
Why it matters: helpers are the program's only "system calls" — they're how a verified, sandboxed
program safely reaches the outside world.
ebpf.io
Histogram — hist() / lhist()bpftrace
Aggregation functions that bucket values and print a text bar chart. hist(v) uses
power-of-two (log2) buckets — great for wide-ranging values like latency. lhist(v, min, max, step)
is a linear histogram with evenly sized buckets you choose.
Where you meet it:@ = hist(retval) to see a latency distribution at a glance —
the shape (and outliers) matter more than an average.
Hook / attach point
A defined place in the kernel or a program where an eBPF program can be attached so it runs when execution reaches
there. Pre-defined hooks include syscalls, function entry/exit, and tracepoints; kprobes and
uprobes let you create hooks almost anywhere.
Why it matters: picking the right hook is the act of tracing — it decides exactly which
events your program sees.
I
interval probe bpftrace
A probe that fires on a fixed time interval on a single CPU — e.g. interval:s:1
once per second. Used for periodic output and script-level timers.
Where you meet it: live dashboards — print and clear your maps every second:
interval:s:1 { print(@); clear(@); }. (Contrast with profile, which fires
on all CPUs.)
J
JIT compiler (Just-In-Time)
The kernel step that translates verified eBPF bytecode into the native machine
instructions of the current CPU, so the program runs at near-native speed instead of being interpreted.
Why it matters: JIT is a big reason eBPF tracing is cheap enough for production — your probe
becomes real CPU code, not a slow interpreter loop.
ebpf.io
K
kprobebpftrace probe
A dynamic probe that fires when a kernel function is entered. You can attach one to almost any
kernel function by name, e.g. kprobe:vfs_read, and read its arguments via
arg0..argN.
Where you meet it: reaching into kernel internals when no tracepoint covers what you need —
the flexible, "anywhere" probe.
kretprobebpftrace probe
The companion to a kprobe that fires when the kernel function returns, giving you its
retval. Pair it with the kprobe to measure how long the function took.
Where you meet it: latency measurement — timestamp on kprobe, subtract on
kretprobe, feed the delta to hist().
kstack / ustackbpftrace builtin
The current stack trace: kstack is the kernel-side call stack, ustack
the user-space call stack of the running thread. Both are capturable as map keys.
Where you meet it: answering "how did we get here?" — @[kstack] = count()
counts code paths and is the raw material for a flame graph.
L
libbpf
The standard C library for loading and managing eBPF programs from user space. It handles talking to the
bpf() syscall, applying CO-RE relocations via BTF, and
attaching programs.
Where you meet it: the modern foundation for portable, compiled eBPF tools (and the direction
BCC now points); you'll see it named when people talk "libbpf + CO-RE." Out of scope to write here,
but good to recognize.
lhist() — linear histogram bpftrace
See Histogram. lhist(value, min, max, step) places values into
evenly sized buckets between min and max.
Where you meet it: when you want uniform buckets (e.g. counts 0–20 by 1s) rather than
hist()'s widening power-of-two ranges.
M
Map
A kernel data structure (hash table, array, ring buffer, stack-trace store, and more) that eBPF programs use to
store state and to share data with user space. Maps can be read and written both by the in-kernel program and by the
user-space tool via the bpf() syscall.
Why it matters: maps are the bridge — every bpftrace @variable is a map,
and that's how your one-liner's results get from kernel to your terminal.
ebpf.io
N
nsecsbpftrace builtin
A timestamp in nanoseconds from a monotonic kernel clock (it counts up steadily; it's not wall-clock time).
Where you meet it: timing things — record nsecs at the start of an event,
subtract at the end to get a precise duration.
O
On-CPU vs off-CPU analysis
On-CPU analysis studies where threads spend time running on a CPU (classic profiling).
Off-CPU analysis studies time threads spend blocked off-CPU — waiting on I/O, locks, timers,
or the scheduler — captured with stack traces.
Why it matters: they're complementary, so 100% of a thread's time can be explained. If your code
is slow but the CPU is idle, the answer is in off-CPU time, not the on-CPU profile.
brendangregg.com
P
Perf buffer
The older mechanism for streaming per-event data from kernel to user space, using one ring buffer
per CPU. Simple and widely supported, but it can waste memory and lose ordering across CPUs.
Why it matters: it's the predecessor to the ring buffer; you'll see it
in older tools and BCC examples.
pid / tidbpftrace builtin
pid is the process ID (the kernel's thread-group ID — the number you see in
ps); tid is the thread ID of the specific thread that triggered the event.
Where you meet it: filtering to one process (/pid == 1234/) or attributing
events per-thread vs per-process.
Predicate / filter bpftrace
A condition in /slashes/ right after a probe; the action runs only when it's true. Example:
kprobe:vfs_read /comm == "node"/ { ... } fires only for the node process.
Why it matters: predicates cut noise at the source — you filter in the kernel, so you process and
print far less.
Probe
In bpftrace, the part of a statement that names what to instrument and when to fire — i.e. the
hook. Each statement is probe /predicate/ { action }; a probe has a type
(kprobe, tracepoint, uprobe, profile, …) and a target.
Why it matters: the probe is the first thing you write and the most important decision — choose it
and you've chosen your data.
profile probe bpftrace
A probe that fires on a timed interval across all CPUs at once — timed sampling. For example
profile:hz:99 samples 99 times per second on every CPU.
Where you meet it: CPU profiling — sample stacks and feed them to a
flame graph. (Contrast interval, which fires on one CPU.)
R
retvalbpftrace builtin
The return value of the probed function — available in return probes (kretprobe /
uretprobe) and in tracepoint exit events.
Where you meet it: checking outcomes — count failed syscalls with
/retval < 0/, or measure how long a call took via its return.
Ring buffer (BPF ring buffer)
The newer (Linux 5.8+) mechanism for streaming per-event data to user space: a single shared
multi-producer/single-consumer buffer across all CPUs. It preserves event ordering and uses memory more efficiently
than the per-CPU perf buffer.
Why it matters: it's the modern default for sending raw events out of the kernel — correct
ordering matters when you correlate things like fork → exec → exit.
nakryiko.com
S
System call (syscall)
The controlled doorway a user-space program uses to ask the kernel to do something privileged — open a file, read,
write, allocate memory, send on a socket. Each is a numbered request like openat or
read.
Where you meet it: syscalls are the richest tracing target — "what files is this opening?" is just
tracing the openat syscall tracepoint.
T
tracepointbpftrace probe
A static, developer-placed instrumentation point in the kernel with a stable name and documented
arguments — e.g. tracepoint:syscalls:sys_enter_openat. Arguments are read by name via
args.
Why it matters: tracepoints are the preferred kernel probe — a stable contract, so your script
keeps working across kernel versions where a kprobe might break.
U
Unprivileged eBPF
Whether a non-root user may call bpf() at all. Most distributions now disable it
(the kernel.unprivileged_bpf_disabled sysctl), so loading programs requires root or
CAP_BPF/CAP_PERFMON.
Why it matters: it's why bpftrace commands need sudo — the kernel gates
tracing behind privilege for safety.
docs.kernel.org
uprobebpftrace probe
The user-space equivalent of a kprobe: a dynamic probe that fires when a function in a
user-space binary or library is entered, e.g. uprobe:/bin/bash:readline.
Where you meet it: tracing inside an application or library — note it adds some latency to the
traced program, so use predicates to keep it targeted.
uretprobebpftrace probe
Fires when a user-space function returns, giving its retval — the user-space
partner to kretprobe.
Where you meet it: timing a user function (entry on uprobe, exit on uretprobe) or inspecting
what it returned.
USDT (User Statically-Defined Tracing)
Stable, developer-placed tracepoints compiled into a user-space program (databases, language runtimes, etc.).
The user-space counterpart to kernel tracepoints — named, documented, low-overhead.
Where you meet it: tracing application-level events an app deliberately exposes (e.g. a query
start), instead of guessing at internal functions with a uprobe.
USE method
A performance checklist by Brendan Gregg: for every resource, check Utilization (how busy it was),
Saturation (how much extra work is queued waiting), and Errors. Walk every resource —
CPU, memory, disks, network — through U, S, E.
Why it matters: it's a fast, systematic way to find bottlenecks; it tells you which
resource to point your tracing at next.
brendangregg.com
User space vs kernel space
Two protected worlds. Kernel space is the privileged core that manages hardware, memory, and
processes; user space is where your applications run, isolated from each other and the kernel. They
communicate through syscalls.
Why it matters: this boundary is the heart of the course — eBPF runs in the kernel, which
is exactly why a bpftrace probe can see across all of user space at once, no app changes needed.
V
Verifier
The kernel safety checker every eBPF program must pass before it runs. It proves the program will terminate
(no unbounded loops), never reads uninitialized memory or accesses out of bounds, and stays within complexity limits —
by analyzing all possible execution paths.
Why it matters: the verifier is why running eBPF in the kernel is safe — a rejected program simply
won't load. Note it checks safety, not what the program is trying to do.
ebpf.io
X
XDP (eXpress Data Path) out of scope
An eBPF hook at the very earliest point of network packet receive, used for ultra-fast packet processing (filtering,
load balancing, DDoS drop) before the kernel's normal networking stack.
Why it's here: you'll see "XDP" everywhere in eBPF writing — but it's networking, which
this observability-focused course deliberately leaves out. Defined so the term isn't a mystery.
💡 How to use this glossary
Every term has a stable #id anchor — the lessons link straight here (e.g.
glossary.html#verifier). Press Ctrl/⌘+F to find a term, or use the
A–Z bar to jump. Print to PDF for an offline cheat sheet — the layout is built for it.