eBPF Course · Lesson 1

What is eBPF?

Run your own small programs inside the Linux kernel — safely, and without changing or restarting anything.

🎯 Mission: see what your programs & system are really doing, live
The whole idea in one sentence

eBPF lets you load tiny, sandboxed programs into the running Linux kernel that fire when an event happens — so you can watch exactly what the system is doing, with no source changes, no kernel module, and no reboot.

01 Why this matters to you

You're an app developer. When something is slow, flaky, or weird in production, your usual move is: add log lines, redeploy, and hope you logged the right thing. eBPF flips that around.

With eBPF you can ask the already-running system a precise question — "which files is this process opening?", "what's making this syscall?", "where is the latency?" — and get an answer in seconds. No code change. No restart. No guessing.

🎯 Tie to your missionThis is the foundation for everything else in this course. Every tracing tool you'll learn (starting with bpftrace) is just a friendly way to load an eBPF program and read what it saw.

02 The wall between you and the interesting stuff

Your program runs in user space. But almost everything you'd want to observe — opening files, sending packets, scheduling threads, disk I/O — actually happens down in kernel space, on the other side of the system-call boundary. From user space you can see that you called open(), but not what the kernel did underneath.

Historically you had only two ways to run your own code inside the kernel to look — both bad for a casual observer:

Patch the kernel source

Change the kernel itself, convince the community to merge it, then wait years for it to ship in distros. Not happening for a debugging session.

Write a kernel module

Load your own C code with full kernel privileges. A bug doesn't throw an exception — it panics the whole machine. And it breaks every kernel update.

💡 eBPF is the third optionLoad a small program that the kernel verifies is safe before it runs, attach it to an event, collect data — then unload it. Safe enough to do on a production box, live.

03 The analogy: JavaScript, but for the kernel

This is the mental model the eBPF community itself reaches for. A web browser lets pages run little sandboxed JavaScript programs on events (a click, a page load). The browser guarantees that script can't crash your computer, and a JIT compiler makes it run fast.

eBPF does the same thing for the Linux kernel. The kernel is the "browser." Your eBPF program is the "JavaScript." Kernel events (a syscall, a function call, a network packet) are the "click handlers." A built-in safety checker plus a JIT make it safe and fast.

Analogy from ebpf.io — "What is eBPF?", the canonical introduction.

04 What an eBPF observability session looks like

Here's the shape of every tracing session you'll do. An event in the kernel triggers your program; your program records something into a map (a shared table); your user-space tool reads the map and prints it to you.

USER SPACE — where your tools & apps live KERNEL SPACE — where the real action happens — the system-call boundary — Your tool bpftrace / BCC Output you read "bash opened /etc/passwd" ① load & attach VERIFIER ✓ proves it's safe, then JIT EVENT fires e.g. open() syscall ② triggers Your eBPF program runs in-kernel, sandboxed "record who & what" ③ writes MAP shared table, readable from both sides ④ tool reads the map
The eBPF observability loop: ① your tool loads & attaches a verified program · ② a kernel event triggers it · ③ it records data into a map · ④ your tool reads the map and shows you the answer.

The four moving parts

Lifecycle & components per ebpf.io and Brendan Gregg, Linux eBPF Tracing Tools.

05 Why it won't crash your machine: the verifier

This is the part that makes eBPF usable in production — and the reason it's not just "kernel modules with a nicer name." When you load an eBPF program, the kernel's verifier statically analyzes it before a single instruction runs and rejects it unless it can prove:

If the proof fails, the program simply doesn't load — you get an error, the kernel keeps running. If it passes, a JIT compiler turns the bytecode into native machine code so it runs at roughly the speed of compiled-in kernel code. Loading generally requires root or the CAP_BPF capability.

💡 The takeawayA kernel module that has a bug crashes the kernel. An unsafe eBPF program refuses to load. That difference is the entire reason you can run this on a live server.

Verifier behavior & safety guarantees: ebpf.io — What is eBPF?

06 A glimpse of what you'll actually type

You won't write kernel C to start — you'll write bpftrace, a high-level tracing language where everything from the diagram above is handled for you. Here's a real one-liner. Don't worry about the syntax yet; just see the shape:

# prints every file every program opens, system-wide
bpftrace -e 'tracepoint:syscalls:sys_enter_openat {
              printf("%s opened %s\n", comm, str(args->filename));
            }'
Linux-only — copy it and try it later on a Linux box (it needs sudo).

Read it as WHEN ... DO ...:

That one line is an eBPF program: bpftrace compiles it, the verifier checks it, the kernel attaches it to that syscall, and the output streams back to your terminal. You'll learn to read and write every piece of this in Lesson 3.

Style from the official bpftrace One-Liner Tutorial.

07 eBPF vs. the old way, at a glance

 Kernel moduleeBPF program
A bug can crash the kernel?Yes — panicNo — won't even load
Safety checked before running?NoYes — the verifier
Need a reboot / module load?Load module (risky)No — load & unload live
Survives kernel upgrades?Often breaksDesigned to be portable
SpeedNativeNative (JIT-compiled)
Good for a quick prod question?NoYes — its whole point

08 Clear up four myths before we go on

"eBPF means writing kernel C."

Not to start. For observability you begin with bpftrace — a high-level language. C + libbpf is a later, optional step (out of scope for now).

"It could crash my kernel."

The verifier rejects unsafe programs before they run. That's the core safety guarantee — and why it's production-friendly.

"Berkeley Packet Filter — so it's only networking?"

That's just the historical name (it grew out of tcpdump's packet filters). Modern eBPF is general-purpose; observability is a huge use case.

"I can run it on my Mac."

Linux-only — it's Linux-kernel tech. On macOS you'll run it inside a Linux VM. That's why this course is conceptual-first for now.

09 Check yourself

Pick an answer — you'll get instant feedback. No grading, just a tight feedback loop.

1. What does the eBPF verifier do?
2. How does data an eBPF program collects get back to your user-space tool?
3. Your eBPF program has a bug that would loop forever. What happens?
4. The single best reason eBPF is safe to run on a live production server is:

10 Flashcards

Click to reveal. Come back to these later for quick review.

Q: In one sentence, what is eBPF?
A: A way to run small, sandboxed, verified programs inside the running Linux kernel, triggered by events — with no source changes, no kernel module, and no reboot.
Q: What's the "JavaScript for the kernel" analogy?
A: The kernel is the browser; your eBPF program is the sandboxed script; kernel events are the event handlers. A safety checker + JIT make it safe and fast — just like a browser running JS.
Q: Name the four moving parts of an eBPF observability session.
A: (1) the event/hook that fires it, (2) the eBPF program that runs in-kernel, (3) the verifier + JIT that makes it safe and fast, (4) the map that carries data out to user space.
Q: How is eBPF fundamentally safer than a kernel module?
A: A buggy kernel module can panic the machine. A buggy/unsafe eBPF program is rejected by the verifier and never runs — so a mistake is an error message, not an outage.
Q: Why can't you run eBPF directly on your Mac?
A: eBPF is Linux-kernel technology. On macOS you run it inside a Linux VM (or a remote Linux box). That's why this course stays conceptual for now.
Q: What's the first tool you'll use to write eBPF for tracing — and why?
A: bpftrace. It's a high-level language (Brendan Gregg's recommended starting front-end) that hides the C, the verifier, and the maps behind simple "WHEN … DO …" one-liners.
👩‍🏫 I'm your teacher — ask me anything

Stuck on a term? Curious how this maps to a problem you've actually hit? Want a sharper analogy? Just ask in the chat. Good questions to try: "Show me what comm and args mean," or "What's a real bug I could've found faster with eBPF?"