Chapter 24Lesson 01~175 minutes

Backend Listener, InfluxDB/Graphite, Grafana, and Real-Time Telemetry: Core Concepts and Mental Model

Chapter 23 taught you to interpret a post-run HTML dashboard only after validating the raw JTL, workload, generator state, labels, time window and target telemetry. That workflow is strong for completed tests, but long tests and active incidents need another question answered while the run is still in progress: what is changing right now on the load generator and the system under test? JMeter's Backend Listener streams aggregated SampleResult-derived metrics to a time-series backend so Grafana can visualize them alongside independently collected service metrics.

Backend ListenerInfluxDB / GraphiteGrafanaCardinalityTime correlation

Learning objectives

  • Explain the asynchronous Backend Listener queue/client model.
  • Distinguish JMeter client metrics, generator resource telemetry and SUT/server telemetry.
  • Understand InfluxDB measurements/tags/fields and Graphite metric paths at a beginner level.
  • Recognize tag/label cardinality and timestamp alignment as measurement-validity concerns.
  • Inspect backend/client/labels/timestamps/retention read-only before adding telemetry.
  • Keep JTL and target evidence as independent sources even when Grafana is available.

1. The practical problem: the interesting event happens before the test ends

A 45-minute test shows a latency spike at minute 28. After the run, JTL proves the spike, but without time-correlated server/generator telemetry you may not know whether it coincided with target CPU pressure, GC, connection issues, injector saturation, or a monitoring/backend problem. Real-time telemetry helps preserve that chronology while the event is happening.

Mandatory chapter boundary: only 127.0.0.1 services are used: fixture :8024, InfluxDB :8086, Grafana :3000. The checkpoint is capped at 2 threads ×80 loops = 160 HTTP samples and ≤25 seconds. All tokens/passwords shown are fake disposable local values. Never substitute a public/shared/production endpoint for the mandatory lab.

2. Mental model: two telemetry streams share time, not ownership

Real-time telemetry with independent evidence streams

Real-time telemetry is a second evidence stream, not a replacement for the raw experiment. JMeter client metrics and SUT metrics are produced by different systems and become comparable only when timestamps, labels, run identity, retention, and telemetry overhead are controlled.

flowchart TD
W[Workload + JMX + properties] --> J[JMeter engine / threads]
J --> S[SampleResult stream]
S --> Q[Backend Listener async queue]
Q --> C[InfluxDB/Graphite client]
C --> TS[Time-series store]
TS --> G[Grafana panels]

J --> L[Lean JTL + jmeter.log]
J --> GR[Generator CPU / heap / network]
J --> H[HTTP protocol]
H --> T[Local target]
T --> SM[SUT metric publisher]
SM --> TS
T --> E[Target JSONL events]

L --> V[Validity / forensic review]
GR --> V
E --> V
G --> V

The JMeter engine still owns the workload and produces SampleResults. Backend Listener receives those results asynchronously through its queue and passes them to a client such as InfluxDB or Graphite. The time-series store persists aggregated metric points, and Grafana queries them for live panels. In parallel, JMeter still writes lean JTL/jmeter.log, the generator exposes its own CPU/heap/network state, and the SUT exposes separate service metrics/events. Grafana can align those signals by time/run labels, but it does not merge their meaning: JMeter response time remains a client-side observation, while the SUT metric remains server-side state.

3. Backend Listener is an asynchronous consumer

Current JMeter defines Backend Listener as an asynchronous listener. Its Async Queue size buffers SampleResults while the selected BackendListenerClient handles them. That decoupling prevents every sampler thread from synchronously writing a metric point, but it does not make telemetry free. Queue objects consume heap, client aggregation consumes CPU, and the backend requires network/socket/disk work.

A large queue can hide a slow backend for longer while consuming more memory. A chronically slow/unreachable backend still creates generator risk. Therefore queue size, send interval, backend errors and generator resources belong in the evidence packet.

4. Built-in client choices

Client What it sends Primary trade-off
InfluxdbBackendListenerClient Aggregated JMeter metrics in a custom InfluxDB schema; supports InfluxDB v2 token + org/bucket URL. Good live dashboard path; fields/tags/cardinality and send interval must be controlled.
GraphiteBackendListenerClient Graphite hierarchy metrics; plaintext or Pickle sender. Simple metric path model; Pickle is documented as more efficient for larger metric volumes.
InfluxDBRawBackendListenerClient Every sample as an InfluxDB point. Maximum detail but JMeter explicitly warns of higher JMeter + InfluxDB resource use.

The mandatory lab uses the aggregated InfluxDB client because the learning goal is correlation, not duplicating every JTL row into the database.

5. What JMeter streams

The real-time metrics documentation exposes active-thread statistics plus per-sampler success/failure/all counts, min/max/average, percentiles, hit counts and sent/received bytes. With the InfluxDB client, the default measurement is jmeter. Important tags/fields include:

  • application — stable tested application name;
  • transaction — sampler label or all/internal;
  • statut — historical tag spelling retained for compatibility: ok/ko/all;
  • fields such as count, countError, avg, min, max, hit, sb, rb, and configured percentile fields;
  • custom TAG_* values, which become InfluxDB tags.

6. Send interval and percentile window are separate controls

The built-in Influx client send interval defaults to 5 seconds. Backend percentile/min/max computation also has a metrics window: fixed mode with 100 samples by default, or timed mode with a larger configurable window. These influence the live series but do not rewrite the original JTL.

