k6 load tests overstate origin traffic: no built-in browser cache emulation to model CDN hit ratios
0 reputation · 24 Mar 2024, 01:39 UTC
0 reputation · 24 Mar 2024, 01:39 UTC
k6's HTTP client does not implement a browser-like cache: every request in a script is sent over the network on every iteration, and response headers such as Cache-Control and ETag are returned to the script but never acted upon automatically. Conditional requests (If-None-Match) must be built explicitly, and http.batch() does not deduplicate or cache anything.
The practical consequence is that a test against a site behind a CDN measures worst-case origin traffic rather than realistic traffic, where a large share of static-asset requests would be cache hits. The documented direction is to model caching manually — for example, gating asset requests behind per-VU state or a probability — but the target hit ratio is itself a modeling decision that needs production traffic data, and applying probabilistic skipping to dynamic endpoints can distort latency distributions.
Assuming a current k6 release, the open questions are:
30775 reputation · 24 Mar 2024, 02:28 UTC
k6 does not currently provide native HTTP cache emulation. The HTTP client treats every request as a fresh network call, regardless of Cache-Control or ETag headers. To avoid overstating origin traffic, you must manually model the cache behavior within your script logic.
To derive a defensible hit ratio, analyze your CDN or origin access logs (e.g., CloudFront or Cloudflare logs) over a representative time window. Group your assets into classes based on content type or path prefix and calculate the ratio as follows:
Hit Ratio = Total Cache Hits / (Total Cache Hits + Total Cache Misses)
Once derived, encode these ratios as probability gates using Math.random(). This ensures that, over a large sample of VUs, the total request volume matches production patterns.
const CACHE_RATIOS = { static_assets: 0.85, // 85% hit ratio images: 0.95, // 95% hit ratio }; export default function () { // Simulate a static asset request if (Math.random() > CACHE_RATIOS.static_assets) { http.get('https://example.com/style.css'); } // Requests skipped by this logic are treated as cache hits (0ms network cost) }Implementation Strategy
exec.vu.iterationInScenario to identify the first iteration per VU. You can either discard these metrics using a custom tag or ensure the first iteration always executes the request before the probability gate takes over.This approach assumes that your VUs map to independent users. To verify that k6 is indeed overstating traffic, run a two-iteration script against a cached endpoint and check your server logs; you will see two full unconditional requests despite the presence of caching headers.
Note on k6 Browser: While the k6/browser module drives a real browser via the Chrome DevTools Protocol (CDP) and may exhibit native caching, the standard k6/http module remains stateless.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.