Skip to content
Go back

Tags in k6 - Organizing Your Requests and Metrics

Edit page

When running load tests, especially on complex systems like SaaS productss, it’s not enough to just measure all requests together. You want insight into specific endpoints, groups of requests, or types of users. That’s where tags come in.

In this post, we will learn how to:

Table of contents

Open Table of contents

Why Tags Matter

In k6, tags are labels you attach to requests. They allow you to:

Using tags, you can tell k6:

I want to make sure the login endpoint is always fast, even if other endpoints are slower.

Without tags, thresholds are applied globally.

Example:

http_req_duration: ["p(95)<500"]

Tags solve this by allowing endpoint-specific thresholds.

How to Use Tags in k6 Requests

You can attach tags to individual HTTP requests via the tags option:

  const loginRes = http.post(
    "https://fakeloadtest.com/auth/token/login/",
    loginPayload,
    { headers: commonHeaders, tags: { name: "login" } }
  );

  // 2. Get Product list (protected endpoint)
  let products = http.get("https://fakeloadtest.com/api/products/",
    { headers: withAuth, tags: { name: "products" } }
  );

Using Multiple Tags

You can have multiple tags per request:


let products = http.get("https://fakeloadtest.com/api/products/",
    { headers: withAuth, tags: { name: "products", method: "GET", user: "admin" } }
  );

Applying Thresholds to Tags

Once requests are tagged, you can define per-tag thresholds in options:

export const options = {
  thresholds: {
    "http_req_duration{name:login}": ["p(95)<400"], // Single tag
    "http_req_duration{name:products,user: admin}": ["p(95)<600"], // Multi tag
    http_req_failed: ["rate<0.01"],
  },
};

Tags let you enforce SLAs for each critical endpoint without affecting the entire system.

This is extremely useful for role-based testing or multi-tenant SaaS productss.

Using Groups with Tags

For multi-step flows, you can group requests to make metrics more readable:

import { group } from "k6";

group("login_flow", () => {
  # Login Request
  # Product Request
});

Applying Thresholds to Groups

Once requests are within Group, you can define Group level thresholds in options:

export const options = {
  thresholds: {
    "http_req_duration{name:login}": ["p(95)<400"], // Single tag
    "http_req_duration{name:products,user: admin}": ["p(95)<600"], // Multi tag
    'http_req_duration{group:login_flow}': ['p(95) < 1000']
    http_req_failed: ["rate<0.01"],
  },
};

Putting it all together

For multi-step flows, you can group requests to make metrics more readable:

import http from "k6/http";
import { sleep, check } from "k6";

export const options = {
  vus: 5,
  duration: "30s",
  thresholds: {
    "http_req_duration{name:login}": ["p(95)<400"], // Single tag
    "http_req_duration{name:products,user: admin}": ["p(95)<600"], // Multi tag
    'http_req_duration{group:login_flow}': ['p(95) < 1000']
    http_req_failed: ["rate<0.01"],
  },
};

export default function () {
  const commonHeaders = {
      "Content-Type": "application/json",
      "X-Client-Version": "1.0.0",
      "X-Request-Source": "k6-learn-series",
    };

    // 1. Login and retrieve JWT
    const loginPayload = JSON.stringify({
      username: "testuser@example.com",
      password: "supersecure",
    });


  group("login_flow", () => {
    const loginRes = http.post(
      "https://fakeloadtest.com/auth/token/login/",
      loginPayload,
      { headers: commonHeaders, tags: { name: "login" } }
    );

    check(loginRes, {
      "login successful": (r) => r.status === 200,
      "token received": (r) => r.json("access") !== undefined,
    });

    const token = loginRes.json("access");
    if (!token) return;

    // Build withAuth by copying commonHeaders and adding Authorization
    const withAuth = { 
      ...commonHeaders, 
      Authorization: `Bearer ${token}` 
      };

    // 2. Get Product list (protected endpoint)
    let products = http.get("https://fakeloadtest.com/api/products/",
      { headers: withAuth, tags: { name: "products", user: "admin" } }
    );
    check(products, {
      "Get Products": (r) => r.status === 200,
    });
  });
}

Exercise: Practice with Tags

  1. Add tags to all requests in your JWT SaaS products flow: login, products, get Product, Update Product (or relevant endpoints).
  2. Define Tag Level thresholds: login < 400 ms, products < 600 ms, get product < 200 ms.
  3. Define Group Level thresholds: login Group (Login api), Product group ( ge products, get single product, update product).
  4. Run the test and check metrics grouped by tag. Observe differences in p95 latency per endpoint.

Edit page
Share this post on:

Next Post
Introduction & Getting Started with k6