Grafana Beyla: Auto-Instrumentation Without Touching Code
Table of contents
- Key takeaways
- What Beyla does
- How it works: the eBPF model
- Kubernetes installation
- Supported languages
- Beyla vs SDK: when to use each
- Integration with the Grafana stack
- Honest limitations
- Real measured overhead
- Incremental adoption path
- Conclusion
- Frequently asked questions
- How much overhead does Beyla add to production applications?
- Does distributed tracing work with Beyla if I don't touch the code?
- What permissions and kernel does Beyla need on Kubernetes?
- Sources
Grafana Beyla is an eBPF agent that automatically instruments existing applications without touching their code: it observes kernel syscalls and generates OpenTelemetry traces and RED metrics for services written in Go, Java, Python, Node, and Rust. It gives broad, immediate coverage, but it does not replace the manual SDK for business metrics and internal logic.
Grafana Beyla[1] solves a classic observability problem: how to instrument legacy or third-party apps without touching source code. Instead of requiring code changes plus SDK integration, Beyla observes syscalls via eBPF and automatically generates OpenTelemetry traces for Go, Java, Python, Node, and Rust, without a single line added to the application.
Key takeaways
-
A single agent per node (DaemonSet in K8s) instruments all apps without requiring code changes.
-
Generates RED metrics (rate, errors, duration) and OTLP spans compatible with any OTel backend.
-
Measured overhead: 0.5-2% additional CPU per agent and ~50-100 MB memory; low enough for production.
-
Distributed context propagation only works if the app forwards W3C TraceContext headers.
-
It cannot see business metrics or internal logic: the manual SDK remains essential for that.
What Beyla does
-
Auto-instrumentation of HTTP/gRPC requests.
-
Generates OTel spans with service name, method, status code, and latency.
-
Exports OTLP to any compatible backend (Tempo, Jaeger, Datadog).
-
Multi-language: compiled (Go, Rust) and interpreted (Python, Node).
-
DNS tracking and SQL tracking (limited).
How it works: the eBPF model
[App A] [App B] [App C]
| /
(syscalls)
| /
[Beyla eBPF agent]
↓ OTLP
[OTel Collector / Grafana Tempo]
Beyla runs as a DaemonSet (one pod per node) and observes traffic from all applications on the same node via eBPF programs attached to network interfaces and kernel syscalls. Requires kernel 5.8+ (recommended) and containers with elevated privileges.
Kubernetes installation
helm repo add grafana https://grafana.github.io/helm-charts
helm install beyla grafana/beyla
--set env.BEYLA_AUTO_INSTRUMENT_TARGET=my-service
--set env.OTEL_EXPORTER_OTLP_ENDPOINT=http://tempo:4317
Alternative manual configuration:
service_name: my-api
discovery:
services:
- open_ports: 8080
- exe_path: ".*/my-api"
otel_traces_export:
endpoint: http://tempo:4317
protocol: grpc
otel_metrics_export:
endpoint: http://mimir:4317
Apps are targeted by port, executable path, or Kubernetes labels.
Supported languages
-
Go: excellent, native, with deep visibility.
-
Rust: good.
-
C/C++: functional.
-
Java: basic HTTP (Java agent gives richer auto-instrumentation).
-
Python: requests, aiohttp, Django.
-
Node.js: http, express, fetch.
-
.NET: basic.
For Go and Rust, Beyla approaches the coverage of a manual SDK. For the rest, it complements without replacing.
Beyla vs SDK: when to use each
| Aspect | Beyla (eBPF) | Manual SDK |
|---|---|---|
| Code changes | None | Required |
| Granularity | Call boundaries | Business logic |
| Context propagation | Header-based | Explicit |
| Business metrics | No | Yes |
| Async distributed tracing | Limited | Full |
| Performance overhead | 1-3% | 1-5% |
Beyla shines as a first step, with legacy apps, and for quick wins in broad coverage. The SDK is essential for rich business-level observability. Using both is the most common production pattern, as described in the OpenTelemetry unification article: Beyla for broad coverage, SDK for critical apps with deep instrumentation.
Integration with the Grafana stack
Recommended full stack:
-
Beyla on each node → OTLP.
-
Grafana Alloy (optional) as intermediate collector.
-
Grafana Tempo for traces.
-
Grafana Mimir / Prometheus for metrics.
-
Grafana for visualisation.
The Service Graph is generated automatically from Beyla data. It also pairs with a well-configured alerting setup; see the SLOs and error budgets with Prometheus article for defining correct thresholds on these RED metrics.
Honest limitations
-
Limited context propagation if the app doesn’t forward W3C TraceContext headers.
-
Internal app spans invisible: Beyla only sees ingress/egress.
-
Business metrics impossible: Beyla only observes syscalls.
-
HTTPS: Beyla doesn’t decrypt (sees only TLS metadata).
-
Kernel requirements: 5.8+ recommended.
-
Considerable security surface: privileged container, HostPID, HostNetwork. Strict RBAC is mandatory.
Real measured overhead
-
CPU: 0.5-2% per Beyla agent.
-
Memory: ~50-100 MB.
-
Network: minimal (OTLP compressed).
-
Latency on apps: <1 ms added.
Low enough for production on most workloads.
Incremental adoption path
-
Deploy Beyla in staging observing some services.
-
Validate overhead and data quality.
-
Extend cluster-wide.
-
Compare with SDK on already-instrumented apps to identify coverage gaps.
-
Decide which apps keep both and which use only Beyla.
Rollback is immediate: no changes to the apps.
Conclusion
Grafana Beyla is the ideal tool to kickstart observability without a long instrumentation project. For Go apps and legacy services, the value is immediate. For modern apps with a proper SDK, Beyla complements without replacing. The Beyla + OTel SDK combination covers the full observability spectrum with minimum accumulated effort.
For teams on the Grafana stack, it is a natural addition. For Datadog or New Relic teams, Beyla’s OTLP output is fully portable.
This article is also available in Spanish.
Sources:
- Grafana Labs: official Grafana Beyla page[1]
- Grafana Beyla: repository and documentation on GitHub[2]
- ebpf.io: what eBPF is and how it works[3]
- OpenTelemetry: traces (spans) documentation[4]
- W3C: Trace Context specification (header propagation)[5]
Frequently asked questions
How much overhead does Beyla add to production applications?
Measured overhead is 0.5-2% additional CPU per agent, roughly 50-100 MB of memory, minimal network traffic because OTLP is compressed, and under 1 ms of added latency on the apps. That is low enough for production on most workloads, and rollback is immediate because nothing changes in the applications themselves.
Does distributed tracing work with Beyla if I don't touch the code?
Only partially. Context propagation is header-based, so distributed traces are only linked if the application forwards the W3C TraceContext headers. Beyla sees only ingress and egress, not the app's internal spans, and async distributed tracing is limited. For business logic, business metrics and full async traces the manual OpenTelemetry SDK remains essential.
What permissions and kernel does Beyla need on Kubernetes?
Beyla runs as a DaemonSet, one pod per node, and requires kernel 5.8+ (recommended) plus containers with elevated privileges: a privileged container, HostPID and HostNetwork. That is a considerable security surface, so strict RBAC is mandatory. It installs with Helm from the grafana/beyla chart, and apps are targeted by port, executable path or Kubernetes labels.