Collector Comparison: Grafana Alloy, ADOT, and OTel¶
Choosing between Grafana Alloy, ADOT, and the OpenTelemetry (OTel) Collector involves balancing vendor neutrality against operational power. Since SRE is already leaning toward Alloy, the "gravity" is strong, and for good reason: Alloy is effectively a "super-distribution" that wraps the OTel Collector engine while adding a programmable configuration layer.
Comparison Matrix¶
| Dimension | Grafana Alloy | AWS Distro (ADOT) | Upstream OTel Collector |
|---|---|---|---|
| Syntax | River (HCL-like): Programmable, supports variables and logic. | YAML: Static, declarative, and linear pipelines. | YAML: Static, industry standard for OTel. |
| Image Size (compressed/uncompressed) | 218/535 MB | 52/202 MB | Core: 40/172 MB, Contrib: 98/360 MB |
| Scaling | Native Clustering: Built-in workload distribution for scraping. | Managed via EKS/ECS or OTel Operator. | Typically requires OTel Operator for scaling. |
| OTel Parity | High: Wraps the otelcol engine; supports most components. |
High (AWS Focused): Lags slightly behind upstream; focuses on AWS stability. | Reference: The standard for all new OTel features. |
| Best For | Teams using the LGTM stack (Loki, Grafana, Tempo, Mimir). | AWS-heavy environments (X-Ray, CloudWatch, Lambda). | Vendor-neutral or multi-cloud strategies. |
Installation & Integration (Alloy vs ADOT)¶
Some of the first beta-testing teams have used ADOT for sending their metrics. In theory ADOT could be easier to install for AWS native teams/services. However, these might not be relevant for our platform. We will discuss them here.
A. Managed EKS Add-ons¶
- ADOT: Can be installed via the AWS Console or CLI as a managed add-on (
aws eks create-add-on). AWS handles the versioning, updates, and underlying IAM permissions. - Alloy: Must be deployed as a standard third-party application using Task definitions, Helm or Kubernetes manifests. The team is responsible for lifecycle management.
This might only be an advantage for EDPP, using EKS, in every other use-case, ADOT is also ran as third party application.
B. Lambda Layers¶
- ADOT: Provides pre-packaged Lambda Layers. You simply add the ARN to your function, and it automatically instruments the runtime and starts a collector extension.
- Alloy: To use Alloy with Lambda, you must either route OTLP data to a central Alloy instance or package a custom extension.
This could definitely be an advantage for some of our lambda intensive applications. However, we would have to test this first, not really familiar with the possibilities.
C. ECS & Fargate Integration¶
- ADOT: Integrated directly into ECS Task Definitions with a "sidecar" checkbox. It automatically handles SigV4 signing for AWS backends. Note: this is only possible in the AWS console.
- Alloy: Requires manual sidecar container definition in the Task Definition and manual configuration of AWS authentication (though standard IAM roles still work).
Authentication is not required in our setup, as only network access is a pre. Defining manual sidecar containers is a normal practice at KNMI, so shouldn't be that difficult to learn.
Key Dimensions Deep Dive¶
1. Syntax & Programmability¶
The shift from YAML to River is the most significant change. While YAML is familiar, it can become brittle in complex environments.
- Alloy (River): Operates as a Directed Acyclic Graph (DAG). You define a component once and "plug" its output into multiple other components. It feels more like writing code (Terraform-style) than editing a text file.
- OTel/ADOT: Uses a rigid
receivers -> processors -> exportersflow. If you want to send the same data to two places with different processing, you often have to duplicate blocks.
2. Ease of Migration¶
The path from ADOT/OTel to Alloy is low-friction due to two key features:
- The
convertTool: You can runalloy convert --source-format=otelcolto automatically generate a River configuration from your existing OTel YAML. - Native YAML Support: Alloy includes an
otelsubcommand. You can runalloy otel --config config.yaml(experimental) and it will execute your native OTel configuration without any changes, allowing for a "lift-and-shift" before refactoring.
3. Image Size & Resource Footprint¶
- Alloy is optimized to replace multiple agents (Promtail, Prometheus Agent, and OTel Collector).
- ADOT is a "fat" binary because it includes specialized AWS SDKs. If you aren't using those specific AWS backends, it is unnecessary weight.
Feature Support Comparison Matrix¶
| Feature | OTel Collector | AWS Distro (ADOT) | Grafana Alloy |
|---|---|---|---|
| Tracking Upstream | Reference implementation | Lagging ~1-2 minor releases | Lagging ~1 minor release |
| Component Pool | 100% of Core & Contrib | Curated subset (AWS-focused) | Curated subset (Grafana & OTel) |
| Traces, Metrics, Logs | Native & Stable | Native & Stable | Native & Stable (wraps OTel libs) |
| Continuous Profiling | Evolving (Alpha/Beta) | Dependent on upstream | Advanced/Native (via Pyroscope) |
| Stateful vs. Stateless | Purely stateless | Purely stateless | Stateful clustering (built-in) |
| Extensibility | Build your own via ocb |
Standard OTel mechanisms | Custom Alloy modules |
OpenTelemetry Collector¶
The upstream collector is the baseline. It is divided into two main distributions:
- Core: A bare-bones, secure binary containing only essential components (OTLP, file, basic processors).
- Contrib: A massive binary containing hundreds of community-built components (receivers for Redis, Kafka, Postgres, and various SaaS exporters).
Note: While "Contrib" has everything, it can be a security and maintenance liability. Deploying the full Contrib image means inheriting hundreds of third-party Go dependencies that you likely don't use.
AWS Distro for OpenTelemetry (ADOT)¶
ADOT is not a fork; it is a custom build of the upstream collector. AWS uses
the OpenTelemetry Collector Builder (ocb) to cherry-pick a subset of upstream
components and add their own AWS-specific logic.
- Signal Parity: Full parity for Traces, Metrics, and Logs.
- The Component Filter: AWS strips out roughly 80% of the
contribecosystem. If you need an obscure receiver (e.g., for a legacy database), it might be missing in ADOT. - AWS Specialization: It includes battle-tested, AWS-supported exporters like
awsxray,awscloudwatchlogs, andawsprometheusremotewrite. - The Lag: ADOT tracks upstream closely, usually trailing by just a few weeks to allow for AWS internal stability testing.
Grafana Alloy¶
Alloy takes a "wrapper" architectural approach. Alloy acts as a programmable agent. It wraps standard OpenTelemetry Go libraries within a dynamic runtime,
How Alloy consumes OTel¶
Alloy imports the OpenTelemetry Go libraries under the hood. In Alloy, standard OTel
components are surfaced under the otelcol.* namespace (e.g., otelcol.receiver.otlp,
otelcol.processor.batch).
- Curated OTel Components: Alloy doesn't import all 200+
contribcomponents, but it imports the "heavy hitters" (standard processors, OTLP receivers, major cloud exporters). - Bridging OTel with Prometheus/Loki: This is Alloy’s "superpower." You can scrape metrics using standard Prometheus Go libraries (often more efficient than OTel's Prometheus receiver) and seamlessly translate them into OTLP pipelines.
- Continuous Profiling: While OTel is still standardizing Profiling, Alloy has first-class, production-ready support for continuous profiling via Grafana Pyroscope components.
Zero Lock-in: The OTel Engine¶
As of 2025/2026, Alloy ships with an embedded OpenTelemetry Engine (experimental).
Running alloy otel --config config.yaml bypasses the River syntax entirely and spins
up a standard upstream OTel collector engine within the Alloy process. This means if
a team demands a vanilla OTel experience, Alloy can execute it natively without any refactoring.
Recommendation¶
The SRE team is already supporting Alloy, the benefits of unified support and programmable pipelines outweigh the overhead of learning River. Furthermore, Grafana Alloy natively integrates with Promtheus better than the otel collector.