Skip to main content
k6 provides global __VU and __ITER variables for accessing VU and iteration information.

__VU

The __VU variable contains the current VU’s unique ID.
__VU
number
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.
__ITER
number
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:
FeatureGlobal Varsk6/execution
VU ID__VUexec.vu.idInInstance
Iteration__ITERexec.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.

Build docs developers (and LLMs) love