k6 provides global __VU and __ITER variables for accessing VU and iteration information.
__VU
The __VU variable contains the current VU’s unique ID.
Current VU ID (1-based, unique within the test)
export default function () {
console.log(`VU ID: ${__VU}`);
}
Usage
import http from 'k6/http';
export default function () {
// Use VU ID for unique data
const userId = 1000 + __VU;
http.post('https://test.k6.io/api/users', JSON.stringify({
id: userId,
name: `user-${__VU}`,
}));
}
__ITER
The __ITER variable contains the current iteration number for the VU.
Current iteration number (0-based)
export default function () {
console.log(`Iteration: ${__ITER}`);
}
Usage
import { sleep } from 'k6';
export default function () {
// Skip first iteration (warmup)
if (__ITER === 0) {
console.log('Warmup iteration');
return;
}
// Normal test logic
console.log(`Running iteration ${__ITER}`);
}
Environment Variables
__ENV
Access environment variables passed to k6.
export default function () {
const apiUrl = __ENV.API_URL || 'https://test.k6.io';
console.log(`Using API: ${apiUrl}`);
}
Run with:
k6 run -e API_URL=https://api.example.com script.js
Examples
Per-VU Data Assignment
import { SharedArray } from 'k6/data';
const users = new SharedArray('users', function () {
return [
{ username: 'user1', password: 'pass1' },
{ username: 'user2', password: 'pass2' },
{ username: 'user3', password: 'pass3' },
];
});
export default function () {
// Each VU gets a different user
const user = users[(__VU - 1) % users.length];
console.log(`VU ${__VU} using ${user.username}`);
}
Iteration-based Pacing
import { sleep } from 'k6';
import http from 'k6/http';
export default function () {
http.get('https://test.k6.io');
// Increase sleep time with each iteration
const sleepTime = 1 + (__ITER * 0.1);
sleep(sleepTime);
}
Conditional Execution
import http from 'k6/http';
export default function () {
// Only even-numbered VUs hit the API
if (__VU % 2 === 0) {
http.get('https://test.k6.io/api');
} else {
http.get('https://test.k6.io/web');
}
}
Unique Session IDs
import http from 'k6/http';
export default function () {
// Create unique session ID combining VU and iteration
const sessionId = `session-${__VU}-${__ITER}`;
http.get('https://test.k6.io', {
headers: { 'X-Session-ID': sessionId },
});
}
Comparison with exec
The global variables are simpler but less feature-rich than the k6/execution module:
| Feature | Global Vars | k6/execution |
|---|
| VU ID | __VU | exec.vu.idInInstance |
| Iteration | __ITER | exec.vu.iterationInInstance |
| Scenario info | ❌ | ✅ |
| Test control | ❌ | ✅ |
| Tags/Metadata | ❌ | ✅ |
When to use global variables:
- Simple VU identification
- Iteration counting
- Quick prototyping
When to use k6/execution:
- Need scenario information
- Want to control test execution
- Need to set tags/metadata
- Require detailed execution state
// Simple case: use global vars
export default function () {
console.log(`VU ${__VU}, Iteration ${__ITER}`);
}
// Complex case: use k6/execution
import exec from 'k6/execution';
export default function () {
console.log(`Scenario: ${exec.scenario.name}`);
console.log(`Progress: ${exec.scenario.progress}`);
exec.vu.tags['iteration'] = exec.vu.iterationInInstance;
}
The global variables __VU and __ITER are available in both the init and VU contexts, but they are only meaningful in the VU context.