HTTP Requests
Thek6/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,
});
}
import http from 'k6/http';
export default function() {
let res = http.post('http://httpbin.org/post', {
verb: 'post'
});
check(res, {
'status is 200': (r) => r.status === 200,
});
}
import http from 'k6/http';
export default function() {
let payload = JSON.stringify({ verb: 'put' });
let params = {
headers: { 'Content-Type': 'application/json' }
};
let res = http.put('http://httpbin.org/put', payload, params);
}
import http from 'k6/http';
export default function() {
let res = http.del('http://httpbin.org/delete?verb=delete');
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
- URL-Encoded Form
- JSON Payload
- Multipart Form
import http from 'k6/http';
import { check } from 'k6';
const form_data = {
name: 'Test Name',
telephone: '123456789',
email: 'test@example.com',
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,
});
}
import http from 'k6/http';
export default function() {
let payload = JSON.stringify({
name: 'Test Name',
email: 'test@example.com',
items: ['pizza', 'soda']
});
let params = {
headers: { 'Content-Type': 'application/json' }
};
http.post('https://quickpizza.grafana.com/api/orders', payload, params);
}
import http from 'k6/http';
export default function() {
let data = {
field: 'value',
file: http.file(open('image.png', 'b'), 'image.png'),
};
http.post('http://httpbin.org/post', data);
}
Authentication
import http from 'k6/http';
import { check } from 'k6';
export default function() {
// Username and password in URL
let res = http.get('http://user:passwd@httpbin.org/basic-auth/user/passwd');
check(res, {
'is authenticated': (r) => r.json().authenticated === true,
});
}
import encoding from 'k6/encoding';
import http from 'k6/http';
export default function() {
let credentials = encoding.b64encode('user:passwd');
let params = {
headers: { 'Authorization': `Basic ${credentials}` }
};
http.get('http://httpbin.org/basic-auth/user/passwd', params);
}
import http from 'k6/http';
export function setup() {
let loginRes = http.post('https://quickpizza.grafana.com/api/login', {
username: 'test@example.com',
password: 'password123'
});
return { token: loginRes.json('token') };
}
export default function(data) {
let params = {
headers: { 'Authorization': `Bearer ${data.token}` }
};
http.get('https://quickpizza.grafana.com/api/orders', params);
}
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
| Option | Type | Description |
|---|---|---|
headers | object | Custom HTTP headers |
tags | object | Custom tags for metrics |
cookies | object | Request-specific cookies |
redirects | number | Max redirects to follow |
timeout | string | Request timeout (e.g., ’60s’) |
jar | CookieJar | Custom cookie jar |
compression | string | Compression 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
- Configure Test Options for your load test
- Learn about Tags and Groups for organizing metrics
- Explore Scenarios for advanced execution patterns