Load Testing: What Happens to Your Checkout Page at 10,000 Concurrent Users
A product launch goes out to an email list, a flash sale starts, a link gets shared somewhere bigger than expected. Traffic spikes from a few hundred visitors an hour to a few thousand in the same…
A product launch goes out to an email list, a flash sale starts, a link gets shared somewhere bigger than expected. Traffic spikes from a few hundred visitors an hour to a few thousand in the same five minutes, and checkout starts timing out. Nobody changed the code. The page that loaded in 1.2 seconds in every manual test and every Lighthouse run is the same page now returning 502s under real traffic.
That gap, a page that's fast for one person and falls over for ten thousand, is exactly what load testing exists to catch, and it's a completely different question than the one page-speed metrics answer.
A Different Question Than "Is This Page Fast"
Core Web Vitals, Lighthouse scores, and manual testing all measure the same thing from a slightly different angle: how a page performs for one visitor, under relatively normal conditions. That's a real and useful measurement, but it says nothing about what happens when a database connection pool runs out, when an API rate limit gets hit, or when a server's CPU is already at 90% handling the other nine thousand, nine hundred and ninety-nine requests arriving in the same second.
Load testing simulates many simultaneous users hitting a system at once, specifically to find the point where it stops handling that load gracefully: the request rate where latency starts climbing, the concurrency level where errors start appearing, the point where the system either degrades predictably or falls over entirely.
The Core Concepts
Virtual users (VUs) are simulated concurrent visitors, each independently making requests the way a real visitor would, loading the page, submitting a form, calling an API endpoint. A load test with 10,000 virtual users isn't one request repeated ten thousand times, it's ten thousand independent, overlapping sessions.
Ramp-up controls how quickly those virtual users are introduced. A test that jumps straight to 10,000 concurrent users instantly tests something different than one that ramps from 0 to 10,000 over five minutes, real traffic spikes are rarely instant, so a realistic ramp pattern usually gives a more useful picture of how the system behaves as load builds.
Throughput is how many requests the system successfully completes per second. Latency is how long each request takes. The relationship between them is the real story: throughput often looks fine right up until a threshold, and then latency spikes sharply as the system starts queuing requests faster than it can process them.
Error rate is the percentage of requests that fail outright, timeouts, 500s, connection refused, rather than just being slow. A system that gets slow under load but keeps succeeding is in a different state than one that starts actively failing requests, and both are worth knowing about separately.
Three Related But Different Tests
Load testing checks expected peak traffic, what does the system do at the busiest realistic load it's likely to see, a product launch, a seasonal spike, a marketing campaign. The goal is confirming the system handles expected demand without degrading.
Stress testing pushes past expected peak deliberately, increasing load until something actually breaks, to find the real ceiling and see how the system fails. Does it degrade gracefully, slower responses, clear error messages, or does it fail catastrophically, crashing, corrupting data, taking dependent services down with it?
Soak testing (or endurance testing) runs a sustained, moderate load over a long period, hours rather than minutes, to catch problems that only appear over time: a memory leak that's invisible in a five-minute test but crashes the process after six hours, a connection pool that slowly exhausts because connections aren't being released properly.
Each answers a different question, and a team that only ever runs a quick load test at expected peak traffic has no idea what their actual breaking point is, or whether the system would survive a long, sustained high-traffic period rather than a short burst.
What Actually Breaks First
The checkout page itself is rarely the bottleneck. The static assets, the HTML, the CSS, the JavaScript bundle, can usually be served from a CDN at effectively unlimited scale. What breaks under load is almost always something stateful behind the page: a database running out of connections because the connection pool wasn't sized for concurrent load, a payment processor's API rate limit getting hit because ten thousand checkout attempts are all calling it in the same window, a session store or cache that wasn't built to handle that many concurrent writes, or a single downstream service that everything else depends on becoming the entire system's ceiling.
This is why load testing a single page in isolation often misses the real problem. A realistic test needs to exercise the actual user journey, browsing, adding to cart, checking out, since that's what touches the database, the payment integration, and whatever else sits behind the page that looks simple from the browser.
A Basic Example
Tools like k6, Gatling, and Locust all handle the same core job, scripting a user journey and running it at scale. A simple k6 script for a checkout flow:
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 1000 },
{ duration: '5m', target: 10000 },
{ duration: '3m', target: 10000 },
{ duration: '2m', target: 0 },
],
};
export default function () {
const res = http.post('https://example.com/api/checkout', JSON.stringify({
productId: 42,
quantity: 1,
}));
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}The staged ramp, 1,000 users over two minutes, up to 10,000 over the next five, held there for three, then ramped back down, mirrors a realistic traffic spike rather than an instant jump, and the results report latency percentiles and error rates at each stage, which is usually where the actual breaking point becomes visible.
Reading the Results Honestly
The average response time is close to useless on its own. A system with a 200ms average response time can still be failing badly for a meaningful fraction of users if the distribution is skewed, p95 and p99 latency (the response time for the slowest 5% and 1% of requests) usually tell the real story, since those are the users actually experiencing the problem while the average looks fine.
A load test result is also only as good as how closely it matches real traffic patterns. A test that hits one endpoint with uniform, predictable requests tells you less than one that mimics an actual user journey with realistic think-time between actions, since real bottlenecks often show up specifically in the interaction between multiple parts of a flow, not in any single request viewed alone.
Frequently asked questions
Final Thoughts
A checkout page that loads in 1.2 seconds for one visitor and a checkout page that survives ten thousand simultaneous visitors are two different claims, and only one of them gets tested by default in most teams' existing test suites. Load testing is how the second claim actually gets verified, not by making the page faster, but by finding out where the whole system, database, API limits, connection pools included, actually starts to bend before it breaks in production instead.
How FlawPilot helps
FlawPilot finds security and quality issues in your AI-built app and shows you how to fix them. It checks your deployed site across security, performance, infrastructure, and SEO, and scans your source code for vulnerabilities, hardcoded secrets, and vulnerable dependencies.
Every finding is prioritized and explained in plain English, with the actual fix: the configuration change, DNS record, security header, or code change needed. For supported findings, AI-powered guidance adds step-by-step instructions and suggested code fixes.
Connect your Git provider to scan your repository alongside your live site, so application findings, code vulnerabilities, secrets, and dependency issues all land in one place.
It fits your existing workflow too: a REST API for scores and findings, an embeddable security badge, and an MCP server so tools like Claude, Cursor, or ChatGPT can read your findings and help you work through them.
The boundaries are clear: the public website scan reads only publicly accessible signals, with no agent or credentials required, and source-code scanning is opt-in and read-only. Fixes are never applied or merged without your review.
Verify your AI-generated app is production-ready.
117 security checks in 60 seconds - free, no account needed.
Scan one page
Enter a URL - no account, no install.
Run a Site Health check
Requires a free accountCrawls every page we can reach and scores each one, so a slow template deep in the site stops hiding behind a healthy homepage.
Scan your source code
Requires a free accountConnect a Git provider to check for vulnerabilities, secrets, and risky dependencies.
