Skip to main content
The init context (also called “init code”) is code in the global context that runs before the test starts. It has access to special functions and variables not available during main script execution.

Overview

Before k6 starts the test logic, code in the init context prepares the script by:
  • Importing modules
  • Loading files
  • Defining global variables
  • Setting up configuration
  • Initializing shared resources
Only a few special functions are available exclusively in the init context.
For details about the runtime and execution phases, refer to the Test Lifecycle documentation.

Init Context Functions

open()

open(filePath, [mode])
function
Opens a file and reads all its contents into memory for use in the script.Parameters:
filePath
string
required
Path to the file (absolute or relative). The file is loaded once even when running with multiple VUs.
mode
string
File read mode:
  • Omit or "t" - Read as text (default)
  • "b" - Read as binary data (ArrayBuffer)
Returns:
content
string | ArrayBuffer
File contents as string or ArrayBuffer (if binary mode)
open() can only be called from the init context. This restriction allows k6 to determine which local files to bundle when distributing tests across multiple nodes.

Global Variables

These variables are available throughout your script:

Environment Variables

__ENV
object
Object containing environment variables as key-value pairs. Access environment variables passed to k6 via -e or --env flags.Example:
const baseUrl = __ENV.BASE_URL || 'https://test.k6.io';

VU Information

__VU
number
Current VU (Virtual User) number. Starts at 1 and increments for each VU.Example:
console.log(`Running as VU ${__VU}`);
__ITER
number
Current iteration number for the VU. Starts at 0 and increments with each iteration.Example:
console.log(`Iteration ${__ITER}`);
For more comprehensive execution context information, use the k6/execution module which provides detailed metadata about scenarios, instances, and test state.

Examples

Loading JSON Data

import { SharedArray } from 'k6/data';
import { sleep } from 'k6';

const data = new SharedArray('users', function () {
  // open() is called in init context
  const f = JSON.parse(open('./users.json'));
  return f; // f must be an array
});

export default () => {
  const randomUser = data[Math.floor(Math.random() * data.length)];
  console.log(`${randomUser.username}, ${randomUser.password}`);
  sleep(3);
};

Loading Binary Files

import http from 'k6/http';
import { sleep } from 'k6';

const binFile = open('/path/to/file.bin', 'b');

export default function () {
  const data = {
    field: 'this is a standard form field',
    file: http.file(binFile, 'test.bin'),
  };
  
  const res = http.post('https://example.com/upload', data);
  sleep(3);
}

Using Environment Variables

import http from 'k6/http';
import { check } from 'k6';

// Read environment variables in init context
const baseUrl = __ENV.BASE_URL || 'https://test.k6.io';
const apiKey = __ENV.API_KEY;

export const options = {
  vus: parseInt(__ENV.VUS) || 10,
  duration: __ENV.DURATION || '30s',
};

export default function () {
  const res = http.get(`${baseUrl}/api/users`, {
    headers: {
      'Authorization': `Bearer ${apiKey}`,
    },
  });
  
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
}
Run with environment variables:
k6 run -e BASE_URL=https://api.example.com -e API_KEY=secret123 -e VUS=20 script.js

Per-VU Data Assignment

import { SharedArray } from 'k6/data';
import http from 'k6/http';

const users = new SharedArray('users', () => {
  return JSON.parse(open('./users.json'));
});

export default function () {
  // Each VU gets a specific user
  const user = users[__VU - 1];
  
  const res = http.post('https://test.k6.io/login', {
    username: user.username,
    password: user.password,
  });
  
  console.log(`VU ${__VU} logged in as ${user.username}`);
}

Conditional Configuration

import http from 'k6/http';

const environment = __ENV.ENVIRONMENT || 'dev';

const config = {
  dev: {
    baseUrl: 'https://dev.example.com',
    vus: 5,
    duration: '1m',
  },
  staging: {
    baseUrl: 'https://staging.example.com',
    vus: 20,
    duration: '5m',
  },
  prod: {
    baseUrl: 'https://example.com',
    vus: 100,
    duration: '10m',
  },
};

const currentConfig = config[environment];

export const options = {
  vus: currentConfig.vus,
  duration: currentConfig.duration,
};

export default function () {
  http.get(`${currentConfig.baseUrl}/api/health`);
}
Run with:
k6 run -e ENVIRONMENT=staging script.js

Memory Efficiency with SharedArray

open() often consumes a large amount of memory because every VU keeps a separate copy of the file in memory.
To reduce memory consumption:

Use SharedArray

import { SharedArray } from 'k6/data';

// Good: Memory is shared between all VUs
const data = new SharedArray('my-data', () => {
  return JSON.parse(open('./large-file.json'));
});

Use k6/experimental/fs

import { open } from 'k6/experimental/fs';

// Good: Memory-efficient file handling
const file = await open('large-file.csv');

export default async function () {
  const buffer = new Uint8Array(1024);
  await file.read(buffer);
}

Init Context vs Default Function

AspectInit ContextDefault Function
ExecutionOnce per VU at startupEvery iteration
PurposeSetup and initializationTest logic
File Accessopen() availableopen() NOT available
VariablesDefine globalsUse globals
PerformanceRuns before metrics collectionMeasured in test metrics
Async OperationsLimited supportFull async/await support

Code Example

import http from 'k6/http';
import { check } from 'k6';

// ========================================
// INIT CONTEXT - Runs once per VU
// ========================================

console.log('Init: Loading data...'); // Runs once
const users = JSON.parse(open('./users.json'));
const baseUrl = __ENV.BASE_URL || 'https://test.k6.io';

export const options = {
  vus: 10,
  iterations: 100,
};

// ========================================
// DEFAULT FUNCTION - Runs every iteration
// ========================================

export default function () {
  console.log(`Iteration ${__ITER} starting...`); // Runs every iteration
  
  const user = users[__VU % users.length];
  const res = http.get(`${baseUrl}/user/${user.id}`);
  
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
}

Best Practices

Keep init context code minimal and fast. Heavy operations in init context delay test startup and increase memory usage per VU.
// Good: Simple initialization
const config = JSON.parse(open('./config.json'));

// Bad: Heavy processing in init context
const data = processLargeDataset(open('./huge-file.csv'));
Always use SharedArray when loading large files to avoid memory duplication across VUs.
import { SharedArray } from 'k6/data';

const data = new SharedArray('large-dataset', () => {
  return JSON.parse(open('./large-file.json'));
});
Provide defaults for environment variables and validate required ones in init context.
const apiKey = __ENV.API_KEY;
if (!apiKey) {
  throw new Error('API_KEY environment variable is required');
}

const baseUrl = __ENV.BASE_URL || 'https://default.example.com';
Use __VU for per-VU data distribution and __ITER for iteration-specific logic.
// Assign user based on VU ID
const user = users[__VU - 1];

// Skip first iteration (warmup)
if (__ITER === 0) {
  return;
}

k6/execution

Detailed execution context and metadata

SharedArray

Share data efficiently between VUs

k6/experimental/fs

Memory-efficient file operations

Test Lifecycle

Understanding k6 execution phases

Build docs developers (and LLMs) love