---
title: eBPF agent best practices guide
source: https://docs.newrelic.com/docs/ebpf/best-practices
---

New Relic eBPF agent uses eBPF technology to provide APM functionality in a single agent with zero code instrumentation. This approach empowers platform engineering teams by eliminating the need for coordination with application teams for monitoring deployment.

## When to use eBPF APM [#when-to-use-eapm]

-   **Large-scale deployments:** When you have many applications that need monitoring deployed at scale and require "good enough" metrics without the overhead of individual language agents.
-   **Unknown or unmodifiable workloads:** When the workload you want to monitor is written in an unknown programming language and/or cannot be modified.
-   **Platform engineering efficiency:** When you want to deploy monitoring at scale without coordinating with individual application teams.
-   **Linux-focused environments:** When you don't need to monitor Windows platforms, as eBPF works excellently on Linux in both Kubernetes and host environments.
-   **No distributed tracing requirement:** When your monitoring needs don't require distributed tracing capabilities.

### eBPF vs traditional APM comparison [#comparison]

Understanding the differences between eBPF APM and traditional APM agents helps you choose the right approach:

| Functionality                                | eBPF APM                                  | APM agent |
| -------------------------------------------- | ----------------------------------------- | --------- |
| Summary                                      | ✅                                         | ✅         |
| Transaction                                  | ✅ (segment linking for Java, Go, Node.js) | ✅         |
| Database operations                          | ✅                                         | ✅         |
| Service map                                  | ✅                                         | ✅         |
| Distributed tracing                          | ❌                                         | ✅         |
| Programming language agnostic                | ✅                                         | ❌         |
| Custom instrumentation                       | ❌                                         | ✅         |
| Auto-discover apps and services continuously | ✅                                         | ❌         |
| Linux support                                | ✅                                         | ✅         |
| Windows support                              | ❌                                         | ✅         |
| TCP and DNS telemetry                        | ✅                                         | ❌         |

### Data source perspective

eBPF APM shifts the monitoring perspective from the application layer to the kernel layer:

