skip to content

Which columns does JMeter write into a CSV results file (JTL) by default?

level: juniorimportance: must knowfreq 72%

answer

  1. One line per sample, fixed order
  2. First line names every column
  3. Two thread-count columns, not one
  4. Three timing columns, two byte columns
  5. One saveservice key per field

basics

~10 s

JMeter's default CSV JTL carries seventeen columns: timeStamp, elapsed, label, responseCode, responseMessage, threadName, dataType, success, failureMessage, bytes, sentBytes, grpThreads, allThreads, URL, Latency, IdleTime and Connect.

solid answer

~40 s

Out of the box a JMeter CSV results file writes one line per sample with seventeen fields, and the first line is that same list of names because `jmeter.save.saveservice.print_field_names` defaults to `true`. In order they are `timeStamp`, `elapsed`, `label`, `responseCode`, `responseMessage`, `threadName`, `dataType`, `success`, `failureMessage`, `bytes`, `sentBytes`, `grpThreads`, `allThreads`, `URL`, `Latency`, `IdleTime` and `Connect`. Each column is switched on or off by its own `jmeter.save.saveservice.*` property — `label`, `latency`, `connect_time`, `idle_time`, `sent_bytes` and `thread_counts` are on by default, while `filename`, `hostname`, `sample_count` and `encoding` are off. Turning one off removes the column but never reorders the rest: the order is fixed in code, not driven by the property file.

code

csv · 3 lines
csv
timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
1551783627191,351,Checkout,200,OK,Thread Group 1-1,text,true,,18,8,1,1,https://shop.example/checkout,120,0,14
1551783627543,192,Checkout,200,OK,Thread Group 1-2,text,true,,18,8,1,2,https://shop.example/checkout,88,0,0

go deeper

for a junior

Be able to name the file the -l flag produces and recite the common columns: timeStamp, elapsed, label, responseCode, success. Knowing that the first line names them is enough at this level.

for a middle

Explain that each column is one jmeter.save.saveservice.* flag, that the order is fixed in the writer, and that thread_counts alone produces both grpThreads and allThreads.

for a senior

Show you can read a JTL nobody documented: reconstruct the column set from the header, spot which optional fields were enabled, and say what is missing before you trust a number taken from it.

for a principal

Own the fact that a result file is only evidence if its schema is predictable. Decide which save flags every team's runs share so files from different injectors and different quarters line up.

A JTL is simply the file a JMeter listener writes, and in CSV form it is one line per sample result with a fixed field order. It is the artefact that outlives the run — the GUI window closes, the dashboard folder gets deleted, but the `.jtl` is the thing someone opens six months later to answer *what did that release actually do?* Knowing its default shape is what makes that possible. ## The seventeen default columns With a stock `bin/jmeter.properties`, the header line is exactly: ``` timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect ``` | Column | What it holds | |---|---| | `timeStamp` | Sample time as epoch milliseconds | | `elapsed` | Whole-sample time in milliseconds | | `label` | The sampler's name | | `responseCode` / `responseMessage` | Protocol status and its text | | `threadName` | Thread Group name plus group and thread index | | `dataType` | `text`, `bin` or empty | | `success` | `true` or `false` for this sample | | `failureMessage` | First assertion failure message, else empty | | `bytes` / `sentBytes` | Bytes received and sent | | `grpThreads` / `allThreads` | Active threads in this group, and in the whole JVM | | `URL` | Request URL where the sampler sets one | | `Latency` | Time to the first part of the response | | `IdleTime` | Milliseconds explicitly excluded from the sample | | `Connect` | Time to establish the connection | ## What switches each column on Every field is a separate `jmeter.save.saveservice.*` key, and the shipped file documents each one as a commented-out line showing its default. Reading the ones that matter: - on by default and therefore present: `label`, `response_code`, `response_message`, `thread_name`, `data_type`, `successful`, `time`, `latency`, `connect_time`, `idle_time`, `bytes`, `sent_bytes`, `thread_counts`, `url`, `assertion_results_failure_message`; - off by default and therefore absent: `filename`, `hostname`, `sample_count`, `encoding`, `samplerData`, `requestHeaders`, `responseHeaders`, `response_data`; - `thread_counts` is one key that produces **two** columns, `grpThreads` and `allThreads`, so counting keys and counting columns give different numbers. ## The order is fixed, the set is not This is the part people get wrong. Switching a field off removes its column and nothing else — the survivors keep their relative order, because the order lives in the writer, not in the property file. So a JTL written with `hostname=true` has `Hostname` sitting between `ErrorCount` and `IdleTime`, exactly where the writer puts it, no matter where you wrote the property. A file with a header is therefore self-describing; a file written with `print_field_names=false` is only readable if you can reconstruct which flags were on. ## Two easy misreadings 1. **`grpThreads` versus `allThreads`.** The first counts active threads in the sample's own Thread Group; the second counts active threads across every group in that JVM. On a single-group plan they are equal, which is why the difference goes unnoticed until a plan grows a second group. 2. **`bytes` on a parent row.** When a sampler produces sub-samples, the parent's `bytes` already includes its children's, so adding the column up over all rows double-counts. ## Quoting, and the delimiter The separator is `jmeter.save.saveservice.default_delimiter`, a comma unless you change it; the shipped file shows a tab as the worked alternative, and the manual notes that setting it to a vertical bar leaves the format still called `csv`. Text fields are quoted only when they need to be: if a value contains the delimiter, a double quote, a carriage return or a line feed, JMeter wraps the field in double quotes and doubles any quote inside it. Numeric fields are written bare. That is why a `failureMessage` holding a comma does not break the row, and why a naive split on the delimiter eventually will. ## Extra columns you can ask for The `sample_variables` property (note: no `jmeter.save.saveservice.` prefix) takes a comma-separated list of JMeter variable names, and each one becomes an additional quoted column appended after `Connect`, with its per-sample value on every row. That is the supported way to stamp a correlation id or a data-set key into the evidence file so a row can be traced back to the input that produced it. What the numbers in these columns *mean* for capacity — how to summarise them, which of them to quote, how to treat errors — is a reading-results question and belongs to the performance-testing foundations material, not to the file format.

  • Which single JMeter property removes that header line, and what does losing it cost you?
    `jmeter.save.saveservice.print_field_names=false`. The rows are unchanged, but the file stops being self-describing: to read it you must know which save flags were on when it was written, because only the order is fixed, not the set of columns present.
  • How do you get an extra column into a JMeter JTL holding one of your own variables?
    Set the `sample_variables` property to a comma-separated list of variable names, for example `sample_variables=ORDER_ID,REGION`. Each name becomes a quoted extra column appended after the last standard field in CSV, and an extra attribute per sample in XML.
  • Does the .jtl extension mean anything to JMeter?
    No. `.jtl` is a convention only; nothing in JMeter keys off it. The file's format comes from `jmeter.save.saveservice.output_format` or from the listener's own saved configuration, so a file called `results.xml` can perfectly well contain CSV.

saying these in an interview costs you the question

  • Claims the column order follows the property file order
  • Thinks grpThreads and allThreads always hold the same number
  • Says elapsed is recorded in seconds
  • Assumes a .jtl extension guarantees CSV, or .xml guarantees XML
  • Believes response bodies are in the default CSV columns