What does k6 reset in a virtual user between one iteration of the default function and the next?
answer
- not everything is wiped
- one store is emptied each pass
- a fresh cookie jar per iteration
- noCookiesReset opts out
basics
~20 sk6 gives the virtual user a fresh, empty cookie jar before each call of the VU function, unless the script sets noCookiesReset: true. Nothing else is reset: the same VU and its module-level variables carry on.
solid answer
~40 sBefore each call of the exported VU function, k6 replaces the virtual user's cookie jar with an empty one, so cookies the server set during the previous pass are gone. That is the whole automatic reset -- k6 does not re-evaluate the module, does not clear variables declared at module level, and does not build a new VU. The behaviour is switched off with the root option `noCookiesReset: true` (or `K6_NO_COOKIES_RESET`); there is no CLI flag for it. Because the fresh jar is created *before* the call, a cookie set early in an iteration is still available later in the **same** iteration -- which is what makes a multi-step journey work -- but a login done in one iteration does not carry into the next.
code
javascript · 16 linesimport http from 'k6/http';
// Run twice with one VU and watch the jar start empty both times.
// Add noCookiesReset: true below and the second iteration keeps the cookie.
export const options = { vus: 1, iterations: 2 };
const URL = 'https://quickpizza.grafana.com/api/cookies';
export default function () {
const jar = http.cookieJar();
console.log('at start of iteration:', JSON.stringify(jar.cookiesForURL(URL)));
http.get(`${URL}?session=abc123`);
console.log('after the request:', JSON.stringify(jar.cookiesForURL(URL)));
}go deeper
Remember that cookies do not survive from one iteration to the next by default. If a request needs a session, the iteration has to obtain one for itself.
Explain that only the cookie jar is replaced, that it happens before the call rather than after, and that noCookiesReset turns it off from the options object or the environment.
Diagnose the symptom on sight: the first request of every iteration looks unauthenticated while later ones in the same pass are fine. Then argue whether the fix is logging in per iteration or persisting the jar.
Decide what a virtual user is meant to represent across the suite. Modelling each iteration as a new visitor and modelling a VU as one long session give different numbers, and mixing the two silently makes runs incomparable.
## The one thing k6 resets Before every call of the VU function, k6 builds the virtual user a **brand-new, empty cookie jar** and installs it as that VU's jar. Cookies the server set during the previous pass are gone. That is the whole of the automatic reset. k6 does not re-evaluate the module, does not clear variables the script declared, and does not create a new virtual user. The user is the same user; only its cookie store was emptied. Note the ordering: the fresh jar is created **before** the call, not swept up after it. Cookies set early in an iteration are therefore fully visible for the rest of *that* iteration -- which is exactly what a multi-step journey needs -- and simply absent when the next one begins. ## Turning it off: `noCookiesReset` The behaviour is controlled by a single boolean root option, which defaults to `false`: ```javascript export const options = { noCookiesReset: true, // the VU's jar now survives from iteration to iteration }; ``` Two details about it are easy to get wrong: - it is exposed as the script option `noCookiesReset` and as the environment variable `K6_NO_COOKIES_RESET`, and **there is no command-line flag for it** -- unlike `--no-connection-reuse` and `--no-vu-connection-reuse`, which do have flags; - it is a double negative. `noCookiesReset: true` means *do not reset*, so cookies persist. Reading it as "no cookies" and expecting the jar to be disabled is a common misreading. ## What survives, and what does not | Crosses the iteration boundary? | What | |---|---| | **No** | the virtual user's cookie jar, replaced with an empty one unless `noCookiesReset: true` | | **Yes** | variables the script declared at module level, and anything stored on them | | **Yes** | the virtual user itself -- same VU, same already-evaluated module | | **Configurable** | idle TCP connections, which k6 closes at the end of each pass when `noVUConnectionReuse` is set | ## The scope of a cookie jar A cookie jar in k6 belongs to one virtual user. Nothing is shared between VUs: two users running the same journey never see each other's cookies, however many of them the run has. The jar is also entirely separate from the module-level state around it, which is why the two behave so differently at the iteration boundary -- one of them is k6's to manage, the other is yours. You can also build a jar of your own with `new http.CookieJar()` and pass it on a single request, which overrides the VU jar for that request only. A jar you created is an ordinary object held by your own code, so the per-iteration reset never touches it. ## Why it matters in a two-step journey Take a browse-then-add-to-cart iteration where the browse step is what makes the server issue a session cookie: 1. The `GET` for the menu returns `Set-Cookie: session=...`. k6 stores it in the current jar. 2. The `POST` that adds an item to the cart, later in the **same** iteration, carries that cookie automatically. The step works. 3. The function returns. k6 throws the jar away. 4. The next iteration's `GET` goes out with no cookies at all. The consequence people trip over is authentication. A login performed in iteration one does **not** leave the virtual user logged in for iteration two. Under the default settings a k6 VU is, from the server's point of view, a new anonymous visitor at the start of every pass. There are two honest ways out, and which one is right depends on what you are testing: - **Log in inside the iteration.** Correct when the login is genuinely part of the journey you want measured -- but it means every pass pays for it. - **Set `noCookiesReset: true`.** Correct when you want a VU to behave like one long-lived session, and the login itself is not what you are exercising. ## Diagnosing it The symptom is unmistakable once you know it: the first request of each iteration behaves as if unauthenticated, while later requests in the same iteration are fine. Inspect the jar directly at the top of the function to confirm -- `http.cookieJar()` returns the current VU jar, and `cookiesForURL(url)` reports what is in it for a given URL. On the default settings that call prints an empty object at the start of every pass, and a populated one immediately after the first response that set a cookie.
- Does k6 clear the cookie jar before the iteration or after it?Before. k6 installs a new empty jar and then calls the exported function, so cookies set during a pass stay usable for the whole of that pass and are simply absent when the next call begins. The distinction matters for multi-step journeys, which depend on cookies surviving within one iteration.
- Is there a command-line flag for `noCookiesReset`?No. k6 exposes it only as the script option `noCookiesReset` and the environment variable `K6_NO_COOKIES_RESET`. That sets it apart from the neighbouring connection options, which do have flags -- `--no-connection-reuse` and `--no-vu-connection-reuse`.
- Do module-level variables get reset between iterations too?No. The module is evaluated once when the virtual user is created, and its top-level bindings live for the whole life of that VU. A counter you increment inside the function keeps climbing across iterations; only the cookie jar is replaced for you.
It is like handing the next tester the same laptop with the browser's cookies cleared but every file they saved still sitting on disk. k6 wipes the jar, not the script's own variables.
saying these in an interview costs you the question
- Assumes a login in one iteration keeps the VU authenticated later
- Thinks k6 rebuilds the whole virtual user between iterations
- Believes module-level variables are cleared at each iteration
- Reads noCookiesReset as disabling cookies rather than the reset
- Looks for a --no-cookies-reset flag, which k6 does not have