| Feature             | APM language agent                               | eBPF APM                                                  |
| ------------------- | ------------------------------------------------ | --------------------------------------------------------- |
| Data source         | Application's memory / runtime hooks             | Linux kernel (via eBPF)                                   |
| Language dependency | High (requires specific agent for each language) | None (operates on kernel's view of process)               |
| Code modification   | Required                                         | Not required (observes process from outside)              |
| Outcome             | Deep insight for known languages                 | Great insight for any workload on Linux (C++, Rust, etc.) |

## Best practices for deployment [#deployment-best-practices]

### Supplement the traditional APM

Use eBPF agent to supplement APM language agents for comprehensive coverage. This gives you full APM coverage with coexistence between eBPF APM and APM agents, without double data ingestion.

**Recommended approach:**

-   **APM language agents:** Use for your most critical applications that require deep-level insights, distributed tracing, or custom instrumentation.
-   **eBPF APM:** Use to cover everything else, including uninstrumented services, third-party apps, and for continuously discovering/reporting new services.

### Add network metrics for deeper context

The eBPF agent can also provide granular network metrics (TCP, DNS, etc.) to give you visibility outside your application's boundary. This capability is complementary and can be used with or without eBPF APM. For more information, refer to [network-metrics](https://docs.newrelic.com/docs/ebpf/network-metrics/).

The following deployment options are available:

| Application metric source | Network metric source                  | Configuration |
| ------------------------- | -------------------------------------- | ------------- |
| APM language agent        | eBPF agent (network metrics only mode) | Two agents    |
| eBPF APM                  | eBPF agent (same agent)                | Single agent  |

### Add log collection for complete MELT

The eBPF agent can also collect application logs and enrich them with New Relic metadata by default, without deploying a separate log forwarder. This capability runs on the same agent, so you can turn it on alongside eBPF APM and network metrics without deploying anything extra. For more information, refer to [eBPF logs](https://docs.newrelic.com/docs/ebpf/logs/).

Use `reportLogs: "auto"` to avoid duplicate log collection automatically: the eBPF agent backs off from an APM agent only if that agent is actively collecting logs itself, and backs off entirely whenever an OpenTelemetry agent is attached. Use `"true"` only when you've confirmed no other agent is reporting logs for that entity.

## Implementation recommendations [#implementation-recommendations]

-   **Start with eBPF APM for scale:** If you need to deploy monitoring at scale across many applications and want "good enough" metrics without complex coordination, start with eBPF APM.

-   **Add network metrics for complete visibility:** Once eBPF APM is deployed, consider adding eBPF network metrics to gain visibility beyond application boundaries for comprehensive troubleshooting capabilities.

-   **Add log collection for unified troubleshooting:** Once you're ready, turn on eBPF logs to collect application logs without deploying a separate log forwarder.

## Data sampling and fine-tuning [#data-sampling]

APM language agents cap **transaction events** with a fixed reservoir, by default **10,000 events per minute** (configured with `transaction_events.max_samples_stored`). The eBPF agent does not use a single fixed per-minute limit. Instead, it samples each telemetry type differently, so understanding how each type behaves helps you control data volume and cost without losing the signals you care about.

| Data type                                 | Sampled?            | Controls                                                      | Default                                       |
| ----------------------------------------- | ------------------- | ------------------------------------------------------------- | --------------------------------------------- |
| Metrics (throughput, latency, error rate) | No, always complete | `protocols.<protocol>.enabled`                                | Enabled per protocol                          |
| Spans                                     | Yes, by threshold   | `samplingLatency`, `samplingErrorRate`                        | `p50` latency                                 |
| Unlinked spans (no parent)                | Yes, capped         | `max_unlinked_spans`, `unlinked_spans_error_quota_percentage` | `100` per protocol, `30`% reserved for errors |
| Logs                                      | Yes, reservoir      | `maxSamplesPerMinute`                                         | `10000` per minute                            |

> #### ⚠️ IMPORTANT
>
> Metrics are never sampled, throughput, latency, and error-rate dashboards stay accurate even when spans are aggressively sampled. Span sampling only affects the individual traces you can inspect, not the aggregate metrics.

### How span sampling works [#span-sampling]

The eBPF agent does not limit spans to a fixed number per minute. For each protocol, it exports only the spans that cross a threshold you set:

-   **Latency threshold** (`samplingLatency`): exports spans slower than the chosen percentile for a given route. The default is `p50` (the median). Raise it toward `p90` or `p99` to keep only the slowest tail and reduce data volume; lower it toward `p1` or `p0` to keep nearly all spans and increase visibility. Any percentile from `p0` to `p99` is accepted.
-   **Error-rate threshold** (`samplingErrorRate`, HTTP): a value from `1` to `100`. When a route's error rate exceeds this threshold, spans for that route are exported so failures are never sampled away. Leave it empty to disable error-based export.

### Controlling unlinked spans [#unlinked-spans]

Spans that the agent captures but cannot associate with a parent are called _unlinked_ spans. They are capped per protocol by `max_unlinked_spans` (default `100`; set to `0` to disable the cap). The `unlinked_spans_error_quota_percentage` setting (default `30`) reserves part of that budget for error spans, so failures stay visible even when normal spans arrive first.

### Tuning examples [#tuning-examples]

Sampling is configured in the Helm `values.yaml` file (Kubernetes) or in `/etc/newrelic-ebpf-agent/newrelic-ebpf-agent.yaml` (Linux host). The keys are identical for both.

```yaml
protocols:
  global:
    max_unlinked_spans: 100          # 0 disables the cap
    unlinked_spans_error_quota_percentage: 30
  http:
    enabled: true
    spans:
      enabled: true
      samplingLatency: "p90"         # keep only slower requests, less data
      samplingErrorRate: "5"         # always keep routes with >5% errors
logDataFilters:
  applicationLogReporting:
    maxSamplesPerMinute: 10000         # APM-equivalent reservoir for logs
```

### Recommendations [#sampling-recommendations]

-   **To maximize trace visibility:** lower `samplingLatency` toward `p0` and set a low `samplingErrorRate`, but expect higher ingest.
-   **To reduce data:** raise `samplingLatency` (for example, `p90` or `p99`), disable unwanted protocols all together (or just `spans.enabled: false` to keep the protocol metrics only), and lower `maxSamplesPerMinute` for logs.
-   **Keep metrics in mind:** metrics are unaffected by span sampling. Disable an entire protocol only when you don't need its data at all.

## Related articles [#related-articles]

[eBPF Kubernetes installation](https://docs.newrelic.com/docs/ebpf/k8s-installation/)

Learn how to set up the New Relic eBPF agent for your Kubernetes cluster.

[eBPF Linux installation](https://docs.newrelic.com/docs/ebpf/linux-installation/)

Learn how to set up the New Relic eBPF agent for your Linux host.

[eBPF logs](https://docs.newrelic.com/docs/ebpf/logs/)

Learn how to collect application logs with the New Relic eBPF agent.

[Troubleshooting eBPF](https://docs.newrelic.com/docs/ebpf/troubleshooting/no-ui-data/)

Learn how to troubleshoot issues with the New Relic eBPF agent.
