Skip to content

Launch spike and soak

Game launches are the highest-stakes performance events in software. The window between “game goes live” and “login servers fall over” can be under five minutes. This page covers how to plan and execute the two complementary tests that make a game ready to ship: the launch spike that validates your system can absorb the day-one storm, and the overnight soak that validates it can run cleanly for the next 72 hours.

  • Your game server, matchmaking, and backend APIs have each passed their individual load tests.
  • The full test suite (spike + soak) should be run in the staging environment, not production.
  • Alert ops and QA before running — a spike at launch-scale can cause elevated errors visible in monitoring.
  • Read Test types: Spike test and Test types: Soak / endurance test for the underlying test patterns.

The first 10 minutes after a game goes live produce a concentrated login storm unlike anything the service will see again at steady state. Every player who has pre-registered or pre-loaded the client hits the login, authentication, and matchmaking services simultaneously. The spike test validates:

  • The authentication service handles the full registration queue without 5xx responses.
  • Session allocation does not fail when match demand exceeds the pre-warmed server pool.
  • Leaderboard and profile services handle the simultaneous write blast at first login.
  • The system recovers and stabilizes after the initial surge — not just survives it.
PhaseVUsDurationNotes
Baseline501 minWarm state, no storm
Launch surge5 0003 minPeak login density
Hold at peak5 0005 minSustained post-surge load
Ramp down502 minBack to steady state
Recovery observation503 minWatch for lingering errors

Total run time: ~14 minutes. The recovery observation phase is critical — a system that survives the surge but continues to show errors after load drops has a resource-exhaustion problem (connection pool, thread pool, in-flight request queue) that will manifest throughout the launch day.

execution:
- executor: k6
concurrency:
- const: 50
duration: 1m
- const: 5000
duration: 3m
- const: 5000
duration: 5m
- const: 50
duration: 2m
- const: 50
duration: 3m
scenario: launch-login
scenarios:
launch-login:
script: launch-spike.js
launch-spike.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
thresholds: {
http_req_duration: ['p(95)<500'], // auth + session under 500 ms at p95
http_req_failed: ['rate<0.01'], // < 1 % errors at peak
},
};
export default function () {
const headers = { 'Content-Type': 'application/json' };
// Step 1: Authenticate
const authRes = http.post(
'https://auth.staging.example.com/v1/login',
JSON.stringify({ username: `loadtest-user-${__VU}`, password: __ENV.TEST_PASSWORD }),
{ headers }
);
check(authRes, { 'login 200': (r) => r.status === 200 });
if (authRes.status !== 200) return;
const token = authRes.json('access_token');
const authHeader = { headers: { Authorization: `Bearer ${token}`, ...headers } };
// Step 2: Load player profile (every player on login)
const profileRes = http.get('https://api.staging.example.com/v1/players/me', authHeader);
check(profileRes, { 'profile 200': (r) => r.status === 200 });
// Step 3: Enqueue for matchmaking
const queueRes = http.post(
'https://matchmaking.staging.example.com/v1/queue',
JSON.stringify({ mode: 'casual' }),
authHeader
);
check(queueRes, { 'queue 202': (r) => r.status === 202 });
sleep(2);
}

import Screenshot from ‘@components/Screenshot.astro’;

After the launch spike validates the day-one storm, the overnight soak validates the next 72 hours: steady-state load held for 8–12 hours to surface slow resource leaks, database connection exhaustion, and gradual latency drift. For games, the soak also validates the game-loop stability — that the game server does not accumulate lag or drop events over long session windows.

Use the same VU count as your steady-state load test — not the spike peak. The soak is not about maximum load; it is about continuous load over time.

ParameterValue
VUsSteady-state target (e.g. 1 000 concurrent players)
Ramp-up5 min
Hold8–12 h
LocationSame as production distribution
Stop modeDuration
execution:
- executor: k6
concurrency: 1000
ramp-up: 5m
hold-for: 8h
scenario: overnight-soak
scenarios:
overnight-soak:
script: game-server-load.js # same as concurrent-player test

Set a Failure criteria on error rate (> 0.5 %) and p95 message latency (> 150 ms) so MaxoPerf automatically fails the run if a leak causes degradation mid-soak — you do not need to watch the dashboard overnight.

After the soak completes, open the Overview tab and look for:

  • Latency drift. p95 message latency should be flat across 8 hours. An upward drift of more than 20 % is a signal worth investigating — it often indicates a memory or connection pool leak.
  • Throughput decline. Messages per second at constant VUs should be flat. A decline signals the server is processing each tick more slowly over time (garbage collection pauses, increasing lock contention, growing data structures).
  • Error rate inflection. Errors that appear only after 4–6 hours are characteristic of resource exhaustion (open file descriptors, connection pool limits, session table overflow).

Cross-reference MaxoPerf’s latency drift chart with your server’s heap metrics, open connection count, and GC pause logs to pinpoint the root cause.

Run the launch spike first. If the spike passes all thresholds, run the overnight soak. If the soak shows drift after 4 hours, fix the leak and run the spike again to confirm the fix did not change launch-day behavior. These two tests together give you the full pre-launch performance sign-off.

Do:

  • Include a recovery observation window (3 min minimum) after the spike — the recovery curve is as important as surviving the peak.
  • Use the same test scenario for both spike and soak so you are testing the same code paths.
  • Set failure criteria before the run — you should never be in a position where you are manually deciding whether a 420 ms p95 is “acceptable” during a launch-night review.

Don’t:

  • Skip the soak because the spike passed — they test different failure modes.
  • Run the soak at spike-level VU count — that tests sustained stress, not steady-state stability, and will exhaust resources that would never be exhausted in normal operation.
  • Use production player accounts as test identities — always use dedicated loadtest accounts with the same permission set as real players.