
How to Run a Load Test for any Online Multiplayer Game
This guide explains how, including which tools, to run a load test online multiplayer game, specifically matchmaking and game server deployments on the Edgegap platform using the Edgegap API.
This guide applies to any game engine (e.g., Unreal Engine, Unity, etc.), any game genre and all intended hardware (PC, Consoles, VR, WebGL, mobile, etc.)
Covered topics (by section):
Pre-requisites
Matchmaking flow & deployment planning
API rate limits
Deployment APIs
Deployment lifecycle management
Deployment status
Webhooks
Load test execution plan
Realistic traffic modeling
Traffic Profiles
Traffic Targets
When to involve Edgegap’s team
Recommended Tools
Note: If you do not use Edgegap's matchmaking, you can skip ahead and go directly to section #4 “Deployment API”.
Target Audience
This document is for backend engineers, DevOps teams, and studios preparing for production launch.
Target Timeline
While there is never ideal time to run a load test, but we recommend a dry run a few weeks ahead of launch to assess any weaknesses in your multiplayer game’s architecture.
See our Multiplayer Game Pre-Launch Checklist for a recommended timeline ahead of launch.
What is a Load Test for Multiplayer Games and Why its Important
A load test is a performance test that simulates large numbers of concurrent players (“CCUs”) to assess how a multiplayer game’s infrastructure holds up under stress, including matchmaking and game servers deployments.
By load testing before launch, issues can be identified, such as memory leaks, database query bottlenecks, inefficient netcode, and fix it ahead of release.
As we’ve often covered in the past, the outcome of being unable to prepare, and thus scale seamlessly at launch, can costs game developers millions of dollars due to the game being unavailable (even if you spent AAA-level of resources ahead of launch to avoid it).
Hence why studio use’s Edgegap game server orchestration, which has proven to scales up to 14M concurrent players in 60 minutes with 40 deployment per second, sustained, over that period. And thus, more over that initial hour.
1. Pre-Requisites
Goal of this step: make sure to make sure you have the pre-requisites needed for the load test.
Purpose: ensure your testing environment mirrors your production configuration.
Edgegap provides an HTTP API to manage game server deployments. As reminder, a deployment is a containerized instance of your game running on Edgegap's edge network.
Before load testing, ensure you have:
An Edgegap account, with billing configured
An API token
Note: Your API token will be included in every request header like this:
Authorization: token <your-token>. Keep this token secure as it has full access to your Edgegap resources.
A containerized game server packaged as an Edgegap application version
A backend system capable of making HTTP API calls
Be aware that API reference is available in our documentation here: https://docs.edgegap.com/docs/api
2. Understanding Matchmaking & Deployment Planning
Goal of this step: Map out how your matchmaking system translates player activity into deployment requests.
Purpose: Accurately simulate real player behavior within the game’s deployment flow. Alongside estimate enough deployments to match performance data that reflects launch day.
In a production multiplayer environment, your matchmaking flow typically looks like this:
Player Login → Matchmaking Queue → Match Found → Deployment Created → Server Ready → Players Connect → Match Runs → Deployment Deleted
The critical insight here is that each match requires exactly one deployment. This one-to-one relationship is the foundation of your capacity planning.
Calculating Your Deployment Needs
Let's work through the math. If your game supports N players per server instance, you can calculate exactly how many deployments you might need:
Total Players | Players per Match | Required Deployments |
|---|---|---|
10 | 2 | 5 |
40 | 4 | 10 |
60 | 6 | 10 |
60 | 12 | 5 |
This effectively means that “Required Deployments” is the intended target number of deployment.
Estimating Playerbase Scaling
Using the number of deployments per total players, the next step is to estimate the number of these deployments over time (i.e., “scaling”).
This is where most game developers make the mistake of load testing its entire player base over minutes, over-estimating the number of deployments per seconds to “scale” to their launch targets.
As an example, the world’s most popular game, Fortnite, all-time peak concurrent users at 14.3 million with an estimated 100/deployment per seconds. Yet Fortnite averages at its daily peaks between 30-40 deployments per seconds. As players, join and leaves games based on their daily life (sleeping, going to work) like waves. Thus, realistically, even if a game is launched worldwide at the same time, a load test should account to 25-50% of its peak launch concurrent users scaling over 60 minutes to be realistic.
i.e., the formula is: (required deployments * estimated peak %) / 3,600 seconds = deployments per second target for the load test
3. Respecting API Rate Limits (Critical)
Goal of this step: Understand and work within server deployment’s rate limits.
Purpose: Ensure your load test reflects real-world constraints. Avoid hitting rate limits during your test as it may mask real performance issues. While unlikely, if you face the same limits in production, your test must account for them.
Edgegap enforces organization-wide rate limits to ensure system stability. These apply to entire organization.
Please refer to the documentation, but Edgegap’s API rate limits are as of writing:
Endpoint Type | Limit |
|---|---|
Deployment endpoints | 40 requests/sec |
Status & context endpoints | 10 requests/sec |
Specifically for matchmaking, each tier has the following limits:
API Endpoint | Free Tier | Hobbyist Tier | Studio Tier | Enterprise Tier |
|---|---|---|---|---|
Overall Limit | 100 | 200 | 750 | 2,000 |
Create Deployment | 5 | 10 | 30 | 30 |
List Beacons | 10 | 20 | 75 | 200 |
Create Group + Create Ticket + Create Group Ticket | 10 | 20 | 75 | 200 |
Read Membership + Read Group + Read Ticket | 10 | 120 | 450 | 1,300 |
Create Backfill | 5 | 10 | 37 | 100 |
When you exceed these limits, the API returns HTTP 429 – Too Many Requests. Make sure to respect these limits to avoid this error message.
Best Practices for Rate Limit Compliance
To stay within limits and ensure reliable performance:
Implement exponential backoff when you receive a 429 response. Don't just retry immediately as that compounds the problem.
Always respect the Retry-After header in 429 responses. It tells you exactly how long to wait before retrying.
Avoid burst spikes by distributing deployment requests over time. Gradual ramps are more realistic anyway.
Use webhooks instead of polling to track deployment status. This dramatically reduces your status endpoint usage.
⚠️ Important: If you're planning a large-scale load test (sustained load over several hours or high deployment rates), coordinate with Edgegap support beforehand. They can temporarily increase your limits and pre-scale capacity to ensure accurate test results.
4. Creating Deployments via the API
Goal of this step: Learn how to programmatically create game server deployments with proper configuration and monitoring.
Purpose: Getting the API calls is core to the deployment flow. It ensures your servers deploys at the optimal location for all players and proper webhook notifications.
The deployment creation endpoint is your primary interface for launching game servers.
The Create Deployment Endpoint
Endpoint: POST https://api.edgegap.com/v2/deployments
Rate Limit: 40 requests/second (organization-wide)
Required Headers:
Authorization: token <your-token>
Content-Type: application/json
Example Request Body
Here's a complete example showing all the key parameters you should include:
{
"application": "my-game-server",
"version": "v1.0.0",
"users": [
{
"user_type": "ip_address",
"user_data": {
"ip_address": "1.2.3.4"
}
}
],
"tags": ["matchmaking", "load-test"],
"webhook_on_ready": {
"url": "https://your-backend.com/webhooks/deployment-ready",
"method": "POST"
},
"webhook_on_error": {
"url": "https://your-backend.com/webhooks/deployment-error",
"method": "POST"
}
}
Understanding Key Parameters
users array: This is how Edgegap determines optimal geographic placement for your deployment. Include the IP addresses of the players who will connect to this match. The system uses this information to select the edge location that minimizes latency for all participants.
webhooks: Strongly recommended over polling. Webhooks give you instant notifications when deployments become ready or encounter errors, allowing you to move players into matches immediately without constant status checks.
tags: Use tags to organize and filter your deployments. During load testing, tags help you identify which deployments belong to your test versus production traffic.
5. Managing the Deployment Lifecycle
Goal of this step: Implement proper deployment cleanup to avoid wasting resources and ensure accurate load test metrics.
Purpose: Orphaned deployments that aren't properly terminated will inflate your costs, consume capacity, and make your load test results meaningless as you need to see how the system handles the full create-run-delete cycle.
A common mistake in load testing is focusing only on deployment creation while ignoring cleanup. In a real production environment, matches end which terminates servers to avoid overspending on resources. Your load test must simulate this complete lifecycle (and save you money on the load test itself).
Deleting Deployments from Your Backend
When a match ends, your matchmaking backend should immediately delete the deployment.
Endpoint
DELETE https://api.edgegap.com/v2/deployments/{request_id}
Headers
Authorization: token <your-token>
The request_id is returned when you create the deployment. Store this ID in your matchmaking system so you can reference it when the match concludes.
Alternative: Self-Termination (i.e., Let the Game Server Decide)
There's an alternative approach that gives you more flexibility: every deployment includes a unique deletion URL and token that allows the game server itself to shut down when appropriate. This is particularly useful when your game logic knows best when a match is truly finished.
For example, your game server might wait until all players have disconnected, post-match statistics are uploaded, and any replays are saved before triggering its own termination. This approach ensures nothing is lost in the cleanup process.
Learn more about self-termination in the Edgegap's deployment lifecycle documentation.
Reminder: Costs of Failing to Terminate Servers
Failing to properly delete deployments will:
Dramatically increase your costs as you pay for idle servers
Skew your load test results by making it appear you need more capacity than you actually do
Create operational issues as your dashboard fills with zombie deployments
During your load test, implement monitoring using Edgegap’s analytics to detect any deployments that aren't being properly cleaned up.
-> These orphaned deployments are a red flag that your lifecycle management must be adjusted before launch.
6. Tracking Deployment Status
Goal of this step: Understand how to monitor deployment readiness without overwhelming the API with status checks.
Purpose: Knowing exactly when a deployment is ready to accept players is crucial for matchmaking flow. However, aggressive polling can trigger rate limits and doesn't reflect production best practices.
After creating a deployment, you need to know when it's ready for players to connect. There are two approaches: polling the status endpoint or using webhooks. One is significantly better than the other.
Webhooks: The Right Approach
Instead of asking "is it ready yet?" every second, let Edgegap notify you immediately when something changes. This is what webhooks do, and they're the recommended approach for production systems (see step 7).
When you include webhook URLs in your deployment creation request (as shown in Section 4), Edgegap will send an HTTP POST to your backend the instant a deployment becomes ready or encounters an error. Your system can then immediately assign players to that match server without any polling delay.
Best practice: Use webhooks as your primary notification mechanism. Reserve the status endpoint for exceptional cases where you need to manually check a deployment's state—perhaps during debugging or handling rare edge cases.
The Status Endpoint (Use Sparingly)
GET https://api.edgegap.com/v1/status/{request_id}
Rate Limit: 10 requests/second
This endpoint returns the current state of a deployment:
Status.DEPLOYING – Server is spinning up
Status.READY – Server is ready for player connections
Status.ERROR – Something went wrong during deployment
While this endpoint works, polling it repeatedly for hundreds of deployments quickly becomes problematic. You'll burn through your rate limit and create unnecessary load on the API.
7. Implementing Webhooks for Production-Grade Monitoring
Goal of this step: Set up reliable webhook handling to receive real-time deployment notifications.
Purpose: Webhooks eliminate polling overhead, provide instant notifications, which are essential for building a responsive matchmaking system that can move players into games without delay.
Webhooks are HTTP callbacks that Edgegap sends to your backend when deployment state changes. Think of them as push notifications for your matchmaking system. Instead of constantly checking if something happened, you're immediately told when it does.
Available Webhook Events
Webhook Type | Trigger Condition |
|---|---|
webhook_on_ready | Deployment is ready for player connections |
webhook_on_error | Deployment failed during startup |
webhook_on_terminated | Deployment has been terminated |
The webhook payload contains the same data as the /v1/status/{request_id} endpoint; you get complete deployment information including connection details, region, and status.
Webhooks Requirements
Return HTTP 2xx: Your webhook endpoint must return a success status code (200-299) to acknowledge receipt. Any other status code or timeout signals a failure.
No automatic retries: Edgegap does not retry failed webhook deliveries. If your endpoint is down or returns an error, you miss that notification. This is why you need to implement your own retry logic and maintain deployment state in your backend.
Implement idempotency: Although Edgegap doesn't retry, network issues or your own systems might cause you to process the same webhook multiple times. Design your webhook handler to safely handle duplicate notifications without corrupting your state.
Best Practices
Using Webhooks to Drive Player Assignment: the time players spend waiting and eliminates the overhead of constant status polling. During your load test, measure how quickly you can move from deployment creation to player connection. Here’s a typical flow
Match is formed, deployment is created with webhook_on_ready configured
Players wait in a "match starting" state
Webhook arrives at your backend: "deployment XYZ is ready"
Your backend immediately sends connection details to waiting players
Players connect and the match begins
Store deployment state: Don't rely solely on webhooks. Maintain a database of deployment states in your backend so you can recover from missed notifications or system restarts. Use webhooks to update this state, but keep the source of truth in your own infrastructure.
Avoid aggressive polling
8. Load Test Execution Plan Suggestion
Goal of this step: Create a structured, multi-phase load test that validates every aspect of your deployment pipeline.
Purpose: Attempt to simulating a timeline of your launch and player journey to ensure every component works under pressure similar to launch day.
Phase 1: Prepare Test Clients
Before you can create deployments, you need something to create them. Build test clients that simulate your matchmaking system's behavior:
· Simulate realistic matchmaking traffic that mirrors how players actually queue for games
· Generate deployment requests from your backend when matches form
· Handle webhook responses and update match state accordingly
· Track all deployment lifecycle events for later analysis
These test clients are essentially a simplified version of your production matchmaking backend. They don't need to be as robust, but they must accurately represent your API usage patterns.
Phase 2: Execute Deployment Creation Ramp
Start creating deployments gradually, respecting rate limits and following a realistic arrival curve. This phase tests your ability to scale up deployment creation as player traffic grows:
Begin slowly and ramp up progressively—avoid instant spikes that don't reflect real player behavior
Stay well within API rate limits by distributing requests evenly
Follow a progressive curve that simulates organic player arrival (more on this in Section 10)
Monitor for rate limit errors and adjust pacing if you encounter 429 responses
This phase validates that your deployment creation logic can handle your expected player arrival rate without overwhelming the API.
Phase 3: Track Deployment Readiness
As deployments spin up, monitor when they become ready for player connections:
Rely primarily on webhooks for ready notifications (as discussed in Section 7)
Optionally poll /v1/status sparingly if webhooks aren't feasible for your test setup
Measure time-to-ready for each deployment—this directly impacts player waiting time
Track error rates and investigate any deployments that fail to reach READY state
If you're seeing long deployment times or high error rates during this phase, you need to investigate before going further. These issues will compound as you scale to full production load.
Phase 4: Simulate Player Connections (If Possible)
This phase is optional but highly valuable. Once deployments report READY, actually connect simulated players to test the complete pipeline:
Launch game client bots that connect using the deployment's connection information
Track connection success rates—some deployments might report READY but still fail connections
Measure network latency from simulated player locations to their assigned servers
Verify gameplay functionality if your bots can execute basic in-game actions
This phase reveals issues that only appear when real client connections happen. If you can't implement full game client simulation, at minimum test raw network connectivity to each deployment's IP and port.
Phase 5: Execute Cleanup and Validation
The final phase validates your deployment lifecycle management:
Terminate deployments as simulated matches complete (see Section 5)
Scan for orphaned deployments that weren't properly cleaned up
Verify lifecycle correctness by checking that deployments move through all expected states
Analyze the data you collected throughout all phases to identify bottlenecks and failures
A successful cleanup phase should show zero orphaned deployments and confirm that your system properly manages the full create-run-delete cycle at scale.
9. Modeling Realistic Player Traffic
Goal of this step: Design load test patterns that accurately reflect how real players join a game’s matches and scales your game server deployments.
Purpose: Align with realistic traffic patterns to produce meaningful insights. If your test doesn't match realistic beajvior, you won't uncover potential real issues at launch.
Here's a critical truth about load testing: synthetic stress tests don't reveal production problems.
If you create 1,000 deployments instantly, you're not simulating a real launch, you're just proving that the API can reject your requests with 429 errors.
What to Avoid
Avoid these unrealistic test patterns:
Creating thousands of deployments instantly: real players don't all arrive at the exact same millisecond
Ignoring the matchmaking flow: production deployments are created as matches form, not on a timer
Skipping deployment cleanup: real matches end and free capacity for new ones
Testing only short bursts: production load is sustained over hours, revealing issues that short tests miss
Running tests without backend orchestration: your actual system includes matchmaking logic, queues, and state management
These patterns might stress the system, but they don't validate that your actual production architecture will work.
What a Good Load Test Simulates
A realistic load test models these behaviors. For example, align with a comparison games using SteamDB’s CCUs tracker. E.g., PEAK’s massive success still took days to scale to its highest CCU peak, with its biggest increase of 40,000 CCUs accomplished over a full day and yet an average CCU of 20,000 versus its peak within that day.
Player arrival rate: players trickle in at first, then arrive in waves during peak hours.
Match creation frequency: based on how quickly your matchmaker can form groups
Complete deployment lifecycle: creation, readiness, player connections, match duration, and cleanup
Variable session duration: some matches are quick, others run longer
Geographic distribution: players come from different regions, affecting deployment placement
When you model these factors, your load test becomes a true validation of your production readiness rather than just an API stress test.
10. Traffic Profiles Examples
As previously stated, the most likely scenario is going to be matching a comparison title within the same genre and scope of project using SteamDB and apply a multiplier for simultaneous console release (3-5x for PlayStation, 1x for XBOX).
With this being said, let's look at three different scale scenarios. Evaluate the one that matches your expected launch traffic, or create a custom profile based on these examples
Scenario A: Indie Launch (200 Concurrent Players)
Metric | Value |
|---|---|
Concurrent players | 200 |
Players per match | 2 |
Matches per minute | 5 |
Deployments per minute | 5 |
Peak active deployments | ~100 |
Recommended test plan: Ramp from 0 to 5 deployments/minute over 10 minutes, then sustain for 60 minutes.
Scenario B: Mid-Size Multiplayer Title (2,000 Concurrent Players)
Metric | Value |
|---|---|
Concurrent players | 2,000 |
Players per match | 4 |
Matches per minute | 20 |
Deployments per minute | 20 |
Peak active deployments | 400–600 |
Recommended test plan: Ramp from 0 to 20 deployments/minute over 20 minutes, then sustain for 90 minutes.
Scenario C: Large Event / Beta Weekend (10,000 Concurrent Players)
Metric | Value |
|---|---|
Concurrent players | 10,000 |
Players per match | 6 |
Matches per minute | 50 |
Deployments per minute | 50 |
Peak active deployments | 1,200–1,500 |
Recommended test plan: Ramp from 0 to 50 deployments/minute over 30 minutes, then sustain for 2 to 4 hours.
Implementing a Realistic Ramp Curve
Regardless of your scale, follow a progressive ramp pattern like this:
Time (minutes) → Deployments/minute0–10 → 0 → 5
10–20 → 5 → 15
20–30 → 15 → 30
30–60 → Sustain at peak
This progressive curve simulates:
Organic player arrival as word spreads that servers are online
Matchmaker warm-up as queues fill and matches begin forming
Deployment provisioning ramp as Edgegap scales capacity to meet demand
Network routing stabilization as traffic patterns establish and optimize
Add some randomness to your deployment timing too. Do not create them on exact second boundaries. Real matchmaking has natural variance in when matches form.
11. Defining Production Validation Targets
Goal of this step: Establish clear success criteria so you know whether your load test passed or revealed problems.
Purpose: Concrete metrics are needed to determine if you're launch-ready or need to further optimization.
A successful load test isn't just about "running without crashing." You need specific performance targets that define acceptable player experience. Here are the key metrics you should validate:
Metric | Target |
|---|---|
Match creation latency | < 5 seconds |
Deployment ready time | Depends on game server boot time |
Player connection success rate | > 99% |
API rate limit saturation | Zero 429 errors |
Orphaned deployments | 0 (zero) |
Match creation latency: This measures how long it takes from "match formed" to "deployment API call completed." Players are waiting during this time, so keeping it under 5 seconds maintains good user experience.
Deployment ready time: This depends heavily on how quickly your containerized game server can boot and become ready for connections. Optimize your container startup time during development—a 30-second boot is better than a 2-minute boot.
Player connection success: Above 99% means nearly every player successfully connects to their assigned server. If you're seeing connection failures, investigate whether it's a network issue, a game server problem, or incorrect connection details being provided to clients.
API rate limit saturation: You should complete your load test without hitting rate limits. If you're getting 429 errors, your deployment request pattern is too aggressive and won't work in production either.
Orphaned deployments: Zero orphans means your lifecycle management is working correctly. Even one orphaned deployment suggests a bug in your cleanup logic that will waste resources at scale.
Use the load test data to identify bottlenecks, optimize your systems, and test again. It's far better to delay launch than to face infrastructure failures with real players.
12. Coordinating with Edgegap for Large-Scale Tests
Goal of this step: Ensure Edgegap's infrastructure is ready to support your load test at scale.
Purpose: Large load tests require coordination to ensure accurate results.
If your load test involves significant scale, don't just start hammering the API. Give Edgegap a heads up to help you prepare our infrastructure to handle your test properly, as it would with a large launch.
When to Coordinate in Advance
Notify Edgegap if your test involves:
More than 20 deployments per second sustained over time
Sustained load over several hours (2+ hours at peak)
Multi-region simultaneous traffic that spans multiple geographic areas
Tests scheduled close to your launch date where you need guaranteed results
Contact Edgegap through the Dashboard → Tools section or via the Edgegap Discord community. Provide details about your expected deployment rate, test duration, and target regions.
What Coordination Enables
When you coordinate in advance, Edgegap can:
Pre-scale capacity in the regions you'll be testing, ensuring servers are available immediately
Temporarily increase rate limits if your test legitimately requires higher throughput
Monitor infrastructure readiness and proactively address any capacity constraints
Provide technical support if you encounter unexpected issues during the test
This coordination ensures your test accurately reflects production performance rather than measuring Edgegap's cold start scaling capabilities. The goal is to validate your system first and foremost.
13. Recommended Load Test Tools
For executing your load tests, we recommend two industry-standard tools: Apache JMeter and k6.
Both are purpose-built for load testing APIs and can simulate realistic deployment request patterns while respecting rate limits.
Apache JMeter: JMeter provides a visual interface for designing complex test scenarios, making it ideal for teams who prefer GUI-based test configuration and want built-in reporting dashboards without writing code.
k6: k6 uses JavaScript for test scripts and excels at modern CI/CD integration, making it great for teams who want to version-control their load tests alongside their code and automate testing in deployment pipelines.
Conclusion
Load testing your multiplayer game infrastructure is a critical milestone before your launch.
It's your opportunity to discover and fix problems before they impact real players. By following this comprehensive approach, you'll validate not just that your servers can handle load, but that your entire matchmaking-to-gameplay pipeline works reliably at scale.
Good luck with your launch! If you have questions or need assistance with your load testing strategy, the Edgegap team is here to help on Discord, email or on Slack (upon request).
Written by
the Edgegap Team








