Why the generator runs on its own machine
k6 measures response time from the generator's side, so anything that slows the generator shows up as a slower target. Run k6 on the same host as the application and the two share the scheduler, the memory and the NIC; the result describes that contention, not the service. A separate machine keeps the measurement honest and lets you watch generator and target independently.
Location matters as well. Grafana's API testing guide calls the load generators the machines that run the test. When latency must reflect real users, it launches them from the users' region; when a test is compared against a baseline, it advises keeping the location fixed and not running from locations that are too close to the system under test.
Sizing the generator
Grafana's guide to large tests states that one k6 process handles 30,000-40,000 concurrent VUs, resources permitting, and in some cases up to 300,000 HTTP requests per second. Most tests never need more than one machine. The figures below are the guide's own rules of thumb.
| Resource | What the k6 documentation says | What to do |
|---|---|---|
| CPU | k6 is heavily multi-threaded; at 100% CPU, response-time metrics come out larger than reality | Size for at least 20% idle; k6 at or below about 80% |
| Memory | Simple tests use about 1-5 MB per VU; uploads or large JS modules can take tens of MB per VU | Run 100 VUs locally, multiply by the target VU count, stay under 90% of RAM |
| Swap | Swapping has erratic effects and likely invalidates results | Disable swap on the generator |
| Network | A 1 Gbit/s link can cap the load; constant traffic at line rate means the NIC is the limit | Watch with iftop; move to a bigger port if it plateaus |
| Connections | Per RFC 6056, one IP address on a Linux host tops out at 65,535 sockets | Widen the ephemeral port range; split very large tests across machines |
Measure before you buy. A 100-VU run on a workstation gives the memory figure; a short run on the target flavor shows whether CPU or the port saturates first. k6 scales roughly with hardware, so twice the resources give roughly twice the traffic until open connections become the ceiling.
Linux limits to raise before the first run
Default Linux limits on open files and local ports are set for ordinary hosts, not for tens of thousands of concurrent connections. The large-tests guide gives these commands, run as root:
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_timestamps=1
ulimit -n 250000
The sysctl values apply at once to the whole system and reset after a network service restart or a reboot; ulimit applies only to the current shell. Grafana's OS fine-tuning page shows how to persist them: soft and hard nofile lines in /etc/security/limits.conf for the user that runs k6 (a * entry does not cover root), which apply at the next login, and the port range in /etc/sysctl.conf. It also warns that the port range covers both TCP and UDP and that tcp_tw_reuse is a last resort. Alter a single setting per run and compare.
On a generator that exists only for a test, the per-shell ulimit and runtime sysctl are often enough: the machine is released before a reboot would undo them.
Setting up k6 on the machine
- Order a Linux flavor with Ubuntu or Debian and paste your SSH key, so root logs in over SSH from the first boot.
- Install k6 from Grafana's package repository with the commands below.
- Apply the limits from the previous section in the shell that will run the test.
- Copy the script up, then start with a short, low-VU run to confirm the target answers and the checks pass.
- Run the full test in one terminal and watch CPU, memory and network in another with
htopandiftop. - Copy the summary and any result files off the machine, then release it.
curl -fsSL https://dl.k6.io/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/k6-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
On AlmaLinux or Rocky Linux, use the two dnf commands Grafana documents for Fedora/CentOS: sudo dnf install https://dl.k6.io/rpm/repo.rpm, then sudo dnf install k6. To keep memory per VU down, the guide recommends discardResponseBodies: true when the script does not read bodies, SharedArray for test data, and guarding checks so that an empty body under load does not throw.
A generator that exists for one test
A load test is a burst: an hour of saturation, a few runs before a release, a soak over one night. Paying a month for that is waste. The elastic plans on our Cloud VPS in New York bill the way the job is shaped:
- Compute is billed by the second, and only while the machine runs.
- Disk and IPv4 accrue hourly for as long as the machine exists, running or stopped, so a stopped generator parked between test days costs only those two.
- Egress is metered per GB, with neither an allowance nor a throttle, so a long run is never shaped down halfway through; ingress is free.
- Nothing is paid up front: a card is kept on file, the checkout holds a week of running time on it, and usage is invoiced once the month ends, or earlier if it crosses a small threshold.
- Release the machine from the dashboard when the test is done; the last usage goes on a final invoice.
The traffic split suits a load generator. Requests leave the machine as egress; response bodies arrive as ingress, which is not billed. A download-heavy test therefore costs little in traffic, while an upload-heavy test is the one to estimate first.
Each flavor is a KVM guest running Debian, Ubuntu, Rocky Linux or AlmaLinux from the distribution's official cloud image, with root over SSH, a noVNC console from the Virtual Machines tab, and a Docker one-click app if you prefer the grafana/k6 image. A flavor can be resized up through support; the machine restarts once and keeps its addresses and data.
Where a VPS stops being the right generator
A Cloud VPS vCPU is a thread scheduled on a physical core that other guests use too; vCPUs are not pinned. For a generator that is a real caveat, because k6 reads contested CPU as slower responses. Hold k6 well under the 80% line, repeat runs, and compare.
- Each flavor caps its virtual port at the speed in its table, in each direction. If iftop shows traffic flat at that figure, the port is the limit, not the target.
- The Cloud VPS is sold in New York only. Tests that must come from users' regions need generators elsewhere; our dedicated servers run in five cities.
- A generator that runs every day, or a soak that keeps every core busy, belongs on a machine of its own. A racked machine from the instant range is live about 30 minutes after approval, on an unmetered port with no traffic allowance.
- Past one gigabit, a dedicated server takes a faster port; the 10 Gbps port is one switch port per server, not a shared uplink.
Above one machine's capacity, k6 can split a test with --execution-segment and --execution-segment-sequence. There is no primary instance: start the generators together with --paused and the REST API, and aggregate their metrics yourself.
Questions
How many virtual users can one k6 machine run?
Grafana's large-test guide puts a single k6 instance at 30,000-40,000 concurrent VUs, depending on resources and script. The real ceiling is usually CPU above 80%, memory per VU, the port, or open sockets. Run a short test on the target flavor and watch htop and iftop to find which one binds first.
How much RAM does a k6 load generator need?
Run the script with 100 VUs on a workstation, note the memory, and multiply by the VU count you plan. Simple scripts use about 1-5 MB per VU; file uploads or large JS modules can take tens of MB each. Leave headroom so physical memory stays under 90%, and disable swap.
Why does k6 report "socket: too many open files"?
The generator hit its file descriptor limit. Raise it with ulimit -n in the shell that runs k6, and for a persistent change add soft and hard nofile lines to /etc/security/limits.conf for that user. Each open connection uses a descriptor, so large tests hit the default quickly.
Can I run k6 on the server I am testing?
You can, but the numbers will describe two processes fighting for the same CPU, memory and network. k6's response times grow when its own CPU is saturated, so a busy target slows the generator and the generator slows the target. Use a separate machine.
What does an elastic load generator cost when it is stopped?
Stopped, it costs only its disk and IPv4 address; both accrue hourly while the machine exists. Compute stops the moment the machine stops. The service page lists the hourly and stopped rates for each flavor; release the machine when you no longer need it and billing ends.
Is a shared vCPU accurate enough for load testing?
For most API and website tests, yes, if you keep k6 well below 80% CPU and repeat runs to check the results agree. vCPUs on the Cloud VPS are not pinned to cores, so a test that needs every core all the time, or very tight latency comparisons, belongs on a dedicated server.