Skip to content

k6 Custom Tags Not Appearing in Output Fix

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about k6 custom tags not appearing in output fix. We cover key concepts, practical examples, and best practices.

Your k6 test tags do not appear in the output — http_req_duration values are aggregated globally without per-endpoint or per-method breakdown. Tags must be set in the request parameters or in the tags option to enable filtering.

The Problem

import http from 'k6/http';

export default function () {
  const res1 = http.get('https://api.example.com/users');
  const res2 = http.get('https://api.example.com/orders');
  const res3 = http.post('https://api.example.com/users', '{}');
}
     http_req_duration........: avg=234ms  p(95)=890ms

All requests are aggregated into a single metric — cannot distinguish between GET /users and POST /orders.

Step-by-Step Fix

1. Tag individual requests

import http from 'k6/http';

export default function () {
  http.get('https://api.example.com/users', {
tags: { endpoint: 'users', method: 'GET' },
  });
  http.get('https://api.example.com/orders', {
tags: { endpoint: 'orders', method: 'GET' },
  });
  http.post('https://api.example.com/users', '{}', {
tags: { endpoint: 'users', method: 'POST' },
  });
}

2. Set global tags in options

import http from 'k6/http';

export const options = {
tags: {
    environment: 'staging',
    team: 'backend',
    service: 'api-gateway',
  },
};

export default function () {
  http.get('https://api.example.com/health');
}

3. Set per-endpoint thresholds with tags

export const options = {
  thresholds: {
    'http_req_duration{endpoint:users}': ['p(95)<500'],
    'http_req_duration{endpoint:orders}': ['p(95)<2000'],
    'http_req_duration{method:POST}': ['p(95)<3000'],
  },
};

4. Tag checks and custom metrics

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

const endpointLatency = new Trend('endpoint_latency');

export default function () {
  const res = http.get('https://api.example.com/users', {
tags: { endpoint: 'users' },
  });

  endpointLatency.add(res.timings.duration, { endpoint: 'users' });

  check(res, {
    'users status is 200': (r) => r.status === 200,
  });
}

5. Use dynamic tags from response data

import http from 'k6/http';

export default function () {
  const res = http.get('https://api.example.com/users/1');

  if (res.status === 200) {
    const user = res.json();
    http.put(`https://api.example.com/users/${user.id}`, JSON.stringify({
      name: user.name,
    }), {
tags: {
        userRole: user.role,
        userId: String(user.id),
      },
    });
  }
}

Expected output:

     http_req_duration{endpoint:users}....: avg=45ms   p(95)=120ms
     http_req_duration{endpoint:orders}...: avg=320ms  p(95)=890ms
     http_req_duration{method:POST}.......: avg=150ms  p(95)=300ms

Prevention Tips

  • Tag every request with endpoint and method for granular metrics
  • Use global tags in options.tags for environment/service identification
  • Set per-endpoint thresholds using tag selectors
  • Tag custom metrics with context data for richer analysis
  • Use short tag values — avoid long strings that bloat output

Common Mistakes with options tags

  1. Mixing let bindings with <- bindings in do notation, producing type errors
  2. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
  3. Non-exhaustive pattern matches that compile with warnings then crash at runtime

These mistakes appear frequently in real-world K6 code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### What is the maximum number of tags?

There is no hard limit, but each unique tag combination creates a separate time series. For high-throughput tests (10,000+ requests/sec), keep tags minimal — 5-10 unique tag combinations per test to avoid excessive cardinality.

Can tags include dynamic values like timestamps?

Yes, but be careful with high-cardinality tag values (unique IDs, timestamps, user emails). Each unique value creates a new time series. Use low-cardinality values like endpoint names, HTTP methods, and status code ranges.

Do tags affect k6 Cloud billing?

In k6 Cloud, each unique tag combination counts as a separate time series. Plan your tag strategy to stay within your plan's metric limits. Aggregate tags to reduce cardinality where possible.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro