cloudparts

eBPF

A small virtual machine inside the Linux kernel: programs are checked by a verifier, compiled to machine code and attached to kernel or app events, so tracing, networking and security tools run in the kernel without kernel modules.

eBPF Foundation project
Type
Open source
Made by
Linux kernel BPF maintainers, backed by the eBPF Foundation (Linux Foundation)
Foundation
eBPF Foundation. The foundation funds and promotes eBPF; the code is developed upstream in the Linux kernel. Part of the Linux Foundation
License
GPLv2 (kernel runtime, verifier and JIT); the instruction set is BSD-licensed; programs that call “GPL only” helpers must be GPL-compatible
Facts checked
28 October 2026

What it is

eBPF lets you run sandboxed programs inside the kernel without changing kernel source or loading a module. You write a small program, usually in restricted C or Rust, and compile it with Clang or GCC to eBPF bytecode, a 64-bit instruction set with ten general-purpose registers, standardised by the IETF as RFC 9669 in October 2024. A loader such as libbpf hands it to the kernel with the bpf() system call. Before it runs, the verifier walks every path through the program, tracking each register’s type and possible values, and rejects anything that could crash or hang the kernel: unchecked pointers, out-of-bounds reads, loops it can’t prove will end. A JIT then compiles the accepted bytecode to native code for the CPU.

The program runs when its hook fires: a kernel function or tracepoint, a function in a user-space binary (uprobes), a system call, a packet arriving at the network driver (XDP) or the traffic-control layer, a cgroup event or a security check. Programs can’t call arbitrary kernel functions, only a stable set of helpers and kfuncs, and they keep state in maps, such as hash tables, arrays, ring buffers and LPM tries for IP prefixes, which user space reads too. Many cloud tools are built on it: Cilium for Kubernetes networking, Falco and Tetragon for runtime security, bpftrace and bcc for ad-hoc tracing, Meta’s Katran load balancer, and the eBPF agents of observability products. Since Linux 6.12 even the CPU scheduler can be written in eBPF, through sched_ext.

Why teams pick it

  • Changes kernel behaviour at runtime without rebuilding the kernel or loading a module, and the verifier makes a crash far less likely than with a module
  • Low overhead: programs are JIT-compiled and run where the event happens, so tools can aggregate in the kernel and copy out only summaries
  • Sees everything on the host, including apps you can’t change: system calls, network packets and functions in uninstrumented binaries
  • Fast packet paths: XDP programs act on packets in the driver, before the kernel allocates its usual socket buffers, which suits load balancers and DDoS filters
  • Portable binaries: with BTF type information and libbpf’s CO-RE relocations, one compiled program runs on kernels whose internal structs differ

Watch out for

  • The verifier is strict and its errors are hard to read: correct-looking code is rejected over a missing null or bounds check, and complex programs hit the 1-million-instruction verification limit
  • Features depend on the kernel version: bounded loops need 5.3, CO-RE needs a kernel built with BTF, and sched_ext needs 6.12, so older distributions get less
  • Loading programs needs root or CAP_BPF unless unprivileged eBPF is enabled, so eBPF tools usually run as privileged agents on each node
  • Linux-first: Microsoft still calls eBPF for Windows a work in progress, and it checks programs with a different verifier (PREVAIL) and usually compiles them into Windows drivers
  • Programs that call “GPL only” helpers, and all LSM and struct_ops programs, must carry a GPL-compatible licence

Alternatives

What all runtime virtual machines have in common →Compare side by side →

How it fits with other technologies

Count execve() calls per command name in a map that user space reads · c

// count.bpf.c, built with: clang -O2 -g -target bpf -c count.bpf.c
#include "vmlinux.h"          // kernel types, generated from BTF
#include <bpf/bpf_helpers.h>

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 10240);
    __type(key, char[16]);      // command name
    __type(value, u64);         // number of calls
} counts SEC(".maps");

