Stress Testing for Gaming Platforms With Peak Player Activity
Stress test login, matchmaking and leaderboard APIs with 3,000 players arriving inside a minute, the way a launch or event drop does. Config and k6 script.
Simulate the minute a game goes live
Player traffic does not ramp politely. A launch, a patch, an event drop or a streamer going live puts thousands of players on the login, matchmaking and leaderboard APIs inside a minute, and the queue that forms in that minute is what players tweet about. This template compresses the ramp to 60 seconds, holds the peak for ten minutes, and measures the APIs that every player hits on the way in.
Configuration
| Setting | Value | Why |
|---|---|---|
| Virtual users | 3,000 | A modest launch spike; scale to your concurrent-player forecast. |
| Duration | 10 minutes | The queue clears or it does not within the first few minutes; the rest is the steady state. |
| Ramp-up | 60 s in 3 steps | 1,000 players every 20 seconds is the spike shape; the results page shows each step. |
| Requests | login, profile, matchmaking request, leaderboard | The path every player takes before playing; leaderboards are the usual expensive query. |
| Think time | 1 to 3 s | Players tap through menus quickly at launch. |
| Regions | 3, matching your player base | Latency to the matchmaking API differs by region, and so does the queue. |
Run this templateOpens the cloud test form with these values filled in. Free plan runs it at the free user limit; sign in or create a free account first.
The button prefills players, duration and the 60-second ramp. Add the endpoints with the auth your client uses (a header preset for the token), pick the regions, and start.
What to read in the results
- Login and matchmaking p95 in the first two minutes. That is the launch experience. Use the Timeline tab at 5-second granularity: a spike that clears is a queue that drained, one that stays is capacity.
- Leaderboard endpoint separately. Ranking queries scale badly with player count; a p95 that climbs with each step while login stays flat points at the ranking store.
- 429 and 503 during the ramp. A rate limiter or an API gateway is shedding load. That is a policy decision to review, not a bug, but it should not hit players who are already logged in.
Pass/fail thresholds for this template
| Threshold | Target | What a breach means |
|---|---|---|
| p95 response time | < 800 ms | Menus and matchmaking feel laggy at the spike. |
| Error rate | < 1% | Players are failing to log in or queue; every one is a support ticket. |
| Throughput | > logins per second forecast for launch | The entry path cannot admit players as fast as they arrive. |
Set them on the test and rerun before every event; the Trend tab shows whether the spike got better or worse.
The same scenario as a k6 script
As a k6 script the spike is three 20-second stages. Real-time game traffic (UDP, custom protocols) is out of scope; this covers the HTTP APIs around the match.
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [{ duration: '20s', target: 1000 }, { duration: '20s', target: 2000 }, { duration: '20s', target: 3000 }, { duration: '9m', target: 3000 }],
thresholds: { http_req_duration: ['p(95)<800'], http_req_failed: ['rate<0.01'] },
};
const BASE = 'https://api.game.example.com';
const H = { headers: { Authorization: `Bearer ${__ENV.LF_TOKEN}`, 'Content-Type': 'application/json' } };
export default function () {
check(http.post(`${BASE}/session/login`, JSON.stringify({ device: 'pc' }), H), { 'login 200': (r) => r.status === 200 });
check(http.get(`${BASE}/profile/me`, H), { 'profile 200': (r) => r.status === 200 });
check(http.post(`${BASE}/matchmaking/queue`, JSON.stringify({ mode: 'ranked' }), H), { 'queued': (r) => r.status === 200 || r.status === 202 });
check(http.get(`${BASE}/leaderboard?season=current&limit=100`, H), { 'leaderboard 200': (r) => r.status === 200 });
sleep(1 + Math.random() * 2);
}When to run it
- Before launch and before every live event that will be announced in advance.
- After patching the matchmaker or moving the leaderboard store.
- After a rate-limit change to confirm it sheds bots, not players.
FAQ on stress testing game launches
Can LoadFocus test the game protocol itself?
Not UDP or proprietary game protocols. It tests the HTTP and WebSocket APIs around the match: login, matchmaking, inventory, leaderboards, telemetry. For WebSocket sessions, see the WebSocket concurrency template.
Why 60 seconds and not a gradual ramp?
Because that is how a launch arrives. A gradual ramp finds the ceiling; the spike finds out whether the queue in front of it drains.
The matchmaking endpoint returns 202 for everyone.
That is correct behaviour for a queue. Measure the follow-up (the match-found poll or the WebSocket notification) in a second scenario if the time-to-match matters.
How do I get 3,000 distinct player accounts?
In the k6 script, load the accounts with SharedArray from a CSV and pick one per virtual user; in the cloud test, generate the account id with a random variable. Reusing one account tests the rate limiter, not the game.
How fast is your website?
Elevate its speed and SEO seamlessly with our Free Speed Test.Outgrown your testing tools?
Load test websites and APIs from 25+ cloud regions, monitor page speed and uptime, and get AI analysis that explains your results in plain English.Start for free→