The lab uses a 1-second send interval to make a short controlled delay visible. That is intentionally more chatty than the default and therefore part of the overhead experiment.

7. InfluxDB: measurement, tags, fields, timestamp

An InfluxDB point has a measurement, optional indexed tags, fields containing values, and a timestamp. Tags are excellent for low-cardinality dimensions such as application=p24-lab or env=local. They are dangerous for unbounded values such as request IDs, URLs with unique IDs, tokens, UUIDs or user IDs because each unique tag combination can create a new series.

8. Graphite: hierarchical metric paths

Graphite encodes dimensions into dot-separated metric names, for example a prefix plus sampler/status/statistic. JMeter's Graphite client supports plaintext and Pickle senders. Use stable prefixes and sampler labels; a dynamic label still creates an explosion of distinct metric paths even without InfluxDB tags.

9. Grafana is a query/visualization layer

Grafana queries a datasource and renders panels. It is not the original JMeter result file, not the SUT event log, and not a magic causal engine. A blank panel can mean query/filter/cardinality/retention/backend problems even while JTL and the target are healthy.

10. Time correlation requires clocks you trust

To compare “JMeter latency rose at 12:00:08” with “server delay changed at 12:00:08,” generator, target and telemetry writer timestamps must be comparable. The local lab runs everything on one host, minimizing clock skew. Distributed Chapter 25 will require explicit NTP/time-sync checks.

11. State checklist before enabling telemetry

State Read-only question
Generator JMeter/Java version, CPU/heap/GC/network, Backend Listener queue/client/send interval?
Thread/arrival Threads/loops/pacing unchanged with telemetry on/off?
Component scope Which labels match samplersRegex; summaryOnly true/false; Transaction Controller parents?
Variables/properties/data Which run ID/env values become tags; are any dynamic/sensitive?
Protocol/session HTTP target state remains independent from telemetry HTTP writes?
Target Which SUT metric/event is collected independently; same clock/run ID?
Results Lean JTL + jmeter.log still written and retained?
Trust/security Influx token/Grafana password storage; localhost binding; no real secret in JMX/tag/query?
Validity Configured versus achieved samples; listener/backend overhead; dropped/late/failed metric evidence?

12. Read-only inspection first

PowerShell:

& "$env:JMETER_HOME\bin\jmeter.bat" -v
java -version

Get-Content .\config\local.properties |
  Select-String -Pattern "backend_|target.|threads|loops|pacing"

Get-ChildItem .\plans -Filter *.jmx |
  Select-String -Pattern "BackendListener|InfluxdbBackendListenerClient|GraphiteBackendListenerClient|TAG_|samplersRegex"

docker compose -f .\observability\compose.yaml config
docker compose -f .\observability\compose.yaml ps
curl.exe --fail --silent http://127.0.0.1:8086/health
curl.exe --fail --silent http://127.0.0.1:3000/api/health
curl.exe --fail --silent http://127.0.0.1:8024/health

These checks prove configuration and service health before load. Do not start the JMeter run until the target/backend stack is healthy and run IDs/tags are known.

13. DevOps connection

Real-time telemetry is most useful when it links a workload symptom to infrastructure/service state without replacing raw evidence. A production operating model should be able to answer: which run produced this point, which label created this series, how long is it retained, which clock stamped it, what overhead did collection add, and where is the corresponding JTL/target evidence?

Knowledge check

Why is Backend Listener called asynchronous?

Why is run_id acceptable as a lab tag but request_id is usually not?

Why can't Grafana prove the SUT caused a latency spike?

What evidence remains mandatory even with live InfluxDB/Grafana?

What is the risk of InfluxDBRawBackendListenerClient?

Next lesson

Build the local live-telemetry stack

Lesson 2 launches pinned InfluxDB/Grafana locally, configures the built-in Backend Listener, publishes a separate SUT delay metric, builds Grafana panels and quantifies listener/backend overhead.

Official references and version notes

Version and compatibility note

Version-sensitive statements were rechecked against current primary documentation on 2026-09-05. The JMeter course baseline remains Apache JMeter 5.6.3 with a Java 17 JDK; JMeter 5.6.3 requires Java 8+. JMeter's Backend Listener is asynchronous and accepts an explicit queue size. JMeter ships with GraphiteBackendListenerClient and InfluxdbBackendListenerClient; since JMeter 5.4 it also ships InfluxDBRawBackendListenerClient, which JMeter explicitly warns consumes more JMeter and InfluxDB resources because it writes every sample individually. The standard InfluxDB client supports InfluxDB v2 by supplying an influxdbToken plus org/bucket in the influxdbUrl. The built-in Influx backend send interval defaults to 5 seconds; this tiny lab deliberately sets it to 1 second for visible time correlation. The default backend percentiles are 90/95/99. Backend metric windows default to fixed mode with a 100-sample window; a too-large timed window can create memory pressure. The lab pins InfluxDB OSS 2.9.1 and Grafana OSS 13.2.1 rather than floating container tags. InfluxDB 3 is the newest InfluxDB product line, but the mandatory lab intentionally uses the documented JMeter v2 write integration. Grafana 13.2.1's InfluxDB datasource supports InfluxDB OSS 2.x and Flux. No third-party JMeter plugin is required.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.