Request rate and error rate tell you how much traffic Traefik is handling and whether it is succeeding. They do not tell you how much data is moving. A proxy serving ten thousand small API calls per second and a proxy serving ten thousand large file downloads per second look identical on a requests-per-second dashboard, but they have completely different bandwidth, memory, and buffering profiles.

Traefik’s bytes counters close that gap. traefik_service_requests_bytes_total and traefik_service_responses_bytes_total measure the volume of data flowing in each direction per service, with entrypoint-level and router-level equivalents for different aggregation needs. This article covers what these counters measure, how to turn them into capacity-planning inputs, which deviations are worth alerting on, and the instrumentation gaps that can mislead you.

This is a reference for the traffic-volume signal. For the broader signal taxonomy, see the Traefik guides hub at /guides/traefik/.

What the bytes counters measure

Traefik emits bytes counters at three levels of its request pipeline. All three are cumulative counters (they only increase), so every useful query starts with rate() or increase().

LevelRequest bytesResponse bytesLabels
Entrypointtraefik_entrypoint_requests_bytes_totaltraefik_entrypoint_responses_bytes_totalcode, method, protocol, entrypoint
Routertraefik_router_requests_bytes_totaltraefik_router_responses_bytes_totalcode, method, protocol, router, service
Servicetraefik_service_requests_bytes_totaltraefik_service_responses_bytes_totalcode, method, protocol, service

The three levels answer different questions:

  • Entrypoint level is your edge bandwidth view. It sums everything arriving on a listener, including requests that never match a router. Use it for link saturation and total ingress/egress planning.
  • Router level splits volume by routing rule. Useful when several hostnames or paths share a service and you need to know which route drives the traffic. Router-level metrics are off by default; you must set addRoutersLabels: true in the Prometheus metrics configuration, and you pay for it in metric cardinality.
  • Service level is the capacity-planning workhorse. It attributes bytes to the backend service that handled the request, which is the unit you scale.

Service-level labels are on by default (addServicesLabels: true), as are entrypoint labels. If you query the router-level metrics and get nothing back, check addRoutersLabels before assuming there is no traffic.

flowchart LR
  C[Clients] --> E[Entrypoint]
  E -->|entrypoint bytes counters| R[Router]
  R -->|router bytes counters, opt-in| M[Middleware chain]
  M --> S[Service / load balancer]
  S -->|service bytes counters| B[Backends]

Turning counters into usable numbers

Raw counter values are meaningless on their own. The two derivations you will use constantly:

# Egress bandwidth per service, bytes per second
sum by (service) (rate(traefik_service_responses_bytes_total{protocol="http"}[5m]))

# Ingress bandwidth per service (client uploads), bytes per second
sum by (service) (rate(traefik_service_requests_bytes_total{protocol="http"}[5m]))

Divide by the request rate to get average payload sizes, which is where these metrics become diagnostic rather than just volumetric:

# Average response size per service
sum by (service) (rate(traefik_service_responses_bytes_total[5m]))
  /
sum by (service) (rate(traefik_service_requests_total[5m]))

Track three baselines per service over at least two weeks so you capture weekday/weekend shape:

  • Bandwidth: bytes/sec in and out, at peak and off-peak.
  • Average request size: catches upload pattern shifts.
  • Average response size: catches payload bloat, compression changes, and error-page substitution.

These baselines are the input to both capacity planning and anomaly detection. Without them, every threshold is a guess.

Capacity planning with bytes metrics

Sum the entrypoint-level response bytes rate across entrypoints and compare it to your actual link or cloud egress capacity. The failure mode here is a cliff, not a slope: once egress saturates, TCP congestion control degrades everything at once and latency climbs for every service simultaneously, not just the heavy one.

Practical approach:

  1. Record peak-hour rate(traefik_entrypoint_responses_bytes_total[5m]) summed across entrypoints, daily.
  2. Fit the growth trend over weeks. Extrapolate to the link limit or the cloud egress tier boundary.
  3. Keep sustained peak below roughly 70 percent of capacity. The headroom absorbs retries, retransmits, and traffic spikes without queueing.

If you pay for cloud egress by the gigabyte, the same query multiplied out over a billing period is your cost forecast. Bytes counters are often the earliest warning that a new service version has started shipping much larger payloads and your egress bill is about to move.

Per-service sizing

Service-level bytes tell you which backends dominate bandwidth. When you need to split a Traefik instance, move a service to dedicated infrastructure, or negotiate capacity with a team that owns a backend, traefik_service_responses_bytes_total by service is the attribution data.

Buffering and memory pressure

