Skip to main content

HTTP Requests

The k6/http module is the core of most k6 tests. It provides methods for making HTTP requests and handling responses.

Basic GET Request

The simplest k6 test makes a GET request:
import http from 'k6/http';

export default function () {
  http.get('https://quickpizza.grafana.com');
}

HTTP Methods

k6 supports all standard HTTP verbs:
import http from 'k6/http';
import { check } from 'k6';

export default function() {
  let res = http.get('http://httpbin.org/get?verb=get');
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
}

Request Parameters

Customize requests with parameters:
import http from 'k6/http';

export default function() {
  let params = {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer token123',
      'User-Agent': 'k6-test',
    },
    tags: {
      name: 'CreateOrder',
      api_version: 'v2',
    },
    timeout: '60s',
  };

  http.post('https://quickpizza.grafana.com/api/orders', 
    JSON.stringify({ items: ['pizza'] }),
    params
  );
}

Handling Response Data

The response object contains all the information about the HTTP response:
import http from 'k6/http';
import { check } from 'k6';

export default function() {
  let res = http.get('https://quickpizza.grafana.com/api/menu');
  
  // Status code
  console.log('Status:', res.status);
  
  // Response body as string
  console.log('Body:', res.body);
  
  // Parse JSON response
  let menu = res.json();
  console.log('Items:', menu.items.length);
  
  // Access specific JSON field
  let firstItem = res.json('items.0.name');
  
  // Response headers
  console.log('Content-Type:', res.headers['Content-Type']);
  
  // Timing information
  console.log('Duration:', res.timings.duration, 'ms');
  console.log('Waiting:', res.timings.waiting, 'ms');
  console.log('Connecting:', res.timings.connecting, 'ms');
}

Form Data and POST Requests

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

const form_data = {
  name: 'Test Name',
  telephone: '123456789',
  email: '[email protected]',
  comment: 'Hello world!',
  topping: ['onion', 'bacon', 'cheese']
};

export default function() {
  // Passing object automatically form-urlencodes it
  let res = http.post('http://httpbin.org/post', form_data);
  
  check(res, {
    'status is 200': (r) => r.status === 200,
    'has correct name': (r) => r.json().form.name === form_data.name,
  });
}

Authentication

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

export default function() {
  // Username and password in URL
  let res = http.get('http://user:[email protected]/basic-auth/user/passwd');
  
  check(res, {
    'is authenticated': (r) => r.json().authenticated === true,
  });
}

Batch Requests

Make multiple requests in parallel:
import { check } from 'k6';
import http from 'k6/http';

export default function() {
  const responses = http.batch([
    'https://quickpizza.grafana.com/test.k6.io',
    'https://quickpizza.grafana.com/pi.php',
    ['GET', 'https://quickpizza.grafana.com/api/menu'],
    {
      method: 'POST',
      url: 'https://quickpizza.grafana.com/api/orders',
      body: JSON.stringify({ items: ['pizza'] }),
      params: { headers: { 'Content-Type': 'application/json' } },
    },
  ]);

  check(responses[0], {
    'main page 200': res => res.status === 200,
  });
  
  check(responses[1], {
    'pi page has right content': res => res.body === '3.14',
  });
}
Batch requests are executed in parallel from the VU’s perspective, but they still count as separate requests in your metrics.

Cookies

k6 automatically handles cookies with a VU-scoped cookie jar:
import http from 'k6/http';
import { check } from 'k6';

export default function() {
  // VU cookie jar automatically manages cookies
  let res = http.get('http://httpbin.org/cookies/set?name=value');
  
  // Access VU cookie jar
  let jar = http.cookieJar();
  let cookies = jar.cookiesForURL(res.url);
  
  check(null, {
    'has cookie': () => cookies.name !== undefined,
  });
  
  // Create local cookie jar
  let localJar = new http.CookieJar();
  localJar.set('http://httpbin.org/cookies', 'custom', 'value123');
  
  http.get('http://httpbin.org/cookies', { jar: localJar });
}

Response Validation with Checks

Use checks to validate responses without failing the test:
import http from 'k6/http';
import { check } from 'k6';

export default function() {
  let res = http.get('https://quickpizza.grafana.com/api/menu');
  
  check(res, {
    'status is 200': (r) => r.status === 200,
    'status is not 404': (r) => r.status !== 404,
    'response time < 500ms': (r) => r.timings.duration < 500,
    'body size < 10KB': (r) => r.body.length < 10240,
    'has menu items': (r) => r.json('items').length > 0,
    'content type is JSON': (r) => r.headers['Content-Type'].includes('application/json'),
  });
}
Checks don’t stop test execution when they fail. Use thresholds if you need to fail the entire test based on check results.

Common Request Options

OptionTypeDescription
headersobjectCustom HTTP headers
tagsobjectCustom tags for metrics
cookiesobjectRequest-specific cookies
redirectsnumberMax redirects to follow
timeoutstringRequest timeout (e.g., ’60s’)
jarCookieJarCustom cookie jar
compressionstringCompression algorithm (‘gzip’, ‘deflate’, ‘br’)

Global HTTP Options

Set default options for all HTTP requests:
export let options = {
  userAgent: 'k6-load-test/1.0',
  maxRedirects: 5,
  insecureSkipTLSVerify: true,
  batch: 10,              // Max parallel requests in batch()
  batchPerHost: 5,        // Max parallel requests per host
  noConnectionReuse: false,
  noVUConnectionReuse: false,
};

Next Steps

Build docs developers (and LLMs) love