k6 Browser Module and HTTP Scenarios in One Run: Safe to Co-Locate VUs?
0 reputation · 17 Dec 2020, 04:32 UTC
0 reputation · 17 Dec 2020, 04:32 UTC
I want a single k6 test run that exercises both layers of a web application: protocol-level HTTP scenarios driving backend load, and browser-module scenarios (Chromium via CDP) capturing frontend behavior, so one end-of-test summary contains both http_req_duration and the browser_web_vital_* metrics.
The browser module runs each iteration in a fresh browser context and exposes an async API distinct from the synchronous http API, so the two scenario types are configured with different executors in the same script. My concern is the resource asymmetry: each browser VU carries a Chromium process, while an HTTP VU is comparatively cheap. On a shared load generator, browser VUs could saturate CPU and memory and distort the HTTP timings and web-vital metrics collected in the same run.
I am also unsure how stable the browser scenario configuration and metric names are across k6 releases, given the module's history of API changes, so any answer should note which k6 version it applies to.
Co-locating is allowed but not isolated. k6 provides no built-in mechanism to cap CPU or memory per scenario — all VUs, browser or HTTP, share the same host process and machine. A Chromium-backed browser VU can therefore starve the cheap HTTP VUs and inflate http_req_duration percentiles in the very summary you wanted to trust. For anything beyond a small smoke run, the reliable options are separate runs, or external isolation (containers/cgroups, separate generators).
Within one script you can mix executors freely — e.g. constant-vus for HTTP and a browser scenario using the browser executor — and both metric families (http_req_duration, browser_web_vital_*) land in one end-of-test summary. That part works. What does not exist:
So \"isolation\" must come from outside k6: run the browser scenario in its own container with --cpus/--memory limits, or split into two runs (possibly against the same environment simultaneously, from separate generators).
Since k6 won't flag generator overload for you, watch for these patterns:
htop, docker stats). This is the primary indicator.http_req_duration p90/p95 with and without the browser scenario active. A significant rise, or much wider spread between mean and p95, suggests contention rather than a slower backend.A practical verification: run 1 browser VU alongside your HTTP load, then 5, and plot HTTP percentiles at each step. The load level where percentiles bend upward is your generator's co-location ceiling.
The browser module landed as experimental in k6 v0.34.0 with an older API surface, and the current API — import { chromium } from 'k6/browser' with an async, per-iteration browser context — stabilized around v0.37.0. Scripts written for 0.34–0.36 are not syntax-compatible with the current module. This answer assumes k6 ≥ v0.37; because the module has a history of breaking changes, confirm executor and option names against the release notes of the exact version you pin, and pin one explicitly in CI rather than tracking latest.
Use a single co-located run only for low-VU functional checks where absolute timings don't matter. For load results you intend to act on, run browser and HTTP scenarios as separate executions (or separate containers with cgroup limits) and merge the reports afterward — you keep one logical test campaign without letting Chromium's appetite contaminate your HTTP measurements.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.