Response size distribution matters beyond bandwidth. Buffering and compression middlewares hold request or response bodies in memory, so memory consumption from those middlewares scales with payload size times concurrency. A service whose average response size doubles will silently multiply the memory footprint of any buffering middleware in front of it. Watch average response size per service and treat sustained growth as a memory-capacity signal, not just a network one: unexpectedly large responses stress buffering middleware and process memory before they stress the link.

Anomaly detection: what deviations mean

The bytes metrics are an anomaly-detection signal more than a static-threshold signal. A reasonable starting point is a TICKET-level alert on sustained volume above 2x baseline. What “anomalous” looks like depends on direction:

PatternLikely meaningFirst check
Request bytes spike, request count flatUpload abuse, large POST bodies, backup job pointed at the wrong endpointBreak down by method, check access logs for large uploads
Response bytes spike, request count flatData exfiltration, runaway export/report endpoint, caching layer bypassedPer-service breakdown; compare average response size to baseline
Response bytes drop, request count flatBackend serving error pages instead of content (error pages are tiny)traefik_service_requests_total{code=~"5.."} for the same service
Request and response bytes both rise with request countGenuine traffic growthConfirm against entrypoint request rate; this is the capacity-planning case
Bytes grow steadily, request count flatPayload bloat (uncompressed assets, chatty serialization, image changes)Diff average payload size across recent deploys

The third row deserves emphasis. Asymmetric response size is one of the cheapest health checks you get for free: a service that normally returns 50 KB of JSON and starts returning 1 KB is usually returning error pages. Correlating response bytes against response codes confirms it in seconds.

Alerting guidance

  • Alert on sustained deviation, not instantaneous. Bytes rates are bursty; use a 5-15 minute window and require the condition to hold.
  • Use per-service baselines. A 2x threshold that is right for an API service will false-fire constantly on a media or export service with lumpy traffic.
  • Treat this as TICKET severity. Bandwidth anomalies rarely require waking someone up, but they frequently precede things that do: link saturation, egress cost spikes, exfiltration in progress.

Known gaps and gotchas

These are the places where the bytes counters will lie to you.

WebSocket traffic reports zero bytes. The request and response bytes counters are not incremented for WebSocket connections. There is no per-message byte accounting for upgraded connections. If a significant share of your traffic is WebSocket, the bytes metrics undercount real bandwidth, and entrypoint-level bandwidth monitoring at the host or load-balancer layer is the only complete view.

Service-level code label shows code="0" with buffering middleware. When the buffering middleware is in the chain, service-level bytes and request counters can be recorded with code="0" instead of the real status code, while entrypoint-level metrics keep the correct code. If you filter or group service bytes by code and see a large code="0" bucket, check whether buffering is in use before treating it as a new error class.

Router-level metrics are opt-in. addRoutersLabels defaults to false. Empty router-level series mean the option is off, not that traffic is zero. Enabling it on a large routing table multiplies cardinality; estimate series count before turning it on in production.

Counters reset on restart. These are process-lifetime counters. rate() handles resets correctly, but any hand-rolled delta math over long windows will break across a Traefik restart or pod replacement.

Retries inflate service-level volume. If the retry middleware is active, each attempt transfers bytes. Service-level bytes can exceed what clients actually sent or received during a retry storm. Cross-check with traefik_service_retries_total before treating a service-bytes spike as client behavior.

Signals to watch

SignalWhy it mattersWarning sign
rate(traefik_entrypoint_responses_bytes_total[5m]) summedTotal egress; the link-saturation inputSustained approach to link or egress-tier capacity
Response bytes rate per serviceCapacity attribution and growth planningSustained >2x baseline
Average response size (bytes rate / request rate)Detects error-page substitution and payload bloatSudden drop (errors) or step increase (bloat)
Request bytes rate per serviceUpload abuse and exfiltration-via-POST detectionSpike without matching request-count growth
Response bytes rate vs traefik_service_requests_total{code=~"5.."}Confirms whether size anomalies are error-drivenSize drop correlated with 5xx rise
Host NIC bytes/sec vs Traefik bytes rateExposes what Traefik cannot see (WebSockets, TCP services)Diverging trends between the two

How Netdata helps

  • Netdata charts the entrypoint, router, and service bytes counters with per-second granularity, so short payload spikes that a 5-minute PromQL window would average away are still visible.
  • Per-service bytes rate next to per-service request rate and 5xx rate on one dashboard makes the “error page vs normal content” asymmetry check a glance instead of a query.
  • Bandwidth charts per entrypoint alongside host network-interface throughput expose the WebSocket blind spot: when host egress grows but Traefik’s bytes counters do not, the traffic is in upgraded connections.
  • ML-based anomaly detection on bytes-rate metrics flags deviation from learned per-service baselines, which is exactly the >2x-baseline pattern this signal calls for, without hand-tuning thresholds per service.
  • Long retention on these counters gives you the multi-week peak history that egress capacity forecasting needs.