Documentation Index Fetch the complete documentation index at: https://mintlify.com/grafana/k6-docs/llms.txt
Use this file to discover all available pages before exploring further.
HTTP requests are the foundation of most k6 load tests. The k6/http module provides methods for all standard HTTP operations.
Making HTTP requests
The simplest HTTP request is a GET request:
import http from 'k6/http' ;
export default function () {
http . get ( 'http://test.k6.io' );
}
POST request with payload
Here’s a more complex example showing a POST request with JSON payload:
import http from 'k6/http' ;
export default function () {
const url = 'http://test.k6.io/login' ;
const payload = JSON . stringify ({
email: 'aaa' ,
password: 'bbb' ,
});
const params = {
headers: {
'Content-Type' : 'application/json' ,
},
};
http . post ( url , payload , params );
}
Available HTTP methods
The k6/http module supports all standard HTTP methods:
Method Description http.get()Issue an HTTP GET request http.post()Issue an HTTP POST request http.put()Issue an HTTP PUT request http.patch()Issue an HTTP PATCH request http.del()Issue an HTTP DELETE request http.head()Issue an HTTP HEAD request http.options()Issue an HTTP OPTIONS request http.request()Issue any type of HTTP request http.batch()Issue multiple HTTP requests in parallel
Batch requests
Use http.batch() to send multiple requests in parallel, similar to how browsers load resources:
import http from 'k6/http' ;
export default function () {
const responses = http . batch ([
[ 'GET' , 'https://test.k6.io/' ],
[ 'GET' , 'https://test.k6.io/contacts.php' ],
[ 'GET' , 'https://test.k6.io/news.php' ],
]);
// All requests execute in parallel
}
HTTP request parameters
The third parameter to HTTP methods accepts an object with request configuration:
Headers
Custom tags
Redirects
import http from 'k6/http' ;
export default function () {
const params = {
headers: {
'Content-Type' : 'application/json' ,
'Authorization' : 'Bearer token123' ,
},
};
http . get ( 'https://test.k6.io' , params );
}
Following redirects
By default, k6 automatically follows redirects. You can customize this behavior:
Global setting
Per-request setting
Set maxRedirects in options to configure redirect behavior for all requests: export const options = {
maxRedirects: 10 ,
};
Override the global setting for specific requests: http . get ( 'https://test.k6.io' , { redirects: 0 }); // Don't follow redirects
k6 automatically tags HTTP requests with metadata for filtering and analysis:
Tag Description Example nameURL or custom name http://test.k6.iomethodHTTP method GET, POSTstatusResponse status code 200, 404urlRequest URL http://test.k6.iogroupGroup name (if in a group) ::user loginscenarioScenario name defaultexpected_responseWhether response was expected true, false
Example tagged output
Here’s how k6 stores metrics with tags:
{
"type" : "Point" ,
"metric" : "http_req_duration" ,
"data" : {
"time" : "2017-06-02T23:10:29.52444541+02:00" ,
"value" : 586.831127 ,
"tags" : {
"expected_response" : "true" ,
"group" : "" ,
"method" : "GET" ,
"name" : "http://test.k6.io" ,
"scenario" : "default" ,
"status" : "200" ,
"url" : "http://test.k6.io"
}
}
}
URL grouping
When testing dynamic URLs, you’ll want to group them to prevent metrics fragmentation.
The problem: dynamic URLs
This code creates 100 different metrics, one for each unique URL:
import http from 'k6/http' ;
export default function () {
for ( let id = 1 ; id <= 100 ; id ++ ) {
http . get ( `http://example.com/posts/ ${ id } ` );
// Results in: tags.name="http://example.com/posts/1",
// tags.name="http://example.com/posts/2", etc.
}
}
This makes analysis difficult and consumes more memory.
Solution 1: Custom name tag
Set a custom name tag to group dynamic URLs:
import http from 'k6/http' ;
export default function () {
for ( let id = 1 ; id <= 100 ; id ++ ) {
http . get ( `http://example.com/posts/ ${ id } ` , {
tags: { name: 'PostsItemURL' },
});
// All requests now have: tags.name="PostsItemURL"
}
}
Now all 100 requests are aggregated into a single metric.
Solution 2: http.url template
Use the http.url template literal wrapper:
import http from 'k6/http' ;
export default function () {
for ( let id = 1 ; id <= 100 ; id ++ ) {
http . get ( http . url `http://example.com/posts/ ${ id } ` );
// Results in: tags.name="http://example.com/posts/${{}}"
}
}
This automatically groups URLs by replacing variable parts with ${}.
Response object
HTTP methods return a Response object with request/response details:
import http from 'k6/http' ;
import { check } from 'k6' ;
export default function () {
const res = http . get ( 'https://test.k6.io' );
console . log ( res . status ); // 200
console . log ( res . body . length ); // Response body size
console . log ( res . timings . duration ); // Request duration in ms
check ( res , {
'is status 200' : ( r ) => r . status === 200 ,
'body size > 0' : ( r ) => r . body . length > 0 ,
});
}
Useful response properties
res.status HTTP status code (200, 404, etc.)
res.body Response body as string
res.json() Parse response body as JSON
res.timings Detailed timing breakdown
res.headers Response headers
res.cookies Response cookies
Complete example
Here’s a comprehensive example combining multiple concepts:
import http from 'k6/http' ;
import { check , sleep } from 'k6' ;
export const options = {
vus: 10 ,
duration: '30s' ,
};
const baseUrl = 'https://quickpizza.grafana.com' ;
export default function () {
// GET request with custom tags
const listRes = http . get ( ` ${ baseUrl } /api/pizzas` , {
tags: { name: 'ListPizzas' },
});
check ( listRes , {
'list status is 200' : ( r ) => r . status === 200 ,
});
// POST request with JSON payload
const createPayload = JSON . stringify ({
name: 'Test Pizza' ,
toppings: [ 'cheese' , 'pepperoni' ],
});
const createRes = http . post (
` ${ baseUrl } /api/pizzas` ,
createPayload ,
{
headers: { 'Content-Type' : 'application/json' },
tags: { name: 'CreatePizza' },
}
);
check ( createRes , {
'create status is 201' : ( r ) => r . status === 201 ,
});
// Batch parallel requests
http . batch ([
[ 'GET' , ` ${ baseUrl } /` , null , { tags: { name: 'Homepage' } }],
[ 'GET' , ` ${ baseUrl } /api/status` , null , { tags: { name: 'Status' } }],
]);
sleep ( 1 );
}
Best practices
Group dynamic URLs Use name tags or http.url to prevent metric fragmentation with dynamic URLs.
Use meaningful names Tag requests with descriptive names for easier analysis.
Check responses Always validate critical responses with checks.
Batch when possible Use http.batch() to simulate realistic browser behavior.