Post-Processors in JMeter
A real website hands out secret tickets, new for every visitor, and expects them back on the next request. Post-Processors are the helpers that catch those tickets as they fly past, so your test can behave like a real person instead of a parrot.
Imagine you visit a cinema. At the door, a clerk gives you a numbered ticket. You walk to the snack counter, and the cashier says, “Show me your ticket number, please.” If you answer with a number you made up, or with last week’s number, the cashier will send you away. The ticket was handed to you for this visit only, and you must carry it from one step to the next.
Websites work in the same way. When you log in, the server gives you a session ticket. When you open a form, it hands you a hidden code. When you create an order, it gives you an order number. Every later request must show the right ticket. A load test that sends the same old ticket again and again is like a visitor waving last week’s stub: the server refuses to play along, and the test measures nothing useful.
In Apache JMeter, the elements that catch these tickets are called Post-Processors. This guide explains them from the first idea. You will learn what they are, where they live, when they run, the main kinds, how to choose between them, how to prevent silent failures, and the habits that keep them fast and reliable in a large test.
1What Is a Post-Processor?
A Post-Processor is a JMeter element that runs right after a request finishes, and it works on the response that came back.
The Simple Definition
In Apache JMeter, a sampler is an element that sends a request to the system under test, such as an HTTP Request. When the answer arrives, JMeter holds a record of it called a sample, which contains the response body, the headers, the code, the time, and more. A Post-Processor is an element you attach to the sampler. Once the answer has arrived, it examines the sample and does something useful with it. Most often, it pulls a piece of the response out and stores it in a named variable for later use.
Think of a waiter taking your order. The kitchen sends back a slip with a table number and a pickup code. The waiter does not just hand it over blindly. He reads the slip, remembers the pickup code, and uses it later when he collects your food. A Post-Processor is the waiter who reads the slip and remembers the one detail that matters.
The Most Common Job: Extraction
The majority of Post-Processors are called extractors. An extractor looks inside a response, finds one value, and copies it into a variable. Later requests can then use that variable in place of a fixed value. Because the value is read fresh from each response, every virtual user carries its own correct ticket.
Other Jobs
- Showing information for debugging. One Post-Processor adds the current variables to the result so you can read them.
- Deciding what to do after an error. One can stop a thread or the whole test when a sampler fails.
- Running custom logic. Script-based Post-Processors can calculate, convert, and decide anything you can express in a script.
- Working with databases. One can run a database statement after a request.
2Why We Need Post-Processors
Modern applications hide short-lived values in their responses. Without a way to catch them, a test cannot go beyond the first page.
The Problem of Dynamic Values
If you record a browsing session and replay it, the recording contains the exact values the server produced during that session: a session id, a security token, an order number. When you replay the script, the server produces different values, but the script still sends the old ones. The server rejects them or shows an error page. This is the number one reason why a freshly recorded script fails when played back.
Why Servers Use Such Values
- Sessions. A session id tells the server which logged-in visitor is calling.
- Security tokens. Hidden form codes stop other sites from tricking a browser into sending requests it did not intend.
- Identifiers. Newly created records, such as orders or tickets, receive fresh numbers.
- Timestamps and nonces. Single-use numbers prevent a request from being replayed by someone else.
- State markers. Some frameworks carry page state in hidden fields that must be returned unchanged.
What Happens Without Them
| Situation | What the Server Does | What You See in the Test |
|---|---|---|
| Old session id sent | Treats the visitor as logged out | Redirects to a login page, often with a success code |
| Wrong security token sent | Rejects the form submission | An error page or a 403 code |
| Fixed order number sent | Updates the same record every time | Conflicts, or a test that does not reflect real load |
| No value sent at all | Returns a message about missing data | Failures that hide the real performance picture |
The art of capturing a changing value and sending it back in a later request has a name: correlation. Post-Processors are the tools of correlation in JMeter.
3Core Concepts You Need First
Eight small ideas explain nearly everything about Post-Processors.
Sampler
The element that sends a request. Picture a messenger carrying a question to the server and bringing back the reply.
Sample
The record of one request and response. A Post-Processor reads the sample that its sampler just made.
Variable
A named box that holds a value for one virtual user. Later steps open the box by writing its name inside a dollar sign and braces.
Extractor
A Post-Processor that copies a piece of a response into a variable.
Scope
The set of samplers a Post-Processor works on, decided by where it sits in the Test Plan tree.
Default Value
The text stored in the variable when the extractor finds nothing. It is the safety net, and also a hiding place for trouble.
Match Number
A setting that says which match to keep when a pattern appears several times: the first, the second, a random one, or all of them.
Correlation
The practice of catching a dynamic value from one response and replaying it in a later request.
Why Variables Belong to One User
Every virtual user, called a thread in JMeter, owns its own set of variables. When user number seven extracts a session id, only user number seven can see that value. This is exactly what you want, because each user must carry their own ticket. It also means that one user cannot read another user’s variable, so you cannot use a variable to share data between users. For sharing, JMeter has separate global settings called properties, which are outside the scope of this guide.
4Adding a Post-Processor to a Test Plan
Adding one takes a few clicks. Choosing where to put it takes thought.
Find the Source of the Value
Decide which response contains the value you need. For a session id, it is usually the login response.
Right-Click That Sampler
Choose Add, then Post Processors, and pick the kind that fits, such as Regular Expression Extractor or JSON Extractor.
Name the Variable
Choose a clear name such as sessionToken. This is the name later steps will use.
Describe What to Find
Fill in the pattern, path, or boundaries that point at the value inside the response.
Set a Default and a Match Number
Use a clearly fake default such as NOT_FOUND, and pick the first match unless you need otherwise.
Use the Variable Later
In the next request, write the variable name inside a dollar sign and braces wherever the old fixed value used to be.
Test With One User
Run with a single thread and a debugging listener to confirm that the value is caught and used.
Always put an extractor directly under the sampler whose response contains the value. That keeps its scope tiny, which is both faster and easier to understand.
5Architecture: Where Post-Processors Sit
The Test Plan is a tree. Post-Processors hang beneath the sampler they serve, and they feed variables to other samplers further along.
flowchart TD
TP["Test Plan"] --> TG["Thread Group: Shoppers"]
TG --> S1["Sampler: Open Login Page"]
TG --> S2["Sampler: Submit Login"]
TG --> S3["Sampler: Search Products"]
TG --> S4["Sampler: Create Order"]
S1 --> P1["Post-Processor: extract security token"]
S2 --> P2["Post-Processor: extract session id"]
S3 --> P3["Post-Processor: extract product id"]
S4 --> P4["Post-Processor: extract order number"]
P1 -. "variable used by" .-> S2
P2 -. "variable used by" .-> S3
P3 -. "variable used by" .-> S4
P4 -. "variable used by" .-> S5["Sampler: Pay for Order"]
TG --> S5
Reading the Diagram
Each sampler has a Post-Processor beneath it that catches one value from its response. The dotted lines show where that value is used next. The security token caught on the login page is sent with the login submission. The session id caught from the login result is sent with the search. The product id from the search is used to create the order, and the order number from the order is used for payment. The test walks a chain of values, each one handed to the next step.
Main Components
- Thread Group. Creates the virtual users.
- Samplers. Send requests and produce samples.
- Post-Processors. Read the samples and store values.
- Variables. Hold the values for each user.
- Later samplers. Use the variables inside their requests.
6When Post-Processors Run: Order of Execution
Timing is everything. A Post-Processor runs after the response arrives and before the checks and the result viewers.
The Order Around One Sampler
For each sampler, JMeter works through its related elements in a fixed order. Configuration elements come first, then pre-processors, then timers. The sampler sends the request and receives the response. Post-processors run next, then assertions, and last of all, the listeners.
| Step | Element Type | What It Does |
|---|---|---|
| 1 | Configuration elements | Supply settings and data |
| 2 | Pre-processors | Prepare the request just before it is sent |
| 3 | Timers | Pause the user to imitate thinking |
| 4 | Sampler | Sends the request and records the response |
| 5 | Post-processors | Read the response and store or process values |
| 6 | Assertions | Check whether the response was correct |
| 7 | Listeners | Show or save the final result |
What the Order Means for You
- Post-processors run before assertions. So an assertion can check the variable that an extractor just filled. This is how you guard against a missing token.
- The variable is ready for the next sampler. By the time the next request is prepared, the value is already stored.
- A value cannot be used in the same request that produced it. The request is already gone when the extractor runs. The variable can only help later requests.
- Several post-processors run in tree order. When more than one sits in the same scope, they run from the top of the tree to the bottom, so a later one can use what an earlier one stored.
If you need a value in the very same request, you need a pre-processor instead, which runs before the request goes out. A post-processor is always one step late for its own sampler.
7Scope: Which Samplers a Post-Processor Touches
Where you put the element in the tree decides which responses it reads.
The Rules
| Where It Sits | Which Samplers It Processes | Typical Use |
|---|---|---|
| Directly under one sampler | That sampler only | Almost every extractor |
| Under a controller | Every sampler inside that controller | A rule that fits a whole step, such as a debug helper |
| Directly under the Thread Group | Every sampler in the group | An error-handling rule for the whole journey |
| Directly under the Test Plan | Every sampler in every group | Rare; usually a debugging aid |
Why Narrow Scope Is Better
An extractor placed high in the tree runs after every sampler in its scope, even those whose response has nothing to extract. This wastes time and can cause damage. If the pattern happens to match something on the wrong page, the variable receives a wrong value. If it matches nothing, the variable is overwritten with the default value, erasing a good value captured earlier.
A librarian who reads every returned book looking for a single bookmark wastes time on every book that has none. A librarian who checks only the one book known to contain the bookmark is quick and never makes a mistake. Narrow scope is the second librarian.
When a Post-Processor needs to work on many samplers, put it higher. When it serves one sampler, put it directly under that sampler. When in doubt, go lower.
8Variables: Where Extracted Values Live
An extractor writes into a variable. Understanding how variables work explains almost every correlation puzzle.
Reading a Variable
To use a stored value, write the variable name inside a dollar sign and curly braces wherever a value is expected. JMeter replaces that text with the stored value just before the request is sent. This works in the path, the parameters, the headers, the body, and in most other fields.
What Gets Created
A single extraction can create more than one variable, depending on the extractor and its settings. A typical set looks like this:
| Variable | Contents |
|---|---|
| The name you chose | The extracted value, or the default if nothing matched |
| The name with a match count suffix | How many matches were found, when the extractor offers it |
| The name with a position number suffix | The first, second, third value, and so on, when all matches are kept |
| The name with a group number suffix | The parts of a match that sit inside separate brackets of the pattern |
How Long a Variable Lives
A variable keeps its value until something replaces it. Each pass of a loop has access to values from earlier passes unless an extractor overwrites them. This is a useful feature when you want a value to persist, and a dangerous one when you do not. A user who fails to extract a fresh token in the second loop may silently reuse the stale token from the first loop, and the error will be hard to see.
Names Are Case Sensitive
A variable called sessionToken is different from one called sessiontoken. A tiny spelling difference means the later request sends the literal text with the dollar sign and braces, instead of a value, and the server rejects it. When a request contains such leftover text, a misspelled name is the most likely cause.
If a request still shows the variable name instead of its value, either the name is spelled differently, or the extractor ran after the request, or the extractor failed and the variable was never created.
9Correlation: The Whole Journey of a Value
Let us follow one security token from the server, through JMeter, and back to the server.
sequenceDiagram
participant U as Virtual User
participant S1 as Sampler: Open Form
participant PP as Post-Processor
participant V as User Variables
participant S2 as Sampler: Submit Form
participant SRV as Server
U->>S1: Run the first step
S1->>SRV: Request the form page
SRV-->>S1: Page containing a fresh security token
S1->>PP: Hand over the response
PP->>PP: Find the token inside the response
PP->>V: Store the token in a variable
U->>S2: Run the next step
S2->>V: Read the stored token
S2->>SRV: Send the form with the token
SRV-->>S2: Accept, because the token is valid
What the Diagram Shows
The user runs the first sampler, and the server answers with a page that contains a fresh token. The Post-Processor finds the token and stores it in a variable. When the next sampler runs, it reads the variable and sends the token back. The server sees a valid token and accepts the form. Without the Post-Processor, the second request would carry an old or empty token, and the server would refuse.
The Four Steps of Correlation
- Detect. Find a value in a request that was recorded and that you suspect is dynamic.
- Locate. Find the earlier response in which that value first appeared.
- Extract. Add a Post-Processor to that earlier sampler that catches the value.
- Replace. Change the later request to use the variable instead of the fixed value.
Record the same journey twice, or replay it once and compare. Values that differ between two recordings, such as long random-looking strings, are dynamic and must be correlated.
10The Regular Expression Extractor
The most widely used extractor. It finds text by a pattern and keeps the part you ask for.
What It Does
A regular expression is a compact way of describing the shape of some text, such as “the word token, an equals sign, and then a run of letters and digits.” The Regular Expression Extractor searches the response for text that fits your description and copies chosen parts of it into variables. It is very flexible, and it works on any text response, whether a web page, a data message, or a header.
Its Main Settings
| Setting | Meaning |
|---|---|
| Apply to | Whether to search the main sample, its sub-samples, both, or a JMeter variable |
| Field to check | Which part of the sample to search: the body, the unescaped body, the body as a document, the response headers, the request headers, the URL, the response code, or the response message |
| Name of created variable | The variable that will hold the result |
| Regular expression | The pattern to search for, with brackets around the part to keep |
| Template | Which bracketed parts to keep and in what form; the first group is the usual choice |
| Match No. | Which match to keep: zero for a random one, a positive number for the nth one, negative one for all of them |
| Default Value | The text to store when nothing is found |
| Use empty default value | Store an empty string instead of a named default |
Brackets Mark the Part You Keep
Inside the pattern, you place the text that surrounds your value as plain characters and wrap the value itself in round brackets. The text outside the brackets acts as a landmark; the text inside is what gets saved. For example, if the page says “csrf equals 8fk2x9” and you want the code, the landmark is “csrf equals” and the bracketed part describes a run of letters and digits.
Imagine telling a friend: “Find the line that starts with Locker number, and tell me the digits that follow.” The words are the landmark, and the digits are what you want. A regular expression is that same instruction, written in a precise shorthand.
Choose landmarks that are stable and unique, such as an attribute name or a field label. Avoid landmarks that appear in many places, because the extractor may grab the wrong one.
11Match Numbers, Groups, and Templates
Three settings decide which pieces of the response end up in which variables.
Match Number
| Match No. | Behaviour | Good For |
|---|---|---|
| 1 | Keeps the first match | A single token or id, the most common case |
| 2, 3, and so on | Keeps that numbered match | When the right value is not the first on the page |
| 0 | Keeps a random match | Picking a random product, article, or link from a list |
| -1 | Keeps all matches, numbered one after another | Looping over every item in a list |
Groups
Each pair of round brackets in the pattern makes a group. Groups are numbered from left to right, starting at one. Group zero is the entire matched text, landmarks included. Usually you want group one, which is the value inside the first brackets.
Template
The template says how to build the final variable from the groups. A template that names only the first group gives you just the value. A template that names several groups lets you glue pieces together, for example joining a prefix and a number into one string. Most extractions use the plain first-group template.
The Variables Created
When the match number is a single value, the variable holds that match. When it is negative one, JMeter creates a family of variables: one for each match, numbered in order, plus one that tells you how many matches were found. This count is the key to looping over lists, which a later chapter explains.
If you ask for the third match and the page contains only two, the extractor finds nothing and stores the default. When using a numbered match, always read the response and make sure that many matches exist.
12Writing Patterns That Do Not Break
A pattern is a small piece of programming, and it can be fragile. These habits make it sturdy.
Greedy and Lazy Matching
Some pattern symbols are greedy: they grab as much text as they can. Others are lazy: they stop at the first chance. If you want the value between two quotation marks, a greedy symbol may run past the first closing mark and swallow the rest of the line. A lazy symbol stops at the first closing mark. For extraction, the lazy style is nearly always what you want.
Special Characters
Some characters have a special meaning in patterns, such as the dot, the round and square brackets, the dollar sign, and the plus sign. If your landmark contains one of them as ordinary text, it must be marked as ordinary, usually by placing a backslash in front of it. Forgetting to do so is a classic reason why a pattern that looks right matches nothing.
Habits for Sturdy Patterns
- Copy from the real response. Paste a piece of the actual text rather than typing from memory. Tiny differences such as extra spaces or different quote styles cause silent failures.
- Use short landmarks. The more text a landmark includes, the more reasons it has to break when the page changes slightly.
- Be specific enough. A landmark that appears once on the page is safer than one that appears many times.
- Allow for spacing differences. Pages may have different spaces or line breaks between the landmark and the value. Use pattern symbols that accept any amount of white space.
- Test against several responses. A pattern that works for one response may fail for another, for example one with an empty list.
- Keep it simple. A complicated pattern is hard to read and can be slow on large pages.
Quote Styles and Encoding
Responses may contain characters in an escaped form, such as an ampersand written as a longer code, or quotes written with a backslash. The raw response is what the extractor sees, so read it in the response viewer and match what is really there. The “unescaped body” option for the field to check can help when the page has been encoded.
Before the real test, run one user and open the response in a viewer. Search the text for your landmark. If your own eyes cannot find it, neither can the extractor.
13The Boundary Extractor
A simpler cousin of the regular expression extractor. It finds text between two plain markers.
What It Does
The Boundary Extractor asks you for a left boundary and a right boundary, which are two pieces of ordinary text. It then returns whatever sits between them. There is no pattern language to learn, which makes it easy to read and less error-prone.
Its Settings
- Apply to and Field to check. Same idea as before: which sample part to search.
- Name of created variable. Where the result goes.
- Left boundary. The text just before the value.
- Right boundary. The text just after the value.
- Match No. Which match to keep, with the same meaning as before.
- Default value. What to store when nothing is found.
Why People Like It
Strengths
- No special characters to escape
- Easy to read by a beginner
- Usually faster than a complicated pattern
- Works well for simple surrounded values
Limits
- Cannot describe the shape of a value
- Needs fixed text on both sides
- Cannot join several groups into one result
- Gets confused if boundaries repeat in odd places
Think of reading the words between two bookmarks in a book. You do not need a clever rule. You only need to know where the first bookmark is and where the second bookmark is, and everything between is your answer.
14The JSON Extractor
Many modern interfaces answer in JSON, a tidy text format of names and values. The JSON Extractor knows how to read it.
What JSON Looks Like
JSON is a text format in which information is organised as named fields, lists, and nested groups. A login answer might contain a field called token with a long string as its value, and a field called user containing further fields such as name and id. Programs love JSON because it is easy to read by machine.
JSON Paths
A JSON path is an address inside a JSON document. It starts at the top, follows field names downward, and can pick items out of lists by position or condition. Pointing at the token field means writing a path that names it. This is much more reliable than searching for text around it, because the path follows the structure, not the spacing.
Its Main Settings
| Setting | Meaning |
|---|---|
| Names of created variables | One or more variable names, separated by a semicolon |
| JSON Path expressions | One address per variable, in the same order |
| Match No. | Which match to keep, with the same meaning as before; negative one keeps all |
| Compute concatenation variable | When keeping all matches, also build one combined variable that joins them |
| Default values | One default per variable, used when the path finds nothing |
Why It Beats Text Searching for JSON
- Immune to spacing. Extra spaces or line breaks in the answer do not matter.
- Immune to field order. If the server lists fields in a different order, the path still works.
- Handles nesting and lists. You can reach into deep structures or pick the third item of a list.
- Several values at once. One extractor can fill several variables.
JMeter also has a JSON JMESPath Extractor, which uses a different path language with its own strengths in filtering and reshaping. The idea is the same: point at the value by structure.
15The CSS Selector Extractor
For web pages built with HTML, the CSS Selector Extractor points at elements the same way a style sheet does.
HTML and Selectors
A web page is built from elements, such as headings, links, forms, and hidden fields, each with names, classes, and attributes. A CSS selector is a short expression that picks elements by their tag, name, class, or position. Web designers use selectors to decide how elements look. The extractor reuses the same idea to pick the element you need and read from it.
Its Main Settings
- CSS selector expression. Describes which element to pick.
- Attribute. Which attribute of the element to read, such as the value of a hidden field or the address of a link. If left empty, the visible text of the element is returned.
- Match No. Which matching element to keep, with the same meaning as before.
- Default value and variable name. As with other extractors.
Typical Uses
- Reading the value of a hidden form field, such as a security token.
- Reading the address of a link to follow next.
- Reading the text inside a heading or message to confirm what the page says.
- Choosing a random item among several elements of the same kind.
Giving someone directions to a book in a library by saying “second shelf, green section, third book from the left” is more reliable than saying “the book near the window,” because shelves keep their layout even when other things move. A selector gives structural directions to an element.
Your browser’s developer tools can show the exact element and its attributes on a real page. Use them to design a selector, and then confirm it against the raw response JMeter received, which may differ from what the browser shows after scripts have run.
16The XPath Extractor
For XML answers, and for tidy pages, XPath gives a precise address inside a tree of elements.
XML and XPath
XML is another text format built from nested elements with names and attributes. It is common in older services and in many business integrations. XPath is an address language for XML: it describes a route through the tree of elements, such as “the status element inside the response element inside the envelope.”
Main Settings
- Use Tidy. When on, JMeter first cleans up an untidy HTML page so it can be read like a tree. Useful for pages that are not perfectly formed.
- XPath query. The address to follow.
- Return entire XPath fragment instead of text content. Choose whether to get the whole element or just its text.
- Match No., variable name, and default value. As with other extractors.
- Namespace handling. XML documents may use namespaces, which are prefixes that group element names. If the document uses them, the query must account for them or it will find nothing.
XPath Versions
JMeter has a standard XPath Extractor and a newer one for a later version of the language, called the XPath2 Extractor. The later version offers more functions. Many tests need only the simple one.
Common Problems
| Symptom | Likely Cause |
|---|---|
| Nothing found on a document that clearly has the element | A namespace is in use and is not handled |
| Parsing errors on an HTML page | The page is not well formed; try the Use Tidy option |
| Whole element returned instead of a simple value | The fragment option is switched on |
| Value found in a browser but not in JMeter | The browser built the element with scripts after loading |
17Script-Based Post-Processors
When no ready-made extractor fits, you can write a small program. Use this power sparingly.
The JSR223 Post-Processor
The JSR223 Post-Processor lets you run a script after a sampler. The script can read the response, the headers, the variables, and the properties, do calculations, and write new variables. It can convert formats, build a value from several pieces, make decisions, and handle special cases that no other extractor covers. It supports several programming languages, and the recommended one is Groovy, which is fast when scripts are cached.
The BeanShell Post-Processor
The BeanShell Post-Processor is an older scripting element. It is still present for older test plans, but it is slower and is not recommended for new work. Prefer the JSR223 version.
When Scripts Make Sense
- Calculating a value from several parts, such as a signature or a checksum.
- Reformatting a value, such as changing a date format.
- Picking an item by a rule that no extractor supports.
- Reading a complicated response in a custom way.
The Costs of Scripts
Benefits
- Unlimited flexibility
- One element can replace several
- Fast when the script is compiled and cached
Drawbacks
- Harder to read and maintain
- Mistakes can crash a sampler or slow the test
- Scripts from unknown sources can be unsafe
- Requires programming skill from every maintainer
Choose a built-in extractor whenever it can do the job. Built-in extractors are clearer to the next person and are tuned for speed. Keep scripts for the cases where nothing else fits, and keep them short.
18Other Post-Processors Worth Knowing
Not every Post-Processor is an extractor. A few others solve different problems.
Debug PostProcessor
Adds the current JMeter variables, and optionally properties and system settings, to the sample so you can read them in a results viewer. Excellent while building. Remove it before large runs.
Result Status Action Handler
Decides what to do when a sampler fails: carry on, start the next loop, stop that thread, or stop the test. It turns failures into controlled behaviour.
JDBC PostProcessor
Runs a database statement after a request. Useful for cleaning up test data or checking a stored result.
JSON JMESPath Extractor
A JSON reader using another path language, with strong filtering abilities.
XPath2 Extractor
A reader for XML using the newer version of the XPath language.
BeanShell and JSR223 PostProcessors
Script-based elements for custom logic, with JSR223 preferred.
A Note on the Debug PostProcessor
When you are unsure whether a variable holds what you expect, add this helper under the sampler and run one user. In the result viewer, you will see a list of all variables and their values at that moment. It removes the guesswork. Remember that it makes every sample larger, so take it out before a big run.
Menus and element names can differ slightly between JMeter versions. Open the Post Processors menu in your own version and read the list, rather than assuming it matches this chapter exactly.
19Choosing the Right Post-Processor
Many tools can do the same job. The best one is the simplest that stays reliable.
flowchart TD
Q["I need a value from a response"] --> A{"What format is the response?"}
A -->|"JSON data"| J["JSON Extractor"]
A -->|"XML data"| X["XPath Extractor"]
A -->|"HTML page"| B{"Is the value in an element or attribute?"}
A -->|"Plain text or mixed"| C{"Is the value between two fixed texts?"}
B -->|"Yes"| CS["CSS Selector Extractor"]
B -->|"No"| C
C -->|"Yes"| BE["Boundary Extractor"]
C -->|"No, the shape matters"| RE["Regular Expression Extractor"]
RE --> D{"Needs calculation or special logic?"}
BE --> D
D -->|"Yes"| JS["JSR223 PostProcessor"]
D -->|"No"| OK["Keep the simple extractor"]
Reading the Diagram
First look at the format of the response. If it is JSON, use the JSON Extractor. If it is XML, use the XPath Extractor. For an HTML page, a CSS selector is excellent when the value sits in an element or attribute. If the value is simply surrounded by fixed text, the Boundary Extractor is the easy choice. When the shape of the value matters, use the Regular Expression Extractor. Only when calculation or special logic is truly needed should you reach for a script.
Quick Comparison
| Extractor | Best For | Strength | Weakness |
|---|---|---|---|
| Regular Expression | Any text | Most flexible search | Fragile and harder to read |
| Boundary | Values between fixed texts | Simple and quick | Cannot describe shapes |
| JSON | JSON answers | Follows structure | Only for JSON |
| CSS Selector | HTML elements and attributes | Follows page structure | Reads only what the server sent |
| XPath | XML answers | Precise addressing | Namespaces can confuse |
| JSR223 | Custom logic | Unlimited flexibility | Harder to maintain |
20Apply To and Field to Check
Two settings decide exactly which text an extractor reads. Mistakes here cause many “pattern not found” puzzles.
Apply To
| Choice | What Is Searched | Typical Use |
|---|---|---|
| Main sample and sub-samples | The page and the extra files it loaded | Broad searching |
| Main sample only | The page or request itself | The usual choice |
| Sub-samples only | The nested samples, such as embedded files | Reading from a loaded script or style file |
| JMeter variable | The text stored in another variable | A second step of extraction |
Searching a Variable
The variable option makes two-stage extraction possible. A first extractor may pull out a long block of text. A second extractor, set to search that variable, then pulls a small value out of the block. This is easier to understand than one giant pattern, and it can be faster when the big block is small compared with the whole page.
Field to Check
- Body. The normal choice for the response text.
- Body (unescaped). The body with certain encoded characters turned back into plain ones.
- Body as a document. The text pulled out of a file such as a PDF or an office document.
- Response headers. The metadata lines the server sends before the body, where redirects, cookies, and locations often hide.
- Request headers. What JMeter sent, useful for checking.
- URL. The final address, useful after redirects.
- Response code and message. The numeric code and its text.
If you look in the body for a value that actually travels in a header, the extractor finds nothing. When the value is not in the body, check the response headers before suspecting the pattern.
21Default Values: The Safety Net and the Hiding Place
What an extractor stores when it finds nothing is one of the most important choices you make.
What Happens When Nothing Matches
When the extractor cannot find the value, it does not stop the test and does not mark the sample as failed. It simply stores the default value in the variable, or leaves the variable empty if none is given. The test then carries on and sends that default to the next request. The extractor reports no error.
Why This Is Dangerous
If the default is empty or sensible-looking, the next request quietly sends a bad value. The server rejects it, perhaps with a success code and an error page, and the test continues. Without checks, the report shows a healthy test, while every later step has been silently failing.
The Remedy: A Clearly Fake Default
Give each extractor a default that nobody could mistake for a real value, such as the word NOT_FOUND. If you ever see that word in a request, in a log, or in a failed response, you know at once that the extraction failed. A clear default turns a silent problem into a visible one.
| Default Choice | Result When Extraction Fails | Verdict |
|---|---|---|
| Leave empty | Requests carry blank values; failures look like server bugs | Poor |
| A realistic-looking value | Requests carry plausible but wrong values; very hard to spot | Poor |
| A clearly fake word such as NOT_FOUND | The word shows up in logs and requests | Good |
| Fake word plus an assertion | The failing sample is flagged immediately | Best |
Use one agreed default word across the whole team. Then a quick search for that word through a results file or a log reveals every failed extraction in one step.
22Guarding Extractions With Assertions
An assertion placed beside an extractor turns a missing value into a clear, counted failure at the exact step that caused it.
How the Guard Works
Because assertions run after post-processors, an assertion can check the variable the extractor has just filled. Using the assertion’s option to apply to a JMeter variable, you can require that the variable is not equal to your fake default and is not empty. If the check fails, JMeter marks that very sampler as failed and records your message.
Sampler Gets a Response
The login request returns a response that should hold a session id.
Extractor Stores the Value
It writes the session id, or the fake default, to the variable.
Guard Assertion Checks the Variable
It confirms the variable is not the fake default and not empty.
Failure Is Counted at the Right Place
If the check fails, the login step shows an error, and the report points at the true cause.
Why This Matters So Much
Without the guard, a missing session id produces a long chain of failures in later steps, and each looks like a different problem. With the guard, there is one clear failure at the beginning of the chain. Debugging time falls from hours to minutes.
Write the assertion’s failure message in plain words, such as “Login: session id was not captured.” Anyone reading a report can then see immediately what went wrong.
23Extracting Many Values and Looping Over Them
Sometimes a response contains a whole list, such as search results, and the test must visit each item.
Keeping All Matches
When the match number is set to negative one, the extractor keeps every match. It creates numbered variables, one for each item, and a count of how many were found. A search that returned five products gives you five stored ids and the number five.
The ForEach Controller
A ForEach Controller repeats the elements inside it once for every numbered variable of a given family. You tell it the common name of the variables and the range, and it fills an output variable with each value in turn. Inside it, a request that uses the output variable visits each product in order.
| Goal | Match No. | Follow-Up |
|---|---|---|
| Use the first result | 1 | Use the plain variable in the next request |
| Use a random result | 0 | Use the plain variable; each user picks different items |
| Use the third result | 3 | Make sure at least three results exist |
| Visit every result | -1 | Loop with a ForEach Controller over the numbered variables |
Realistic Behaviour
Real visitors rarely open every item in a list. They look at one or two. Choosing a random match makes the test more lifelike and spreads load across many items, instead of hammering the first one in the list. This also avoids unrealistic caching, where the same item is requested over and over and served from memory.
Beware of Stale Numbered Variables
If the first search returned ten results and a later one returns only three, the old numbered variables four to ten may still hold values from earlier. Use the stored count, not a guess, to decide how many items to loop over.
24Values in Headers, Redirects, and Addresses
Not all useful values live in the page body. Some hide in the metadata around it.
Response Headers
The server sends lines of information called headers before the body. Some contain tokens, such as an authorisation value, and some contain addresses, such as the location of a newly created record. To read them, set the field to check to the response headers.
Redirects
Sometimes a server answers a request by saying “go to this other address.” JMeter’s HTTP sampler can follow redirects automatically. When it does, the final sample may be the destination, and values you want could sit in the address itself. Setting the field to check to the URL lets you read parameters from that final address, such as a code or an identifier added to the query part.
Cookies
Session cookies are normally handled for you by the HTTP Cookie Manager, which stores and sends cookies automatically. You usually do not need an extractor for ordinary cookies. You need one only when a value from a cookie must be used somewhere unusual, such as inside a request body.
Where to Look
| Where the Value Hides | Field to Check |
|---|---|
| Inside the page or data | Body |
| In an authorisation or location line | Response headers |
| In the address after a redirect | URL |
| In a status line or code | Response code or message |
| Inside an earlier stored variable | Apply to a JMeter variable |
When a value cannot be found in the body, open the response headers tab in the results viewer. Many beginners spend an hour fixing a pattern when the value was in a header all along.
25Debugging Extractions
When a value is not captured, a calm routine finds the cause quickly.
The Tools
- View Results Tree. Shows each request and the full response. Use it with one user to read the actual text.
- Debug PostProcessor. Lists all variables and their current values in the sample.
- Regular Expression Tester. Inside the View Results Tree, a tester lets you try a pattern against the response and see what it finds.
- The log file. JMeter writes warnings about scripts and extractors that could not do their job.
A Step-by-Step Routine
Run One User, One Loop
A single sample is easier to study than thousands.
Open the Real Response
Read what the server actually returned. Is it the page you expected, or an error page?
Find the Value by Eye
Search the text for the value. If it is absent, the problem is upstream, not in your pattern.
Test the Pattern in the Tester
Try the pattern against the response and see whether it finds the value.
Check the Variable
Use the Debug PostProcessor to see whether the variable received the value or the default.
Check the Next Request
Confirm in the request details that the variable was substituted into the right place.
The most common reason an extractor fails is that the response is not what you think. An expired session or a validation error can return an entirely different page in which the value does not exist. Always read the response first.
26Performance Cost of Post-Processors
Every extractor uses processor time on the test machine. At large scale, those small costs add up.
Where the Cost Comes From
- Large responses. Searching a huge page takes longer than searching a small one.
- Complex patterns. Some patterns are very slow on certain texts, especially those with nested repetition.
- Wide scope. An extractor high in the tree runs after every sampler beneath it.
- Many extractors. Each repeats a search over the same response.
- Scripts. Uncached or heavy scripts can be very expensive.
- Debug helpers. They enlarge every sample and slow listeners down.
How to Keep Costs Low
Keep the Scope Narrow
Place each extractor directly under the sampler it serves.
Prefer Structure Over Search
Use JSON, CSS, or XPath extractors for structured data instead of text searches.
Use Simple Patterns
Short landmarks and lazy matching are fast and stable.
Remove Debug Helpers
Take them out of the plan before the real run.
If the test machine runs out of processor power, requests leave late and the response times you report include that delay. Watch the load generator’s own health as part of the evidence.
27Post-Processors With Controllers and Loops
Controllers decide which samplers run and how often. Post-Processors must fit into that flow.
If Controllers
An If Controller runs its contents only when a condition is true. If an extractor feeds a variable that later steps depend on, and the If Controller skips the sampler that holds the extractor, the variable keeps its old value or was never created. Make sure the condition and the extraction match up.
Loop Controllers and Thread Group Loops
When a journey repeats, each pass should extract fresh values. If an extraction fails in the second pass, the variable keeps the value from the first pass, and the test silently reuses a stale ticket. To prevent this, use a guard assertion, or reset the variable to the fake default at the start of each pass with a pre-processor or a user-defined variable step.
Transaction Controllers
A Transaction Controller groups requests into one business step. Extractors inside it work as normal. If a guard assertion fails inside the transaction, the whole transaction is marked failed, which gives a clear business-level error rate.
Common Combinations
| Combination | Effect | Care Needed |
|---|---|---|
| Extractor in a loop | Fresh value each pass | Guard against stale values from earlier passes |
| Extractor under an If Controller | Extracts only when the branch runs | Later steps may depend on a variable that never got set |
| Extractor inside a Transaction Controller | Value captured within a business step | A failed guard fails the whole step |
| ForEach over extracted list | One request per item | Use the stored count to avoid stale items |
28Naming Variables Well
A good name saves hours when a test grows to dozens of correlations.
Rules for Good Names
- Describe the content. A name like orderNumber is better than var1.
- Stay consistent. Pick one style, such as starting with a lower-case word and capitalising each following word, and use it everywhere.
- Avoid clashes. Do not reuse a name for two different values in the same journey.
- Avoid special characters. Letters, digits, and underscores are safe.
- Mark the source. A prefix such as login_ shows which step produced the value.
- Remember case. Names are case sensitive, so the later request must spell it identically.
Name the Elements Too
Besides naming variables, rename each Post-Processor in the tree so it says what it extracts, such as “Extract session id from login.” When someone reads the tree, they can then understand the data flow without opening every element.
Keep a Correlation Table
For large tests, keep a small table in your notes with four columns: the variable name, the step that creates it, the steps that use it, and the way it is extracted. When the application changes, you can see at a glance which extractors might be affected.
| Variable | Created By | Used By | Method |
|---|---|---|---|
| loginToken | Open login page | Submit login | CSS selector on hidden field |
| sessionId | Submit login | Every later request | JSON extractor |
| productId | Search | Add to basket | JSON extractor, random match |
| orderNumber | Create order | Pay and confirm | Boundary extractor |
29Types of Dynamic Values You Will Meet
Knowing what dynamic values look like helps you spot them in a recording.
| Type | What It Is | Where It Often Hides | Usual Extractor |
|---|---|---|---|
| Session id | Identifies a logged-in visitor | Cookie, header, or response body | Header or JSON extractor; cookie manager for cookies |
| Security token | Protects forms from forged submissions | Hidden form field or meta element | CSS selector |
| Bearer token | Proves login to an interface | JSON answer of the login call | JSON extractor |
| Record id | Number of a newly created item | Body or location header | JSON, boundary, or header extraction |
| Page state | Hidden data some frameworks pass between pages | Hidden fields | CSS selector or regular expression |
| Timestamp or nonce | A time or single-use number | Form fields or scripts | Often generated by a function or script instead |
| Link addresses | Addresses that change per visitor | Anchors in a page | CSS selector |
Not Everything Needs Extraction
Some dynamic values are created by the client, not the server. A timestamp or a random number can often be produced by JMeter’s built-in functions or a pre-processor, with no need to extract anything. Ask whether the value came from the server or was made by the browser. Extract only the first kind.
Look for long, random-looking strings in a recorded request. If they changed between two recordings, they are dynamic. Then find where each first appeared in an earlier response, and extract it there.
30Handling Failures With the Result Status Action Handler
Not every Post-Processor reads data. This one decides what the test should do when a request has failed.
What It Does
The Result Status Action Handler looks at whether the sampler it is attached to succeeded or failed. If the sampler failed, it triggers an action that you choose. This gives you control over the flow of the test when something goes wrong, at the exact place where it went wrong.
The Choices
| Action | Effect | Good For |
|---|---|---|
| Continue | Keep going as if nothing happened | Load tests where users should keep trying |
| Start next thread loop | Abandon the rest of this pass and begin the next one | When a failed login makes later steps pointless |
| Stop thread | End that one virtual user | When a user cannot continue and should leave |
| Stop test | End the whole test gently, letting running samples finish | When a failure means the whole test is invalid |
| Stop test now | End the whole test immediately | Serious problems where continuing would do harm |
How It Relates to the Thread Group Setting
The Thread Group also has a setting that decides what to do after a sampler error, and it applies to every sampler in the group. The Result Status Action Handler is more precise: it applies only within its own scope. You can let most requests continue after errors, while forcing a stop for the one step that matters, such as login.
If a factory worker finds a faulty part, the plant must decide what to do. The worker may set the part aside and keep working, stop the machine, or stop the whole line. A general company rule is a blunt tool. The handler is a specific instruction written for one station only.
The handler reacts to the sampler’s failed status. An extractor that finds nothing does not make the sampler fail on its own. Pair the extractor with a guard assertion, and the handler can then act on the missing value.
31Post-Processors in Distributed Testing
When several machines generate load, each runs its own copy of every Post-Processor.
How It Works
In distributed mode, a controller machine sends the Test Plan to several worker machines. Each worker runs the whole plan with its own virtual users, including all extractors. Variables belong to each user on each worker. A token captured by a user on worker one is never seen by users on worker two, which is exactly right.
Points to Remember
- Same plan everywhere. Every worker must have the same plan, so the same extractors run.
- Supporting files must exist on each worker. If a script or a data file is used, it must be present at the same path on every machine.
- Variables are not shared. A variable lives with one user. To share data across users or workers, you need other mechanisms.
- Worker health matters. An overloaded worker may run its scripts slowly and delay requests.
- Scripts must be thread safe. Many users run the same script at the same time, so a script must not rely on shared state that users could overwrite.
If extraction failures appear only on one worker, suspect that machine first: its data files, its software version, or its resources. Failures on every worker at once usually point to the application or the pattern.
32Monitoring, Logging, and Metrics
Extractions fail quietly. You need signals that make failures visible during and after a run.
What to Watch
- Guard assertion failures per label. These tell you which extraction fails and how often.
- The fake default word in logs and requests. A search for it counts failed extractions.
- Error percentage by step. A sudden jump on a step right after an extraction step often points at correlation trouble.
- Response sizes. A drop in the average size of a response often means error pages are replacing real content.
- Load generator health. Processor and memory, since scripts and large searches consume them.
Logging Without Drowning
Script-based post-processors can write to JMeter’s log. Log only unusual events, such as a missing value or an exception. Writing a line for every sample fills the disk and slows the test.
Sending Metrics Elsewhere
A Backend Listener can stream results to an external system, where dashboards show error counts live. If guard assertions have clear failure messages, those messages become readable labels in the dashboard, and anyone can see that “session id not captured” jumped at ten past two.
A car’s dashboard has warning lights. The engine may be struggling long before it stops, but without a light, you would not know. Guard assertions and clear defaults are the warning lights of your correlation.
33Security and Safety Considerations
Extractors handle the most sensitive values in a test: sessions, tokens, and identifiers.
What Can Go Wrong
- Tokens in result files. If you save request details, extracted tokens and session ids appear in the files.
- Tokens in logs. A script that prints a variable to the log writes a credential into a text file.
- Secrets in the plan. Passwords or keys typed into extractor settings or scripts are shared with everyone who sees the plan file.
- Debug helpers. The Debug PostProcessor lists every variable, including tokens, in the result.
- Scripts from unknown sources. A script runs code on the test machine.
Good Habits
- Use synthetic test accounts and fake data, never real customer records.
- Do not print tokens or passwords to logs.
- Remove debug helpers before sharing results or running large tests.
- Keep plans and result files in access-controlled storage.
- Review every script before running a plan from another team or an unknown source.
- Delete result files that contain tokens when they are no longer needed.
- Test only systems you own or have written permission to test.
Tokens Expire
Tokens captured in a test are real credentials for the test system. Use test environments and short-lived tokens. If a log or result file with tokens is leaked, short lifetimes limit the damage.
A Post-Processor can also verify safety properties, such as extracting a role from a response and checking that an ordinary user never receives administrator rights. That is a useful light check, but it never replaces proper security testing.
34Advantages, Disadvantages, and Trade-Offs
Post-Processors are essential, and they come with costs.
Advantages
- Make realistic multi-step journeys possible
- Give every user their own correct tokens and ids
- Many ready-made kinds for different formats
- Allow random selection for lifelike behaviour
- Support looping over lists of results
- Can control the flow after failures
- Scripts allow any custom logic
Disadvantages
- Fail silently by default when nothing matches
- Fragile when pages or formats change
- Use test-machine resources on every sample in scope
- Patterns are hard for beginners to write and read
- Need maintenance as the application changes
- Scripts add risk and demand programming skill
Key Trade-Offs
| Choice | One Side | The Other Side |
|---|---|---|
| Simple vs flexible | Boundary and structured extractors are clear and quick | Regular expressions and scripts handle odd cases but are fragile |
| Narrow vs broad scope | Narrow is fast and safe | Broad is convenient but costly and risky |
| Strict vs lenient defaults | A fake default exposes problems at once | An empty default hides problems |
| Built-in vs script | Built-in elements are readable and maintained by everyone | Scripts are powerful but need skilled owners |
A sensible middle path is the simplest extractor that fits the response format, with narrow scope, a clearly fake default, and a guard assertion beside it.
35Design Patterns and Anti-Patterns
Teams that build large test suites keep discovering the same good habits and the same traps.
Good Patterns
Extract, Guard, Use
Extract the value, assert that it exists, then use it. Three small steps, one reliable chain.
Fake Default
A shared, obviously fake default word that makes failures visible.
Structure First
Choose JSON, CSS, or XPath extractors when the response has structure.
Narrow Scope
One extractor under the one sampler that needs it.
Correlation Table
A short written list of every variable, its source, and its users.
Random Choice
Pick random items from lists to imitate varied real users.
Anti-Patterns
What Happens
A recorded script is replayed with the old tokens and ids still inside.
Why It Hurts
The server rejects the stale values, and the test measures error pages.
Better Approach
Find every dynamic value and extract it from the response that first produces it.
What Happens
Extractors use an empty or realistic-looking default, with no assertion.
Why It Hurts
Missing values travel onward unseen, and later failures look unrelated.
Better Approach
Use a clearly fake default and a guard assertion.
What Happens
A very long, exact pattern describes a large part of the page.
Why It Hurts
Any small change in the page breaks it, and it is slow and unreadable.
Better Approach
Use short, stable landmarks, or switch to a structured extractor.
What Happens
An extractor is placed at the Thread Group level to save effort.
Why It Hurts
It runs after every sampler, wastes time, and can overwrite good values with defaults.
Better Approach
Attach it directly to the one sampler that returns the value.
What Happens
Every extraction is written as a script, even simple ones.
Why It Hurts
Only a few people can maintain the plan, and mistakes are harder to find.
Better Approach
Use built-in extractors first and scripts only when nothing else fits.
36Best Practices and Common Mistakes
A short list that separates calm, dependable correlation from endless debugging.
Best Practices
- Correlate before you scale. Make one user work perfectly before adding more.
- Pick the right extractor for the format. JSON for JSON, CSS or XPath for markup, boundary for simple text.
- Keep scope narrow. Under the sampler that returns the value.
- Use a clearly fake default and guard every important extraction with an assertion.
- Name things clearly. Variables and elements should say what they hold.
- Test patterns against real responses, including empty and error cases.
- Remove debug helpers before big runs.
- Document the correlations in a short table.
- Review after each application change. Pages change, and extractors must follow.
Common Mistakes
| Mistake | Consequence | Fix |
|---|---|---|
| Misspelled variable name in the next request | The literal text is sent instead of a value | Copy the exact name, remembering case |
| Extractor placed under the wrong sampler | It reads a response that lacks the value | Attach it to the sampler that returns the value |
| Using the value in the same request | The value is not yet extracted | Extract in an earlier request |
| Special characters not escaped in a pattern | The pattern matches nothing | Escape them, or switch to boundaries |
| Wrong match number | The wrong item, or no item, is chosen | Check how many matches exist and which you need |
| Searching the body for a header value | Nothing found | Set the field to check correctly |
| Stale values in loops | Old tokens are reused silently | Reset or guard each pass |
| Debug helper left on | Slow test and leaked tokens | Remove before real runs |
37Real-World Examples
These are teaching illustrations of common situations. They are not descriptions of any particular company’s setup.
An Online Shop With Form Protection
Each form carries a hidden security code. A CSS selector extractor reads the code from the login page, and the login request sends it back. A guard assertion confirms the code was found, so a layout change on the page is detected at once.
A Mobile Application Interface
The login call returns JSON with an access token. A JSON extractor stores it, and every later request carries it in a header. Because the token expires, the test also checks for an “unauthorised” response and re-logs in when it appears.
A Ticket Booking Flow
A search returns a list of events. A JSON extractor with a random match picks one event per user, and a second extractor reads the seat map identifier from the next response. Different users pick different events, so load spreads across the catalogue.
An Order Creation Interface
Creating an order returns the new order’s address in a response header. A header-based extractor reads it, and later steps pay, confirm, and fetch the order using that address.
A Legacy XML Service
An older integration wraps everything in XML envelopes with namespaces. An XPath extractor with the namespace handled reads the transaction reference, and later calls quote it.
A Signed Request
An interface requires each request to carry a signature calculated from the body and a secret key. No ready-made extractor can calculate it, so a short script element builds the signature before each call. Here, a script is justified because nothing simpler can do the job.
38Step-by-Step: Correlating a Real Journey
A repeatable recipe that works for almost any recorded journey.
Record the Journey Twice
Use the same steps and different test accounts, so differences stand out.
Compare the Requests
List the values that differ between the two recordings. These are the dynamic values.
Find Each Source
For each dynamic value, find the earliest response that contains it.
Choose an Extractor
Use the format of that response to pick the simplest suitable extractor.
Configure It Carefully
Name the variable, set the pattern or path, the match number, and a clearly fake default.
Add a Guard Assertion
Check that the variable is not the fake default.
Replace the Fixed Values
In every later request that used the old value, write the variable name instead.
Run One User and Check Everything
Confirm that every step passes and that the variables hold what you expect.
Scale Up Gradually
Add users in steps, watching for new failures that only appear under load.
39A Worked Example: Login, Search, Order
Let us design the Post-Processors for a small shop journey, using invented details to teach the method.
The Journey
A visitor opens the login page, submits credentials, searches for a product, and creates an order. Four requests, four possible hidden values.
| Request | Dynamic Value Needed Next | Post-Processor | Guard |
|---|---|---|---|
| 1. Open login page | Hidden security code in a form field | CSS Selector Extractor reading the field’s value attribute | Variable must not equal the fake default |
| 2. Submit login | Session token in the JSON answer | JSON Extractor on the token field | Variable must not equal the fake default |
| 3. Search products | A product id from the results list | JSON Extractor with a random match | Variable must not equal the fake default |
| 4. Create order | Order number for payment | Boundary Extractor between two fixed texts | Variable must not equal the fake default |
What Happens When Something Breaks
Imagine the developers rename the hidden security field on the login page. The CSS selector now finds nothing, and the variable holds the fake default NOT_FOUND. The login submission sends that word, and the server rejects it, probably with an error page that still has a success code.
Without a guard, the report would show a healthy-looking test, but every later step would fail. With the guard, the very first request is flagged, with a message such as “Login page: security code not captured.” The cause is clear, and the fix takes minutes: update the selector to the new field name.
What We Learned
- Four small extractors carry the whole journey.
- Each uses the simplest suitable extractor for its response format.
- Each has a guard, so failures appear where they begin.
- The random match in the search step gives each user a different product.
40Troubleshooting Extraction Problems
When a value is not captured or not used, a fixed path of questions finds the cause fast.
flowchart TD
S["Later request fails or carries a wrong value"] --> A{"Does the variable hold the fake default or the variable name text?"}
A -->|"Variable name text appears"| N["Check spelling and case of the name; check the extractor ran earlier"]
A -->|"Fake default appears"| B{"Does the earlier response contain the value?"}
A -->|"A real but wrong value"| W["Check match number, scope, and whether an earlier value was overwritten"]
B -->|"No, it is an error page"| R["Fix the earlier request: login, data, or session problem"]
B -->|"Yes"| C{"Is the extractor under the right sampler?"}
C -->|"No"| M["Move it under the sampler that returns the value"]
C -->|"Yes"| D{"Does the pattern, path, or selector find it in the tester?"}
D -->|"No"| P["Rewrite it using text copied from the real response"]
D -->|"Yes"| F["Check field to check and apply to settings"]
Reading the Diagram
Start with what the failing request actually carried. If you see the literal variable name, the variable was never created or is spelled differently. If you see your fake default, the extractor ran but found nothing, so ask whether the response really contained the value. If it did not, the problem lies upstream. If it did, check the position of the extractor, the pattern, and the field being searched. If the variable holds a real but wrong value, look at the match number and scope.
Common Symptoms and Causes
| Symptom | Likely Cause | What To Do |
|---|---|---|
| Works for one user, fails under load | The server returns different pages under pressure, such as busy or error pages | Read failed responses and add content assertions |
| Works in the browser, fails in JMeter | Value created by page scripts, not present in the raw response | Find the call that supplies it and extract from that response |
| Works first time, fails on later loops | Stale variable or changed page flow | Reset variables and guard each pass |
| Wrong item chosen | Match number does not suit the page | Count matches and choose deliberately |
| Extractor finds an empty string | Pattern captured nothing between landmarks | Widen the capture or revise the landmarks |
| Test becomes slow | Heavy patterns or wide scope | Narrow the scope and simplify the pattern |
41Terms People Often Confuse
Several pairs of ideas look alike and behave differently. Knowing the difference saves hours.
Post-Processor vs Pre-Processor
A post-processor runs after the request, on the response. A pre-processor runs before the request, to prepare it.
Post-Processor vs Assertion
A post-processor reads or stores data and does not judge. An assertion judges the response and marks pass or fail.
Extractor vs Variable
The extractor is the element that finds the value. The variable is the box where the value is kept afterwards.
Variable vs Property
A variable belongs to one virtual user. A property is global to the whole JMeter run and shared by all.
Regular Expression vs Boundary
A regular expression describes the shape of a value. A boundary names the text on either side of it.
Match No. 0 vs -1
Zero picks one random match. Negative one keeps all matches in numbered variables.
Default Value vs Failure
Storing a default is not a failure. The sample still passes unless a guard assertion marks it failed.
Cookie Manager vs Extractor
The cookie manager handles ordinary cookies automatically. An extractor is needed only to move a value somewhere unusual.
When two terms sound alike, test both on a tiny example. A few minutes of experimenting beats an hour of guessing.
42A Case Study: The Test That Passed Without Logging In
This is a composed story built to teach. It is an illustration, not an account of a real team.
The Situation
A team load-tested a members’ portal before a major release. Their report was calm: no errors, response times well inside the goal, and a smooth throughput line. They announced the release was safe.
The Doubt
Two days after launch, members complained that pages were slow. A developer compared the test with real traffic and noticed something odd. The test’s response sizes were tiny, far smaller than the pages members actually saw.
The Investigation
Replay With One User
They ran one user and opened the results viewer. Every “member page” in the test was actually the login page, returned with a success code.
Find the Cause
The login step used a session id extractor whose pattern no longer matched after an earlier release changed the page. The extractor stored an empty default, and every later request went out without a session.
Fix the Extractor
They replaced the fragile text pattern with a JSON extractor that followed the structure, and used a clearly fake default.
Add Guards
They added a guard assertion on the session variable and content assertions on the member pages.
Rerun the Test
With real member pages, response times were much longer, and the true capacity problem became visible and fixable.
The Lesson
The old test had measured how fast the login page could be served to people who were not logged in. It had never touched the heavy member pages. One silent extraction failure made the whole test meaningless, while every number looked healthy.
43Post-Processors in Automated Pipelines
When tests run on their own after each change, correlation must be dependable without a person watching.
Why Pipelines Raise the Stakes
In a pipeline, nobody opens the results viewer. A test whose extractions silently fail may pass every automatic check, and the pipeline then approves a release that was never truly tested. Guard assertions and clear failure messages are the only voice the test has.
Practices for Pipelines
- Always guard important extractions. A missing token should fail the build, not pass quietly.
- Check the fake default. A step after the run can search the results for the fake default word and fail if any appear.
- Check response sizes. A large drop against the previous run is a good alarm for hidden errors.
- Use properties. Pass server names, accounts, and options as settings, so the same plan serves every environment.
- Use stable test data. Fresh accounts or reset data keep extractors from meeting unexpected states.
- Run a short smoke test first. One user, one loop, checking all correlations before the heavier run starts.
A night watchman who falls asleep is worse than no watchman, because everyone believes the building is guarded. A pipeline test with silent extraction failures is a sleeping watchman. Guards keep him awake.
44Maintaining Extractors as the Application Changes
Applications keep changing, and an extractor that works today may break after the next release.
Why Extractors Go Stale
Developers rename fields, reorder markup, change the format of an identifier, or move a value from the body to a header. Text-based patterns are the most fragile, because they depend on exact surrounding words and spacing. Structure-based extractors are sturdier, but they also break when names change.
Habits That Keep Extraction Healthy
- Prefer structure over text. Paths and selectors survive cosmetic changes better than text patterns.
- Ask developers for stable markers. A stable identifier on an element is a gift to testers.
- Run a smoke test after every release. One user and one loop will reveal broken correlations in minutes.
- Keep the correlation table current. It shows which extractors to review when a page changes.
- Read guard failures as news. A new “token not captured” message after a release is a clear pointer to the change.
- Keep plans in version control. A history of changes shows who altered which extractor and why.
Telling Real Problems From Stale Extractors
Do the Step by Hand
Use a browser and repeat the step. If a person succeeds, the extractor may be stale.
Compare the Responses
Look at the new response beside an older saved one and find what changed.
Update or Report
If wording or structure changed, update the extractor. If the server really is failing, report it with evidence.
45Quick Reference
A one-page reminder for the next time you are in a hurry.
| I Need To | Use This | Remember |
|---|---|---|
| Read a value from a JSON answer | JSON Extractor | Point at it with a path |
| Read a hidden field or link from a page | CSS Selector Extractor | Name the attribute to read |
| Read a value from XML | XPath Extractor | Handle namespaces |
| Read text between two fixed markers | Boundary Extractor | Simple and quick |
| Read a value that has a particular shape | Regular Expression Extractor | Lazy matching, escaped special characters |
| Calculate or reformat a value | JSR223 Post-Processor | Short, cached, and a last resort |
| See all variables while debugging | Debug PostProcessor | Remove before big runs |
| Stop or skip after a failure | Result Status Action Handler | Needs the sampler to be marked failed |
| Pick a random item from a list | Any extractor with match number 0 | Makes users varied |
| Visit every item in a list | Match number -1 and a ForEach Controller | Use the stored count |
46Glossary of Terms
Plain-language meanings of the words used in this guide.
| Term | Meaning |
|---|---|
| Post-Processor | An element that runs after a sampler and works on its response. |
| Pre-Processor | An element that runs before a sampler to prepare the request. |
| Extractor | A post-processor that copies a piece of a response into a variable. |
| Sampler | The element that sends a request and records the result. |
| Sample | One recorded request and response. |
| Variable | A named container for a value belonging to one virtual user. |
| Property | A global setting shared across the whole JMeter run. |
| Scope | The set of samplers an element applies to, decided by its place in the tree. |
| Correlation | Catching a dynamic value from one response and using it in a later request. |
| Dynamic value | A value that changes from visit to visit, such as a session id. |
| Session id | A value that identifies a logged-in visitor. |
| Token | A short-lived code that proves identity or permission. |
| Regular expression | A compact pattern language for describing text shapes. |
| Group | A bracketed part of a pattern whose match can be saved. |
| Boundary | A fixed piece of text marking the start or end of a value. |
| JSON path | An address that points to a field inside a JSON document. |
| CSS selector | An expression that picks elements of a web page. |
| XPath | An address language for elements inside XML. |
| Match number | The setting that decides which match to keep. |
| Default value | The text stored when nothing is found. |
| Guard assertion | A check that confirms an extraction succeeded. |
| ForEach Controller | A controller that repeats its contents for each numbered variable. |
| Thread | A virtual user inside JMeter. |
| Load generator | The machine that runs JMeter and creates the load. |
47A Checklist Before Every Important Run
Pilots read a checklist before every flight, however experienced they are. A short list protects a test run in the same way.
Before You Press Start
- Every dynamic value has been found and correlated. Two recordings were compared, and nothing suspicious is left fixed.
- Each extractor sits directly under its sampler.
- Each extractor uses the simplest suitable kind for its response format.
- Each default is clearly fake and the same across the plan.
- Each important extraction has a guard assertion with a clear message.
- Variable names match exactly in every request that uses them.
- One user passes the whole journey, and the variables hold what you expect.
- Debug helpers are removed and heavy listeners are off.
- Scripts are reviewed, short, and free of secrets and log noise.
- The target is permitted, and test accounts and data are synthetic.
After the Run
- Search results and logs for the fake default word.
- Compare response sizes with the one-user baseline.
- Read the earliest failure in each journey, since later ones often follow from it.
- Update the correlation table and the notes for the next run.
Paste this checklist into your team’s notes and tick it for each important run. A habit that takes two minutes can save a day of chasing failures caused by one silent extraction.
48Frequently Asked Questions
After the sampler receives its response, and before assertions and listeners. The value it stores is available to later samplers, but not to the sampler that produced the response.
It stores the default value you set, or leaves the variable empty. It does not fail the sample by itself, which is why a guard assertion is important.
Match the response format. Use the JSON Extractor for JSON, XPath for XML, CSS selector for HTML elements, boundary for text between fixed markers, and regular expressions when the shape matters.
No. The request has already been sent when the extractor runs. Extract in an earlier request, or use a pre-processor if the value must be prepared beforehand.
The name may be misspelled or in a different case, the extractor may not have run before this request, or the extraction failed and the variable was never created.
Set the match number to zero in an extractor that reads the list. Each user then receives a random match.
Set the match number to negative one, and use a ForEach Controller over the numbered variables, using the stored count.
Usually not. The HTTP Cookie Manager stores and sends cookies automatically. Extract only if a cookie value must be used somewhere unusual.
Only when nothing built-in can do the job. Built-in extractors are clearer, safer, and easier for others to maintain.
No. Variables belong to one virtual user. For data shared across users, other mechanisms such as properties or data files are used.
JMeter sees the raw response from the server. A browser may add elements with scripts after the page loads. Design the extractor against the raw response.
Slightly, and more with large responses, complex patterns, wide scope, and scripts. Keep scope narrow and patterns simple, and remove debug helpers.
49Summary and Key Takeaways
Post-Processors are the catchers of a JMeter test. They grab the changing tickets that servers hand out and return them at the right moment, so that a test behaves like a real visitor.
- A Post-Processor runs after the response arrives, before assertions and listeners, and its stored value helps later requests, not its own.
- Correlation means finding dynamic values, extracting them from the response that first produces them, and using them in later requests.
- Pick the extractor that matches the format: JSON, CSS selector, XPath, boundary, or regular expression, with scripts as a last resort.
- Place each extractor directly under the sampler that returns the value, to keep scope narrow, fast, and safe.
- Extractors fail silently, so use a clearly fake default and a guard assertion that fails the step where the problem begins.
- Use match numbers deliberately: the first for single values, zero for random choice, and negative one to loop over lists.
- Keep tokens out of logs and files, remove debug helpers before big runs, review scripts, and recheck extractors after every application change.