Last updated: September 7, 2026
Deploy the Edge Proxy
The edge proxy is a stateless proxy you run in your own network as part of SignalControl Edge. It is optional but recommended at scale: instead of each collector connecting to Dash0 directly, the proxy holds one upstream connection per site and fans the results out to the collectors. It runs two independent pipelines, each enabled separately:
- Edge-settings fan-out (
upstream.edgeSettings.enabled, defaultfalse): Polls Dash0 once per proxy instance and broadcasts the settings snapshot to subscribed collectors over gRPC. The snapshot carries the organization's signal-to-metrics rules and its dataset settings, which include the spam filter rules. It is deduplicated and compressed once per change, so N collectors receive one broadcast per real change instead of N polls. - Tail-sampling decisions (
upstream.tailSampling.enabled, defaulttrue): Forwards sampling reports from collectors to Dash0 and fans decisions back, so decisions cross the internet once. This upstream is not required when only edge settings is enabled.
Enabling neither pipeline is rejected at startup.
Configuration
Config comes from ./edge-proxy.yaml, /etc/dash0/edge-proxy.yaml, or environment variables (upstream.edgeSettings.address maps to UPSTREAM_EDGESETTINGS_ADDRESS, and so on). The two pipelines are configured independently: upstream.address and upstream.headers drive the sampling upstream, and the nested upstream.edgeSettings block drives the settings upstream.
Both pipelines enabled, tail sampling and settings fan-out. This is the usual shape when you use edge tail sampling:
1234567891011121314151617181920listenAddress: ":8011"listenAddressInternal: ":8012"upstream:# Sampling upstream (the Dash0 decision maker for your region).address: "decision-maker.eu-west-1.aws.dash0.com:443"headers:authorization: "Bearer <dash0-auth-token>"Dash0-Dataset: "<dataset>"tailSampling:enabled: true # default# Settings upstream (the Dash0 API for your region).edgeSettings:enabled: trueaddress: "https://api.eu-west-1.aws.dash0.com"headers:authorization: "Bearer <dash0-auth-token>"refreshInterval: 60s # 10s–1hfallbackMinConnectedRatio: 0.5subscriberBufferSize: 10000reportBufferSize: 10000
A settings-only proxy, for collectors that do not use edge tail sampling. No sampling upstream is needed:
12345678910listenAddress: ":8011"upstream:tailSampling:enabled: false # no sampling upstream needededgeSettings:enabled: trueaddress: "https://api.eu-west-1.aws.dash0.com"headers:authorization: "Bearer <dash0-auth-token>"refreshInterval: 60s
Save one of these as edge-proxy.yaml and start the edge proxy with it mounted at /etc/dash0/edge-proxy.yaml:
123docker run --rm --name edge-proxy --publish 8011:8011 --publish 8012:8012 \-v "$(pwd)/edge-proxy.yaml:/etc/dash0/edge-proxy.yaml" \ghcr.io/dash0hq/edge-proxy:<tag>
Instead of a config file, you can pass every setting as an environment variable. The names map from the YAML keys, so upstream.edgeSettings.address becomes UPSTREAM_EDGESETTINGS_ADDRESS. The Docker setup steps use that form.
Environment Variables
| Variable | Default | Purpose |
|---|---|---|
LISTENADDRESS | :8011 | gRPC listen address collectors connect to |
LISTENADDRESSINTERNAL | :8012 | Internal admin and pprof HTTP |
UPSTREAM_TAILSAMPLING_ENABLED | true | Enable the sampling pipeline |
UPSTREAM_ADDRESS | none | Sampling upstream address; required when tail sampling is on |
UPSTREAM_HEADERS | none | Auth headers for the sampling upstream (key=value,key2=value2) |
UPSTREAM_INSECURE | false | Disable TLS upstream (local and dev only) |
UPSTREAM_EDGESETTINGS_ENABLED | false | Enable the edge-settings pipeline |
UPSTREAM_EDGESETTINGS_ADDRESS | none | Dash0 API base URL |
UPSTREAM_EDGESETTINGS_HEADERS | none | Bearer token for the settings upstream |
UPSTREAM_EDGESETTINGS_REFRESHINTERVAL | 60s | Settings poll period, 10s–1h |
FALLBACKMINCONNECTEDRATIO | 0.5 | Tail-sampling only. The proxy fans decisions out from several upstream decision-maker instances; when the fraction still reachable drops below this ratio it can no longer coordinate reliably, so it disconnects its collectors and they fall back to local probabilistic sampling (each collector's fallback_sample_ratio). 0.5 trips when fewer than half are reachable; 1.0 trips if any one is unreachable; 0.0 disables the behavior entirely, so the proxy never disconnects collectors even with every upstream gone. This is a different mechanism from the collector's dash0sampling.fallback_min_connected_ratio, where 0.0 means "fall back only when fully disconnected". |
SUBSCRIBERBUFFERSIZE | 10000 | Per-subscriber buffer for the sampling pipeline |
REPORTBUFFERSIZE | 10000 | Async report forwarder buffer |
Operational Notes
- Health checks are gRPC (
liveness,readinesson the listen port). Only tail sampling gates readiness, so a degraded settings upstream does not cascade into the sampling pipeline. - Edge-settings snapshots are capped at 32 MiB compressed on the gRPC wire, and the collector caps the decompressed payload at 100 MiB. A snapshot larger than 32 MiB compressed is rejected and the last good snapshot is kept.
- gRPC connections are sticky. Run at least two proxy replicas; a single replica drops every collector on turnover.
Further Reading
- About SignalControl Edge. The architecture and the direct-vs-proxy choice.
- Set Up SignalControl Edge Without Kubernetes. Run the collector and proxy with Docker.
- Sample Traces. Tail sampling, whose decisions the proxy fans out.