Every application agent and telemetry shipper you run competes with production workloads for node resources, and each one is another Helm chart to version, another upgrade cycle to schedule, another compatibility surface to re-check each upgrade cycle. Most eBPF vs traditional APM evaluations start with that operational load rather than a feature checklist.
The two approaches differ in where collection happens. Traditional APM agents run in user space inside each application process as per-language SDKs or injected agents. An eBPF sensor runs sandboxed programs inside the Linux kernel and observes every process on the node from below. Kernel-space collection buys you zero-code visibility into every service on the cluster from a single deployment. It costs you application-level trace context: most eBPF sensors cannot inject or extract W3C Trace Context headers, so they cannot stitch a distributed trace across service boundaries the way an in-process SDK can.
eBPF vs traditional APM at a glance
Platform teams usually compare eBPF vs traditional APM on the dimensions below.
How each approach collects telemetry
The split is physical. eBPF programs observe syscalls, network traffic, and function calls from inside the kernel for every process on a node. APM agents observe function calls from inside each application process, which is why they need a presence in every service.
How eBPF works inside the Linux kernel
eBPF programs attach to kernel hooks:
- kprobes on kernel function entry and exit
- uprobes on user-space functions
- tracepoints at static kernel instrumentation points
- syscall interfaces
Before any program loads, the eBPF verifier rejects unbounded loops and out-of-bounds memory access; the kernel JIT-compiles accepted programs to native instructions.
This is why eBPF is safe to run in production kernels without loading kernel modules or modifying kernel source, and why the per-hook cost is small. The Linux kernel documentation puts an optimized kprobe at roughly 0.07–0.1 microseconds per hit.
groundcover's Flora eBPF sensor uses these hooks to inspect every packet a service sends and receives, classify it by protocol, and reconstruct HTTP and SQL transactions. One Flora pod per node captures traces, metrics, logs, and Kubernetes events for everything running on that node.
How traditional APM agents instrument code
Traditional APM puts instrumentation inside the application. Datadog ships tracing libraries for nine server-side APM languages, each with its own version matrix and update cycle. Dynatrace OneAgent uses process injection to auto-instrument supported runtimes. New Relic offers per-language agents plus Pixie and a Kubernetes auto-attach operator, and you have to work out which fits each workload.
Getting these agents into a service means SDK integration, language-specific configuration, and usually a restart.
Zero-code instrumentation vs per-service agents
An eBPF DaemonSet sees every request on the node the moment a pod schedules, with no SDKs, no restarts, and no sampling. groundcover's APM documentation says Flora captures 100% of requests at the kernel level with zero code changes. A platform team can complete a POC in a single day, with full-cluster visibility within hours.
Per-service instrumentation makes the platform team dependent on application teams. Every new service needs an SDK added, configured, and maintained by the developers who own the code, so visibility lags deployment by however long that coordination takes. The lock-in compounds: once @sentry/node or sentry-python is instrumented across a hundred services, switching means re-instrumenting all of them.
In-process agents also carry in-process risk. Dynatrace OneAgent earns praise as install-and-forget for supported runtimes, but process injection still adds another moving point inside the workload.
Performance overhead compared
groundcover published a head-to-head benchmark in April 2023: a Go HTTP server under a constant 3,000 requests per second on an isolated Kubernetes cluster.
- Flora added 9% CPU and 0% memory overhead.
- The Datadog agent added 249% CPU and 227% memory.
- The OpenTelemetry collector added 59% CPU and 27% memory.
- The Pixie agent added 32% CPU and 9% memory.
Those results are the source of the figures groundcover still publishes: Flora consumed 73% less CPU than Datadog and 96% less memory than Pixie. groundcover documents the methodology, but the benchmark is vendor-run with a single workload type, and no independent replication exists, so treat it as directional rather than definitive.
Independent evidence supports the direction while showing that eBPF overhead depends heavily on implementation:
- DoorDash: Its internal eBPF DaemonSet, BPFAgent, consumes under 0.3% of a typical node's CPU and memory.
- Datadog itself: Replacing its user-space connection tracker with eBPF cut that component's CPU usage by about 35% internally.
- Grafana Beyla: A reproducible February 2026 benchmark measured a ~24% throughput drop and p95 latency rising from 11.09 ms to 14.16 ms with Beyla enabled, driven by capture, protocol parsing, and span construction.
On the traditional side, the cost shows up inside the request path. Datadog's official APM figures show the trace agent scaling from 0.05 cores at 2,000 spans per second to 2.0 cores at 130,000, and the agent is CPU-bound: throttling it can cause OOM kills.
What eBPF can and cannot see
eBPF operates at the kernel and network layer, and outside a narrow opt-in path in Beyla it cannot inject or extract the W3C traceparent and tracestate headers that distributed tracing depends on. Without those correlation identifiers, the sensor cannot stitch kernel-captured spans into an end-to-end trace across service boundaries. The OpenTelemetry project states the limit plainly in its OBI documentation: "OBI does not replace language-level instrumentation in every scenario. Use language agents or manual instrumentation when you need custom spans, application-specific attributes, business events, or other in-process telemetry that eBPF-based instrumentation cannot derive automatically."
Grafana donated Beyla to OpenTelemetry as OBI, and Beyla is the one eBPF tool that documents traceparent injection. Its own docs show how narrow the path is. Beyla disables network-level injection by default, rewrites plaintext HTTP packets via traffic control programs, and falls back to TCP/IP packet-level propagation for HTTPS/TLS traffic between OBI/Beyla-instrumented services. The Go-specific alternative writes into process memory with bpf_probe_write_user, requires CAP_SYS_ADMIN, and stops working under kernel lockdown, as documented in OBI distributed traces.
The visibility ceiling extends beyond context propagation:
- Application internals: eBPF cannot see business logic, custom span attributes, or internal call stacks without uprobes targeting known function signatures. Dynatrace PurePath and IBM Instana's line-of-code tracing operate at a depth kernel-level capture cannot reach.
- Continuous profiling: groundcover does not currently document profiling, while Pixie, Coroot, and the OpenTelemetry eBPF Profiler offer it.
groundcover's position follows from these limits: eBPF enriches OpenTelemetry rather than replacing it. Flora provides the kernel-level baseline for every service, and groundcover ingests OTel spans as a first-class data source for the services where application-level context matters.
Unique eBPF capabilities
Kernel-level collection also sees things user-space agents structurally cannot, because it sits below every process on the node:
- Network telemetry without a separate product: TCP/DNS flow data comes from the same sensor. Datadog sells Cloud Network Monitoring as a distinct product.
- Auto-generated service maps: groundcover builds dependency maps from eBPF topology data at deployment, with no instrumentation defining the edges.
- Continuous profiling without instrumentation: Coroot, Pixie, and the OpenTelemetry eBPF Profiler derive CPU flame graphs from kernel-level sampling with no profiler inside the process.
- HTTP and SQL transaction reconstruction: Flora reconstructs HTTP and SQL transactions at the kernel level.
- Kubernetes event correlation: Flora collects Kubernetes events natively alongside traces, logs, and metrics, so a pod eviction sits in the same store as the latency spike it caused.
Agent sprawl and operational complexity
The multi-agent stack has a measurable footprint before it has any value. One agent analysis of typical enterprise Kubernetes agents, from CNI through mesh and telemetry components, totals roughly 910m CPU and 1.4 GB RAM per node, about 23% of an m5.xlarge's capacity before the first application pod schedules.
A single agent requesting 256Mi across 100 nodes locks up 25 GiB of cluster memory on its own. The CNCF's 2021 observability microsurvey found 72% of organizations run up to nine observability tools and 23% run ten to fifteen.
Each agent adds an upgrade surface. Datadog's nine server-side APM language SDKs each carry their own compatibility matrix. A self-managed Grafana LGTM stack means coordinating the LGTM components as separate systems with three query languages. Each upgrade cycle adds compatibility surface across all of it.
The eBPF model collapses that surface to one deployment. Flora is a single DaemonSet covering all signal types, so one Helm release and one upgrade cycle replace the APM agent, log shipper, and metrics exporter. TRM Labs took this path, replacing Datadog and Splunk with groundcover and consolidating collection onto eBPF, as documented on TRM's engineering blog.
Kubernetes and cloud-native fit
A DaemonSet scales with node count, not pod count. Sidecar-based collection scales the other way: 5,000 pods means 5,000 sidecars, and a sidecar analysis puts the collection footprint at 250 CPU cores and 250 GB of RAM when each sidecar uses 50m CPU and 50Mi. Node-scoped eBPF collection also removes the coverage lag.
When a team spins up a new namespace or deploys a new service, Flora on that node sees its traffic immediately; no one updates configuration, and no workload waits for instrumentation. Ephemeral workloads that would go unmonitored under a per-service model are visible from their first request.
Deployment requirements and blockers
Check kernel version, BTF support, privileged-container policy, and platform support before a proof of concept.
- Kernel version: groundcover requires Linux kernel 5.3 or newer with BTF enabled; its kernel requirements tell you to check for /sys/kernel/btf/vmlinux on your nodes. The "4.16+" figure in older articles is outdated. Pixie runs on 4.14 without BTF; Beyla needs 5.8 with BTF. Amazon Linux 2 nodes (kernel 4.14) fail the BTF-based requirements.
- Privileges: loading eBPF programs requires privileged containers. CAP_BPF and CAP_PERFMON have existed since kernel 5.8, but most production tools still request CAP_SYS_ADMIN because uprobe-based TLS capture requires it and because Debian-based distros, including default AKS and EKS worker nodes, set perf_event_paranoid high enough to force it anyway.
- Security review: the DaemonSet runs with hostPID: true, which triggers Elastic Security runtime alerts in clusters running Elastic Defend. The sensor holds what amounts to god mode over every node in the cluster. Treat it like CNI-level infrastructure in your review, because that is the trust level it operates at.
- Platform support: Standard Linux nodes on EKS and AKS work; GKE standard nodes work too. AWS Fargate restrictions state that "Daemonsets aren't supported on Fargate," and neither are privileged containers. GKE Autopilot moved from a blanket block to a partner allowlist in 2025, with customer-defined allowlists arriving in GKE 1.35, so verify your tool's status before deploying there. Windows and macOS nodes are out of scope entirely; eBPF for Windows remains a pre-release work in progress.
eBPF monitoring tools compared
Platform teams usually compare two groups: eBPF-native platforms and traditional APM vendors that use eBPF for supplementary signals.
The incumbents' eBPF usage is worth reading precisely. Datadog, Dynatrace, and Splunk all use eBPF for network-layer visibility while keeping SDK or process-injection instrumentation as the primary path. Only the eBPF-native tools use the kernel as the primary telemetry source.
Which should you choose?
Use workload shape to choose between the two models.
Choose eBPF-based monitoring if:
- You run Kubernetes-heavy, Linux-based workloads where a DaemonSet is deployable
- You want visibility into every service without SDK integration or app-team coordination
- You need to minimize the CPU and memory that observability takes from production workloads
- You want to replace the APM agent, log shipper, and metrics exporter with one deployment
- You have data residency requirements; groundcover's BYOC model (Bring Your Own Cloud, meaning the data plane runs in your own cloud account) keeps all telemetry in your VPC
Choose traditional APM if:
- You need deep distributed tracing with W3C Trace Context propagation across service boundaries
- You run Windows, macOS, mainframe, or serverless workloads; Fargate and Cloud Run cannot host eBPF sensors
- You need code-level tracing to individual lines (IBM Instana, Dynatrace PurePath)
- Continuous profiling is a first-class requirement and your chosen eBPF tool lacks it (groundcover does not currently document profiling; Coroot, Pixie, and the OpenTelemetry eBPF Profiler do)
Hybrid: running eBPF alongside APM
You do not have to pick one. groundcover ingests OpenTelemetry spans alongside Flora's eBPF signals in the same interface, so services already instrumented with OTel SDKs keep their application-level trace context while eBPF supplies kernel context for everything else. The CNCF recommends exactly this sequencing: "Starting with zero-code auto-instrumentation to establish an immediate telemetry baseline, followed by progressive layering of manual instrumentation where deep context is required for business logic and high-value custom domains."
In practice the migration runs in phases. Deploy the eBPF DaemonSet for baseline coverage of every service, keep OTel SDKs on the handful of services that need custom spans and business attributes, and retire per-service agents everywhere else as coverage is confirmed. If you want to validate the model on your own cluster, groundcover's free tier runs the full BYOC architecture with no host or seat limits, no credit card, and 12-hour retention, so you can deploy Flora on one cluster and check the coverage claims against your own workloads.







