skip to content

In a JMeter HTTP Request's Body Data field, how do you generate a unique order id per request?

level: seniorimportance: should knowfreq 54%

answer

  1. Uniqueness has a scope, not just a value
  2. One function needs no coordination at all
  3. Thread numbering restarts somewhere
  4. Two identical fields are two counters
  5. Reading the id back matters too

basics

~20 s

Put the function in the Body Data field itself. ${__UUID} yields a fresh type-4 UUID on every evaluation; ${__counter(TRUE,)} yields a per-thread sequence; ${__threadNum} is fixed per thread and only unique inside its own Thread Group.

solid answer

~40 s

An HTTP Request's **Body Data** box is interpolated like any other field, so `{"orderId":"ORD-${__UUID}"}` re-evaluates on every execution of that sampler — no pre-processor needed. Pick the function by the uniqueness you actually need. `${__UUID}` is a type-4 UUID generated with no coordination, so it survives extra threads, a second Thread Group and extra machines. `${__counter(TRUE,)}` counts per thread, `${__counter(FALSE,)}` counts across threads in one JVM, and **each occurrence in the plan is its own counter** — two fields spelled identically do not share a sequence. `${__threadNum}` returns the thread's index within its own Thread Group, so it repeats once per group. `${__RandomString(...)}` and a `${__timeShift(...)}` timestamp are decoration, not guarantees. Apache JMeter 6.0.0.

code

json · 6 lines
json
{
  "orderId": "ORD-${__UUID}",
  "clientRef": "${__threadGroupName}-${__threadNum}-${__counter(TRUE,)}",
  "placedAt": "${__timeShift(yyyy-MM-dd'T'HH:mm:ss,,,,)}",
  "lines": [ { "sku": "${SKU}", "qty": 1 } ]
}

go deeper

for a junior

Know that a function can go straight into an HTTP Request's Body Data field and is re-evaluated per request, and that ${__UUID} is the simplest way to get a value that will not repeat.

for a middle

Explain the scope of each option: UUID needs no coordination, __counter(TRUE,) is per thread, __counter(FALSE,) is per JVM, and __threadNum is fixed and Thread Group-local.

for a senior

Demonstrate the operating judgment: identical counter calls are separate counters, ids must still be traceable in a server log, and the substitution should be eyeballed once before a real run.

for a principal

Own the convention for identifier shape across a suite - what the system stores, what the run correlates on, and how those hold up when the plan later runs from several machines at once.

## The body field is interpolated like any other An HTTP Request's **Body Data** box is an ordinary JMeter text field. A reference in it is compiled once when the plan is prepared and re-evaluated every time that sampler runs: ``` {"orderId":"ORD-${__UUID}","sku":"${SKU}","qty":1} ``` Nothing else is required — no pre-processor, no script element. The only real question is which function gives you the uniqueness you actually need. ## What each candidate guarantees | Call | New value on | Unique across | | --- | --- | --- | | `${__UUID}` | every evaluation | threads, Thread Groups and JVMs | | `${__counter(TRUE,)}` | every evaluation, per thread | that one thread | | `${__counter(FALSE,)}` | every evaluation, shared | threads in one JVM | | `${__threadNum}` | never — fixed for the thread's life | its own Thread Group only | | `${__RandomString(12,0123456789ABCDEF)}` | every evaluation | nothing; collisions are possible | | `${__timeShift(yyyyMMddHHmmssSSS,,,,)}` | every evaluation | nothing; threads share a millisecond | `${__UUID}` is the honest default. It takes no arguments, returns a type-4 UUID, and needs no coordination, so it keeps working when you add threads, add a second Thread Group, or run the same plan from more than one machine. ## The counter traps 1. **Every occurrence is its own counter.** A call is compiled into one function instance per occurrence in the plan, so two fields containing `${__counter(TRUE,)}` count independently. To share one sequence, produce it once with the second argument — `${__counter(TRUE,ORDER_SEQ)}` — and reference `${ORDER_SEQ}` everywhere else. 2. **`FALSE` is not global to the test.** It is global to that one function instance inside that one JVM. 3. **It is backed by an int**, so the sequence stops meaning anything past 2,147,483,647. 4. **Each server in a distributed run evaluates its own copy of the plan**, so counter-based and thread-number-based ids repeat once per server. `${__UUID}` does not. ## __threadNum is Thread Group-local JMeter names its worker threads `<group name> <group number>-<thread number>`, and `__threadNum` returns the text after the last hyphen — the thread's 1-based index inside its own Thread Group. Add a second Thread Group and there are two threads numbered 1. If you want the number to identify a virtual user across the whole plan, prefix it with `${__threadGroupName}`, which also takes no arguments. Two further limits are easy to trip over: `__threadNum` does not work in a config element such as User Defined Variables, because config elements are processed from a separate thread, and it means nothing on the Test Plan element. ## Readable ids versus safe ids Two shapes are worth knowing, and they trade against each other: - `ORD-${__UUID}` — unique with no reasoning required, but it tells you nothing when you find it in a server log. - `ORD-${__threadGroupName}-${__threadNum}-${__counter(TRUE,)}` — reads as *group, user, iteration*, so a failed request traces straight back to the virtual user and iteration that sent it; unique only within one JVM. A common compromise carries both: a UUID as the id the system under test stores, and the readable composite in a custom header or the sample label so the run itself stays navigable. How realistic the rest of the payload has to be is a test-data question rather than a JMeter-syntax one, and is decided elsewhere. ## Use the same id twice, on purpose If the id must appear in the body *and* in a header, or in a later request, do not write `${__UUID}` twice — the second call returns a different UUID. `__UUID` has no store-to-variable argument, so capture it once (a User Parameters pre-processor is the usual place) and reference the variable afterwards. `__counter` and `__RandomString` do take a variable name as their last argument, which is the cheaper route when either of those fits. Finally, check the substitution once. An unresolved reference is passed through as literal text, so a mistyped `${__UUId}` puts the characters `${__UUId}` into the order id rather than failing anything. Behaviour described is Apache JMeter 6.0.0.

  • Two fields in your JMeter plan both contain ${__counter(TRUE,)}. Do they produce the same number?
    No. Each occurrence of a call in the plan compiles to its own function instance with its own count, so the two fields run independent sequences. Generate the value once with the reference-name argument — `${__counter(TRUE,ORDER_SEQ)}` — and use `${ORDER_SEQ}` wherever the same number is needed.
  • Why is ${__threadNum} a poor unique id once a plan has two Thread Groups?
    It returns the thread's index within its own Thread Group, taken from the worker thread's name, so numbering restarts at 1 in every group. Two concurrent users can both be thread 3. Prefixing with `${__threadGroupName}` fixes the collision without changing anything else.
  • The same order id must go in the body and in an X-Request-Id header. How do you avoid two different UUIDs?
    Evaluate it once and store it. `__UUID` has no variable-name argument, so generate it in a User Parameters pre-processor on the sampler and reference the variable from both fields. Writing `${__UUID}` in each field calls the function twice and produces two unrelated values.

saying these in an interview costs you the question

  • Thinks ${__UUID} written twice yields the same value
  • Treats ${__threadNum} as unique across the whole plan
  • Assumes two identical counter calls share one sequence
  • Believes __counter(FALSE) is global across all machines in a run
  • Uses a formatted timestamp alone as a unique identifier