SEC("tracepoint/syscalls/sys_enter_execve")
int count_execve(void *ctx)
{
    char comm[16];
    u64 one = 1, *n;

    bpf_get_current_comm(&comm, sizeof(comm));
    n = bpf_map_lookup_elem(&counts, &comm);
    if (n)                      // without this check the verifier rejects the program
        __sync_fetch_and_add(n, 1);
    else
        bpf_map_update_elem(&counts, &comm, &one, BPF_ANY);
    return 0;
}

char LICENSE[] SEC("license") = "GPL";

Where a program can attach#

The hook decides what a program sees and what it may change. These are the families cloud tools use most.

Runs whenTypical use
kprobes, fentry, tracepointsA kernel function is entered or returns, or a stable tracepoint firesTracing and profiling: latency histograms, syscall auditing (bpftrace, bcc)
uprobes, USDTA function in a user-space binary or library runsTracing functions in apps and libraries without changing or restarting them
XDPA packet reaches the network driver, before the kernel’s networking stackLoad balancing and DDoS filtering at line rate (Katran, Cloudflare)
tcA packet enters or leaves an interface in the traffic-control layerContainer networking and policy (Cilium)
cgroup, LSMA process in a cgroup opens a socket, or a security hook runsPer-container firewalls and runtime security (Tetragon, Falco)
struct_opsThe kernel calls an operation that the program implementsCustom TCP congestion control, and CPU schedulers through sched_ext

See it in a real stack

No architecture uses eBPF yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from1993–2024

BPF, the Berkeley Packet Filter, was described by Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory at USENIX in 1993: a tiny register machine in the kernel that ran a capture filter on each packet, so tools such as tcpdump copied only the packets they wanted. Linux adopted it for socket filtering, and later for seccomp system-call filters.

In 2014 Alexei Starovoitov reworked the kernel’s BPF into a more general machine: ten 64-bit registers, instructions close to real hardware and calls to a restricted set of kernel functions. LWN called it “the universal in-kernel virtual machine”. Linux 3.18, released in December 2014, added the bpf() system call, maps and the verifier, which “statically determines that the program terminates and is safe to execute”. Tracing hooks followed, then XDP in Linux 4.8 in 2016, BTF type information and, in 2020, libbpf’s “compile once, run everywhere” relocations.

Meta, Google, Isovalent, Microsoft and Netflix set up the eBPF Foundation at the Linux Foundation in August 2021, the year Microsoft started eBPF for Windows. The IETF published the instruction set as RFC 9669 in October 2024, and Linux 6.12 that November let schedulers be written in eBPF.

Why it’s built this way

A verifier instead of trust
Code in the kernel can crash the whole machine. Checking every path before loading, and refusing anything that might loop forever or touch memory it shouldn’t, lets far more people run their own code in the kernel than kernel modules ever could.
A small, hardware-like instruction set
Registers and instructions that map almost one-to-one onto x86-64 and Arm64 make the JIT simple and the compiled code fast, and the same bytecode can be checked once and run on any CPU the kernel supports.
Helpers and maps instead of free access to the kernel
A fixed API of helper functions, and shared maps for state, keep programs away from arbitrary kernel internals while still letting them talk to user space and to each other.

Timeline

  1. 1993

    McCanne and Jacobson publish the BSD Packet Filter at USENIX

  2. 2014

    Extended BPF; Linux 3.18 adds the bpf() syscall, maps and the verifier in December

  3. 2016

    XDP in Linux 4.8

  4. 2019

    Linux 5.2 raises the verifier limit to 1 million instructions; 5.3 allows bounded loops

  5. 2020

    BPF CO-RE: compile once, run on many kernels

  6. 2021

    eBPF Foundation founded in August; eBPF for Windows started

  7. 2024

    RFC 9669 standardises the instruction set in October; sched_ext in Linux 6.12 in November

Sources18 · facts checked 28 October 2026

Improve this page on GitHub