A launch date is a traffic plan, not a traffic fact. A new title, a jackpot rollover, a knockout fixture or a campaign all change how many players arrive and how quickly — and whether the platform absorbs that change is a claim someone has to test rather than assume.
A load test answers one narrow question honestly: can this system, in this configuration, serve this mix of work at this rate without breaking its own objectives? Almost everything else said about load testing — that a platform “scales”, that it will “handle launch day” — is a prediction about traffic nobody has measured yet.

The launch itself is the spike
Google’s launch coordination checklist is a useful starting point because it was written to be run before a date, not after an incident. It asks a launch team for “HTTP traffic and bandwidth estimates, launch ‘spike,’ traffic mix”, for a “Load test, end-to-end test, capacity per datacenter at max latency”, for the “Impact on other services we care most about”, and for “Graceful degradation, how to avoid accidentally overrunning third-party services”.
That list is general to web services and predates most of the industry’s current tooling. Its shape still fits a gambling platform, because a launch is a step change rather than a slope. At the moment a title goes live, players arrive together, and each arrival is not one request. A session start, a lobby read, a balance check, a bet, an outcome, a wallet posting sequence and a history read are separate pieces of work that arrive multiplied by the same crowd.
Write the workload model before you write the script
A benchmark against one endpoint measures one endpoint. It says nothing about the platform. The first useful artefact of a capacity programme is therefore an inventory of the work the platform actually does, with each entry’s cost and side effects recorded:
| Work | What the test has to model | What it writes |
|---|---|---|
| Session start and authentication | Login bursts at the moment of a launch announcement, including the retries a slow response provokes | Session records and authentication events |
| Lobby, catalogue and game-detail reads | Mostly reads, cheap individually, dominant in volume | Nothing |
| Round lifecycle | Bet acceptance, outcome generation, and the wallet postings that settle the round | Ledger postings and round history |
| Jackpot contribution and accrual | A shared counter every contributing round touches | Accrual state and its justification records |
| Bonus evaluation and grants | Read-heavy rules plus occasional writes that create liability | Bonus records and outstanding liability |
| Payments | Deposit initiation, provider callbacks and withdrawals, each with its own external latency | Payment and wallet records |
| Back-office and reporting queries | Long, expensive, and often run by staff during working hours | Nothing, but they consume the same resources |
| Event and analytics streams | Continuous, asynchronous, and easy to forget when sizing | Stream offsets and derived reporting |
Two choices in that model decide what the test can conclude. The first is the mix: a run made mostly of lobby reads will pass comfortably while telling you nothing about the round path. The second is whether load is modelled as a fixed population of users or as a fixed arrival rate. The distinction is worth reading in the k6 documentation on open and closed models, because the two behave differently the moment the system slows down: one applies back pressure by waiting, the other keeps arriving.
A request count is not a capacity model
It is tempting to express capacity as requests per second and then compare that number with a launch estimate. The SRE chapter on handling overload explains why that comparison misleads: “Different queries can have vastly different resource requirements,” and modelling capacity as “queries per second” or as static request features “often makes for a poor metric”, because the ratios between requests change as the product changes. The chapter’s recommendation is to measure capacity in available resources — CPU first, in most cases — and to define per-customer limits so that one caller’s excess cannot starve the others.
For a gambling platform the practical version is that a settled round touching the ledger several times is not interchangeable with a lobby read. If the workload model does not carry a cost per unit of work, a peak figure derived from it is a number without units.
Test somewhere that can be wrong the same way
A load test run against an under-sized environment produces a confident number about the wrong system. Parity matters in the places that decide whether a query is fast: dataset volume and index size, table statistics, the configuration and feature-flag state under test, cache warmth, and whether integration partners are reachable at realistic latency. A restored, production-shaped dataset will find the slow query that a fixture of a few thousand rows never will. The non-production environment requirements guide covers what else such an environment has to separate before it can be used for this.
Six test types, six different failure modes
Grafana’s load test types page sorts the work into smoke, average-load, stress, soak, spike and breakpoint tests, and makes two points worth carrying into any capacity programme: “no single test type eliminates all risk”, and the categories are relative — “a stress test for one application is an average-load test for another”.
| Type | The question it answers for a platform | What to keep |
|---|---|---|
| Smoke | Does the script still exercise the real path after the last release? | The script version and a baseline result |
| Average load | Does the platform hold its objectives at the mix you expect? | Latency and error rate at the modelled rate |
| Stress | What happens past the expected peak, and where does it degrade first? | The point of first degradation, and the shape of it |
| Soak | Does the platform hold for hours rather than minutes? | Resource trend over the run, not just the endpoint |
| Spike | Does a sudden, short arrival survive without a cascade? | Recovery time and whether anything stayed stuck |
| Breakpoint | Where is the limit, and is the failure orderly? | The limiting resource and the refusal behaviour |
The soak window is where accumulation shows up
A one-hour test at average load exercises the paths; a soak test exercises the arithmetic of the platform holding state. The failures it finds are slow: a connection pool that leaks one handle per cycle, a session table that grows without a retention job, a cache that never evicts, a queue that is drained during the day and never overnight, accrual that drifts because a reconciliation job has not run, and log volume that fills a disk after a threshold nobody modelled. Grafana’s own description of a soak test is “the reliability and performance of your system over extended periods”, with a duration measured in hours rather than minutes.
Two practical rules make a soak test worth its calendar time: run it long enough to cross at least one scheduled maintenance or batch window, and watch resources over time rather than reading the end-of-run summary.
Synthetic load writes real financial records
A load test against a gambling platform does not resend a static page. Every simulated round creates ledger postings, every simulated bonus creates liability, and every simulated deposit creates a payment record. Those records land in the same tables the business reports from, and if the test is not identified they will be indistinguishable from real activity afterwards.
Decide before the run how synthetic traffic is marked, which tenants or accounts it uses, whether it is excluded from reconciliation, and when it is removed — and keep the record of that decision with the run. The wallet reconciliation requirements guide describes the controls those exclusions have to respect, and the security logging and audit evidence guide describes where a record of a deliberate test belongs.
Your peak is also your suppliers’ peak
A platform under load pushes its load outward. Payment providers rate-limit, identity vendors throttle, and game providers’ wallet endpoints have limits of their own. The checklist line about avoiding accidentally overrunning third-party services is a warning about exactly this: your spike becomes their spike, and their degradation comes back as your timeouts.
Confirm the published limits with each partner, model their realistic latency and their errors in the environment, and test how your platform behaves when they are slow rather than absent. An aggressive retry policy that is harmless at normal volume is how one slow dependency turns into a queue that saturates everything behind it.
Set the pass condition before you press start
The checklist asks for “capacity per datacenter at max latency”, and the qualification is the point: a capacity figure without a latency bound describes a system that served requests, not one that served them usefully.
Write the thresholds down first — the percentile that matters, the error rate that is acceptable, the mix the run must use, and the resource ceiling — and let the run produce a pass or a fail against them. A conclusion chosen after reading the results is an opinion with a graph attached. Where the objective is a service-level objective for players, the same discipline applies as to any other: the number is the thing you fail against.
Reject load deliberately, and prove you can
Under overload, the desirable behaviour is not to accept everything and collapse. It is to keep serving the traffic you can process and refuse the rest clearly. RFC 6585 defines the shape of that refusal: the 429 status code “indicates that the user has sent too many requests in a given amount of time (‘rate limiting’)”, the response “SHOULD include details explaining the condition, and MAY include a Retry-After header”, and a 429 “MUST NOT be stored by a cache”. The SRE chapter on handling overload makes the same point from the serving side: a task provisioned for a rate should “continue to serve traffic at that rate without any significant impact on latency, regardless of how much excess traffic is thrown at the task”, must not fall over, and that should hold “somewhere above 2x or even 10x what the task is provisioned to process”.
So the stress test has a second deliverable beyond a limit: the evidence that the refusal is orderly. Push past capacity on purpose and check whether callers receive a clear, retryable answer — or whether they receive timeouts while queues fill.
Keep a record that outlives the release
A capacity run that leaves no artefact is indistinguishable from one that was skipped. The record worth keeping is short: the script and workload version, the dataset and how it was produced, the topology and instance sizes, the configuration and feature-flag state, the load profile, the raw results, the thresholds, every exception with an owner, who read the result and what was decided, and the date.
Two more conditions belong in that record rather than in someone’s memory. First, a test against shared or production capacity needs a declared window, a named owner and a defined stop condition — a load test that starts affecting real players has stopped being a test and become the incident it was meant to prevent. Second, if the run is expected to produce a spike, the incident response plan guide is the document that should already name who is watching and who can stop it.
Stop at what the test proves
A passing run proves that this build, in this environment, served that modelled workload on that date at that rate. It does not prove that the platform is correct, that a live population behaves like the model, that a supplier will hold its own limits, or that the result survives the next release. Capacity is a trend, not a badge: a change to the round path, the data volume or the topology invalidates the last result, and the useful number is the one with a date and a build beside it.
That is also why a load test belongs on a schedule rather than in a launch checklist alone. The RGS observability guide covers the runtime side of the same question — what the platform records about itself while it is serving — and the two together are what turn a launch date from a hope into a watched event. The platform development work is where the capacity side of that release process sits.
Questions operators ask
How long should a soak test run?
Long enough to cross at least one scheduled batch or maintenance window, which in practice means hours rather than minutes. The point of the duration is not endurance for its own sake: it is to let leaks, growth and drift accumulate to a visible size.
Can a load test ever run against production?
Yes, but it is a different exercise with different rules: a declared window, a named owner, a defined stop condition and a decision about the synthetic records it creates. A load test that degrades the live service is an incident. Where the goal is measuring the platform rather than the change, testing on a production-shaped environment is the cheaper decision.
Does a passing load test prove the platform will survive launch day?
No. It proves that a modelled workload was served by a specific build in a specific environment on a specific date. A live player population decides its own mix, third parties impose their own limits, and the next release can change the cost of the work.








































