eBPF Observability: Kernel-Level Telemetry for Cloud-Native Systems
Cloud-native systems generate more telemetry than ever, yet many teams still struggle to answer basic production questions: Which service caused this latency spike? Which process opened that file? Which pod is retransmitting packets? Traditional observability relies on application instrumentation, sidecars, agents, and sampling. Those approaches work, but they leave gaps at the kernel boundary where syscalls, sockets, schedulers, and containers actually interact. eBPF closes much of that gap. It lets you run safe, sandboxed programs inside the Linux kernel and stream structured telemetry to user space without modifying application code.
This article explains how eBPF observability works, where it delivers the most value, how to design a production architecture, and what pitfalls to avoid.
Why Traditional Observability Hits a Wall
Logs, metrics, and traces are the pillars of observability, but each has blind spots in distributed systems.
- Instrumentation debt: Every service, language, framework, and dependency must be instrumented. Libraries change, teams forget, and coverage becomes uneven.
- Overhead and sampling: High-cardinality tracing can be expensive. Aggressive sampling saves cost but hides the rare events that matter during incidents.
- Context loss: A trace may show that a request was slow, but not whether the delay came from DNS, TCP retransmits, page cache misses, or CPU scheduling.
- Security blind spots: Application-level logs rarely reveal process execution, file access, or raw network connections at the host level.
eBPF does not replace logs, metrics, or traces. It adds a kernel-level source of truth that can enrich all three.
What Is eBPF, Exactly?
eBPF is a virtual machine and instruction set inside the Linux kernel. You compile small programs into eBPF bytecode, load them into the kernel, and attach them to predefined hooks. The kernel verifier checks safety before execution, and a JIT compiler translates the bytecode into native machine code.
- Programs: Event-driven functions that run in response to kernel or user-space events.
- Hooks: Attachment points such as kprobes, tracepoints, uprobes, XDP, TC, cgroup hooks, and perf events.
- Maps: Kernel-resident key-value data structures used to share state between eBPF programs and user space.
- Helper functions: Kernel-provided APIs for tasks like reading memory, getting timestamps, manipulating packets, and emitting events.
- BTF and CO-RE: BPF Type Format and Compile Once – Run Everywhere allow programs to adapt to different kernel versions without recompilation.
eBPF is not a kernel module. It cannot call arbitrary kernel functions or block indefinitely. The verifier enforces bounded execution, memory safety, and stack limits. That safety model is why eBPF can be used in production without rebooting nodes or risking kernel panics.
The eBPF Observability Toolchain
A production eBPF observability stack usually has four layers.
- Kernel programs: Small eBPF programs attached to syscalls, network interfaces, cgroups, or tracepoints. They collect events and update maps or ring buffers.
- User-space agent: A daemon that loads programs, reads maps and ring buffers, enriches events, and handles retries and backpressure.
- Collector and exporter: A pipeline that converts eBPF events into OpenTelemetry, Prometheus, or other standard formats.
- Backend: Storage and visualization for metrics, traces, profiles, logs, and security events.
Common tools include bpftrace for quick investigations, BCC for scripted tooling, libbpf for production agents, Cilium for networking and security, Pixie for Kubernetes-native observability, Parca for continuous profiling, and Grafana Beyla for auto-instrumentation. Many platforms now embed eBPF collectors and export to OpenTelemetry.
High-Value Use Cases
1. Service-Level Latency Without Code Changes
eBPF can observe request latency at the kernel boundary. By attaching to socket operations, TLS uprobes, or syscall entry and exit, an agent can measure how long a request spends in the network stack or in a service. This can produce RED metrics – rate, errors, and duration – for services that were never instrumented.
A simple bpftrace one-liner can count syscalls by process:
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { @[comm] = count(); }'
That is only a starting point. Production agents correlate events with request IDs, container IDs, and Kubernetes metadata to build service-level views.
2. Network Flow and Dependency Mapping
eBPF programs attached to TC or XDP can inspect packets at high speed. Socket-level programs can observe TCP connections, retransmits, DNS queries, and TLS handshakes. When combined with Kubernetes metadata, this data becomes a live service dependency map.
- Identify unexpected east-west traffic.
- Measure retransmits and connection failures per service.
- Detect DNS latency before it becomes an application timeout.
- Map which pods communicate with external endpoints.
3. Continuous Profiling
Continuous profiling samples stack traces across the fleet to show where CPU time is spent. eBPF makes this possible without injecting a profiler into every application process. It can capture on-CPU stacks, off-CPU waits, memory allocations, and lock contention. The result is a flame graph that points to the exact function, library, or kernel path causing a bottleneck.
4. Runtime Security and Anomaly Detection
Security teams use eBPF to observe process execution, file access, privilege changes, and network connections. Because eBPF runs at the kernel level, it is harder for user-space malware to evade. Common detections include reverse shells, crypto miners, suspicious container escapes, and unexpected writes to sensitive files.
Projects like Falco and Tetragon use eBPF to enforce and alert on runtime policies. Observability and security then share the same low-level event stream.
5. Kubernetes-Aware Context
Kernel events are not automatically Kubernetes-aware. A PID or cgroup ID must be mapped to a pod, namespace, deployment, and node. eBPF agents perform this enrichment by reading cgroup paths, container runtime metadata, and the Kubernetes API. Without this step, telemetry is just a stream of anonymous PIDs.
Architecture Blueprint for Production
A reliable eBPF observability architecture should be designed like any other distributed data pipeline.
- Agent per node: Run a DaemonSet or systemd service on every node. Load only the programs needed for current policies. Use ring buffers for event delivery and maps for aggregation.
- Local aggregation: Aggregate counters, histograms, and latency summaries before export. Sending every syscall event to a central backend is rarely sustainable.
- Enrichment: Add Kubernetes labels, process names, container images, and cloud metadata close to the source.
- Export: Emit OpenTelemetry Protocol, Prometheus remote write, or another standard format. Keep the agent protocol-agnostic where possible.
- Backend: Store metrics, traces, profiles, and security events in systems that support high-cardinality dimensions and efficient querying.
- Control plane: Provide remote configuration for sampling rates, program enablement, and policy updates. Never require SSH access to change observability behavior.
Performance and Overhead: What to Expect
eBPF overhead depends on hook frequency, program complexity, event volume, and how much data is copied to user space. A well-written agent might use 1-5% of a node CPU for baseline telemetry. High-frequency network or syscall programs can use more, especially if every event is sent to user space.
- Measure before and after: Benchmark with production-like load. Compare CPU, memory, network, and application latency.
- Use sampling and aggregation: Count in kernel maps instead of streaming every occurrence.
- Keep programs small: The verifier limits complexity. Large programs also increase instruction cache pressure.
- Avoid high-cardinality maps: Unbounded keys can exhaust memory. Use LRU maps or pre-aggregate by service, pod, or operation.
- Watch ring buffer pressure: Dropped events usually mean the user-space reader is too slow or the buffer is too small.
Security, Permissions, and Compliance
eBPF is powerful, which means it must be governed. Loading eBPF programs typically requires elevated capabilities such as CAP_BPF, CAP_PERFMON, or CAP_SYS_ADMIN depending on kernel version and program type. Unprivileged eBPF is disabled by default on most production systems for good reason.
- Least privilege: Grant only the capabilities needed by the agent. Use separate service accounts and node pools where possible.
- Lock down tooling: bpftrace and BCC are excellent for debugging, but they should not be available to every user in production.
- Audit program loads: Monitor who loads eBPF programs and what hooks they attach to.
- Protect data privacy: Kernel-level observability can capture file paths, process arguments, and network payloads. Define redaction and retention policies before enabling broad collection.
- Verify supply chain: Treat eBPF agents and programs as privileged code. Pin versions, verify signatures, and scan dependencies.
Common Pitfalls and How to Avoid Them
- Kernel version drift: Different nodes may run different kernels. Use CO-RE and BTF, and test across your fleet before rollout.
- Cardinality explosion: Adding pod name, request path, and user ID to every metric can overwhelm backends. Aggregate early and sample selectively.
- Missing process context: Without cgroup and namespace mapping, you cannot reliably attribute events to services.
- Over-reliance on syscalls: Not every request maps cleanly to a syscall. TLS libraries, async runtimes, and shared memory can hide activity. Combine eBPF with application traces when possible.
- Running everything in production first: Start in staging, compare against existing telemetry, and roll out by namespace or node pool.
Getting Started: A Practical Roadmap
- Start with questions: Choose one high-value problem, such as unexplained latency or missing service dependencies.
- Use bpftrace for one-off investigations: Validate that the kernel can see the events you need.
- Move to a production agent: Select a tool that supports CO-RE, Kubernetes enrichment, and standard export formats.
- Add Kubernetes context: Map PIDs and cgroups to pods, namespaces, and deployments.
- Define SLOs and alerts: Turn eBPF data into actionable metrics, not just dashboards.
- Govern access and data: Document capabilities, retention, redaction, and approval workflows.
The Future of Kernel-Level Observability
eBPF is becoming a default layer in cloud-native platforms. Expect tighter integration with OpenTelemetry, more standard semantic conventions for kernel events, and broader support for continuous profiling and runtime security. eBPF is also expanding beyond Linux, with Windows eBPF and cross-platform runtimes maturing.
The long-term value is not a single tool. It is a shared, low-overhead event substrate that multiple systems – observability, security, networking, and cost management – can use without reinstrumenting every application.
Conclusion
eBPF observability gives engineering teams kernel-level visibility without forcing changes to application code. It is especially valuable for cloud-native environments where services are ephemeral, polyglot, and heavily networked. The best results come from treating eBPF as one signal in a broader observability strategy: start small, aggregate aggressively, enrich with Kubernetes context, and govern privileged access carefully.
Used well, eBPF turns the kernel from a black box into a trustworthy source of production truth.

