eBPF (extended Berkeley Packet Filter) is a Linux kernel technology that runs small, sandboxed programs in response to events such as system calls, function calls, network packets or timers. The kernel verifies each program for safety before running it, which allows deep networking, security and observability insight without kernel modules or application code changes.
What eBPF is
eBPF lets you extend the Linux kernel at runtime without writing kernel modules or rebuilding the kernel. Its roots are the original Berkeley Packet Filter, created in the early 1990s to filter network packets efficiently for tools like tcpdump. Starting around 2014, the Linux kernel gained an extended version with a more powerful instruction set, data structures and many new attachment points. Today the name eBPF is used for the whole technology, far beyond packet filtering.
For observability, eBPF is attractive because it sees what the kernel sees: every system call, every TCP connection, every scheduled process, and with user-space probes even function calls inside applications. It does so from outside the application, so data can be collected without changing or restarting code.
How eBPF works
- Write and compile. eBPF programs are typically written in restricted C or generated by higher-level tools, and compiled with LLVM/Clang into eBPF bytecode.
- Verify. When the program is loaded, the in-kernel verifier checks that it terminates, only accesses memory it is allowed to, and cannot crash the kernel. Programs that fail verification are rejected.
- JIT-compile and attach. The bytecode is just-in-time compiled to native machine code and attached to a hook.
- Share data via maps. eBPF maps (hash tables, arrays, ring buffers and more) store state and pass data to user space, where an agent aggregates and exports it.
Common hooks include kprobes and fentry for kernel functions, uprobes for user-space functions, tracepoints, perf events for sampling, and networking hooks such as XDP and traffic control (tc). BTF type information and CO-RE ("compile once, run everywhere") let one compiled program run across different kernel versions.
Why eBPF matters for observability
Traditional approaches to deep visibility had uncomfortable trade-offs. Kernel modules are powerful but risky, because a bug can crash the host. Language agents and SDKs provide rich context but must be added to every service, in every language, and kept up to date. eBPF offers a third path: safe, programmable access to kernel events with one agent per host. That makes it especially valuable in Kubernetes clusters with many teams and languages, where it provides a consistent baseline of network, process and performance data for every workload, including third-party software you cannot instrument yourself.
Observability use cases
| Use case | What eBPF provides |
|---|---|
| Network monitoring | TCP connections, retransmits, DNS latency and traffic flows between pods and hosts |
| Continuous profiling | Sampled stack traces from perf events across all processes with low overhead |
| Automatic instrumentation | HTTP and gRPC request metrics and spans derived from kernel and library probes |
| Security | Process execution, file access and network activity for runtime threat detection |
| Performance analysis | Scheduler latency, disk I/O latency and system call histograms |
Well-known open source projects in this space include bpftrace and BCC for ad-hoc tracing, Cilium for networking, Falco for runtime security and Parca for profiling. The OpenTelemetry project also hosts eBPF-based components for network telemetry and zero-code instrumentation.
Example: a one-line trace
With bpftrace you can count system calls per process on a host for ten seconds without touching any application:
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); } interval:s:10 { exit(); }'
Production agents use the same mechanisms, but with precompiled programs, careful sampling and aggregation in kernel maps so that only summaries cross into user space.
Limits and trade-offs
- Linux-centric. eBPF is a Linux kernel feature. An eBPF for Windows project exists, but the ecosystem is far less mature, and managed serverless platforms usually do not allow loading eBPF programs.
- Kernel versions matter. Many features require recent kernels; BTF and CO-RE work best on kernels from the 5.x series onward.
- Privileges. Loading programs requires elevated capabilities such as
CAP_BPFandCAP_PERFMON, orCAP_SYS_ADMINon older kernels, so agents run privileged. - Less application context. eBPF sees bytes and function calls, not business meaning. Encrypted traffic requires probes on TLS libraries, and full context propagation across services is harder than with SDK-based instrumentation.
Best practices
Treat eBPF as a complement to OpenTelemetry SDKs, not a replacement. Use it for broad, zero-code coverage of infrastructure, network and profiling data, and add SDK instrumentation where you need business attributes and precise spans. Pin and test the kernel versions you support, review the privileges agents require, and measure overhead on representative workloads before rolling out fleet-wide.
How Obseria helps
Obseria ingests OpenTelemetry data natively, so telemetry produced by eBPF-based OpenTelemetry components lands next to SDK traces, logs and metrics. Obseria network monitoring, continuous profiling with under 1% overhead and Kubernetes monitoring put this low-level data into the context of the services it affects.