Running in Production
Guidance for deploying Prometheus Proxy in a production environment, pulling together the security, reliability, and tuning knobs documented elsewhere into one operational checklist.
Security
- Encrypt the gRPC channel with TLS, and prefer mutual TLS so the proxy authenticates agents and vice-versa. See TLS Setup.
- Set an agent token (
--agent_token/AGENT_TOKEN) as a lightweight app-level control in addition to TLS. An empty token leaves the agent port open and logs a startup warning. - Prefer per-agent identities over one shared token. A shared token cannot tell agents
apart, so any holder can register — and silently take over — any path, including one already
served by another agent. Named identities under
proxy.authscope each agent to its own path patterns and can be revoked individually. See Per-Agent Identities, including the incremental migration path from a shared token. - Segment the network so only trusted agents can reach the gRPC port (
50051). - Do not expose the admin or dashboard ports publicly.
/threaddumpand friends are operational tools, not public endpoints — keep8092/8093on an internal network only. The dashboard port (8094) is equally unauthenticated and shows agent names, hostnames, and target URLs; it runs on its own port precisely so it can be firewalled without cutting off the/pingand/healthcheckprobes. - When forwarding auth headers to targets, require TLS so credentials aren't sent in plaintext between proxy and agent. See Auth Header Forwarding.
High availability
-
For proxy redundancy, give the agent an ordered list of proxy endpoints. It connects to the first that answers, and on a failed connect moves to the next; when a working connection drops it returns to the head of the list, so a recovered primary is picked up on the next reconnect without any manual step.
Equivalently
--proxy proxy-a.example.com:50051,proxy-b.example.com:50051, or the same comma-separated value inPROXY_HOSTNAME.Only one connection is active at a time; the agent registers its paths on whichever proxy it is connected to. Point Prometheus at both proxies with identical target lists — see Scraping an HA pair below, which has a requirement that is easy to get wrong.
All endpoints must share the same TLS configuration. The agent builds one TLS context and one authority override for the whole list, so endpoints with different CAs or certificate SANs fail with an opaque handshake error rather than a clear configuration error.
-
For agent redundancy, use consolidated mode: multiple agents register the same path, and the proxy keeps serving it as long as one remains connected. This also smooths rolling upgrades — the new agent registers before the old one drains.
Scraping an HA pair
Use static_config, not http_sd_config
A standby proxy — one no agent is currently connected to — returns an empty list from its
service-discovery endpoint. Under http_sd_config Prometheus treats that as "these targets no
longer exist" and deletes them: no up=0, no failed scrape, no alert. The series simply stop,
which is the one failure mode an HA pair is supposed to make impossible.
With static_config, the standby returns 404 for a path it does not know, Prometheus records
up=0 for that target, and your existing alerting works unchanged.
scrape_configs:
- job_name: proxied-metrics
static_configs:
- targets: ["proxy-a.example.com:8080", "proxy-b.example.com:8080"]
Both proxies are scraped every interval. Exactly one of them has the agent connected and returns the
metrics; the other returns 404 and shows as up=0. Deduplicate in the usual Prometheus HA way
(distinct external_labels plus a downstream deduplicating reader, or honor_labels).
- Set Kubernetes liveness/readiness probes to /ping and /healthcheck so unhealthy pods are
restarted and kept out of rotation. See Kubernetes.
Sizing & tuning
Start from the defaults and adjust against the backlog and latency metrics:
| Parameter | Default | When to change |
|---|---|---|
agent.maxConcurrentClients |
1 | Raise for many endpoints or slow targets |
agent.scrapeTimeoutSecs |
15 | Raise for slow targets |
agent.http.clientTimeoutSecs |
90 | Lower for fast-failing scrapes |
agent.chunkContentSizeKbs |
32 | Raise for large payloads to cut chunk count |
agent.minGzipSizeBytes |
512 | Lower to compress more aggressively |
agent.http.maxContentLengthMBytes |
10 | Raise for large scrape bodies (guards agent heap) |
proxy.internal.maxUnzippedContentSizeMBytes |
— | Raise for large decompressed payloads |
proxy.internal.maxAgentInactivitySecs |
60 | Tune stale-agent eviction window |
Size the JVM heap for the largest decompressed payload times the scrape concurrency, and
watch agent_scrape_backlog_size / proxy_cumulative_agent_backlog_size — a steadily growing
backlog means agents can't keep up. See Performance Tuning.
Observability
- Enable metrics on proxy and agent and scrape their internal
/metrics. See Monitoring. - Import the dashboards and alert rules from Grafana & Alerting.
- Alert on success rate, P99 latency, agent count, and backlog growth — the rules on that page cover each.
- Enable the operational dashboard (
--dashboard) on an internal network. Grafana tells you that a target is failing; the dashboard shows why — which agent backs the path, whether that agent is still connected, and how its recent scrapes went — including paths whose agent has already gone.
Logging
- Leave
requestLoggingEnabledon if you want per-scrape logs — they emit at DEBUG, so they won't flood INFO on a busy proxy. - Use
logLevel = "trace"for the most verbose output; the legacy"all"level was removed and now fails fast at startup.
Shutdown
- Standalone proxy/agent processes shut down cleanly on SIGTERM. Embedded agents should be
stopped via
EmbeddedAgentInfo.shutdown()(orclose()), which blocks until terminated. See Embedded Agent.
Pre-flight checklist
- [ ] TLS (ideally mutual) enabled on the gRPC channel
- [ ] Agent token set (per-agent identities where teams share a proxy), or mutual TLS in place
- [ ] gRPC port reachable by agents; admin and dashboard ports not publicly exposed
- [ ] Metrics enabled and scraped by Prometheus
- [ ] Dashboards imported and alert rules loaded
- [ ]
maxConcurrentClients/ timeouts tuned for your targets - [ ] Content-size limits sized for your largest payload
- [ ] JVM heap sized for peak decompressed payload × concurrency
- [ ] Liveness/readiness probes wired to
/pingand/healthcheck - [ ] Consolidated mode configured where you need agent redundancy