# How to Load Test a Website: A Step-by-Step Guide

> How to load test a website, step by step: plan your traffic, build realistic test scripts, run the load test, and read the results with confidence.

Source: https://loadster.com/guides/website-load-testing/

## Introduction

We've all seen websites crash under a flood of traffic. Site crashes are notorious around marketing events like Black
Friday and the Super Bowl, but they can strike year-round and for a variety of reasons, whenever an overloaded site
can't handle all the requests coming in.

When *your* site crashes under heavy traffic, it's stressful for you and costly to your business. Customers turned away
by the outage might never return. Even if your site stays alive but loads slowly or incompletely, the broken and
sluggish experience will deter many users. People have short attention spans, and it only takes a few seconds to hit the
back button and find an alternative.

The danger of site crashes is amplified by the fact that *they always happen at the worst possible time*, like during a
launch or a big marketing campaign. Any website downtime is a problem, but when a site crashes under peak load it
impacts the most users.

If your site is important enough that crashing under peak traffic is possible, it's worth taking some steps to reduce
your risk of downtime. Otherwise you'll find yourself scrambling to bring your site back online after it gets slammed.

This guide walks through how to load test a website in six steps: choosing a tool, gathering your requirements,
creating scripts and scenarios, running the tests, analyzing the results, and improving your site's scalability based
on what you find.

## Preparing Your Site For Heavy Traffic

Predicting how many users your site can handle is difficult to impossible. A normally fast site can suddenly become slow
and broken once a certain number of users visit concurrently. So how can you determine the breaking point?

It's not enough to simply test how fast your website loads. Of course, you could test a single page load with tools like
WebPageTest, Google Lighthouse, or our own [free website speed test](https://loadster.com/tools/website-speed-test/), but that will only
measure your site's performance at baseline, when a few people are using it. Site speed tools are useful, but they don't
tell you how your site will perform when many people are hitting it at once. In other words, they tell you a lot about
your site's baseline performance, but very little about how well it can maintain this performance under heavy load.

To prepare for peak traffic, you'll need to measure your site's *scalability*. Scalability means its ability to deliver
acceptable performance to many users at once. To measure this, you'll actually need to test it with heavy traffic.

It would be impractical to recruit an army of human testers to all load your site at once to generate peak traffic
conditions. Instead, you can use tools to simulate thousands of users interacting with your site the same way real users
do.

The technique of simulating thousands of users on your site is called *[load testing](https://loadster.com/guides/load-testing/)*
(or *[stress testing](https://loadster.com/guides/web-application-stress-testing/)*), and *load testing tools* exist for this very purpose.

## When Is Load Testing Your Site Worthwhile?

For important websites, even a brief period of downtime under peak traffic could cost vast amounts in lost business and
reputation. Load testing can predict and prevent such crashes, so load testing an important site to prepare ahead of
time is a smart investment. Of course, for smaller or non-critical sites, it might not be necessary.

By load testing your site with simulated peak traffic ahead of time, you'll get a clear picture of how it will respond
to real traffic when the time comes.

If your site crashes during the load test, it would almost certainly crash in real life under similar conditions.

But don't worry! A site crashing during a load test is actually a good thing. It gives you advance notice of your site's
limitations and potential scalability bottlenecks, so you can address the limitations and fix any problems *before* they
impact your real customers.

Load testing your site and tuning it to address any deficiencies will prepare it for heavy traffic. It takes a little
effort, but you'll gain the confidence and peace of mind that your site will perform well even in extreme traffic
conditions.

## Step 1: Choose a Load Testing Tool

The results from a load test are only useful if the test is a *realistic simulation* of your peak traffic conditions,
and only insofar as the test results are measured and reported accurately.

Everyone's tradeoffs in selecting a tool are a bit different, but here are a few things to consider so you get the best
outcome from your load testing.

### Simulating Realistic User Traffic

A load test needs to be realistic enough that from your website's point of view it is *just like thousands of real
users* are actually hitting the site. In an ideal load test, your site and servers shouldn't even know the difference
between the load test traffic and real traffic.

If your site is a trivial one-page static website, generating realistic traffic might be pretty easy. You can just load
the home page over and over with many distributed bots (virtual users), and each page load impacts the server the same
as a real site visit.

On the other hand, if your site is large and complex with many dynamic features (like a shopping cart, search bar, login
and registration, account management, order processing, etc), then load testing is trickier but even more critical.
Dynamic websites have more moving parts, including backend application servers and databases, so there are more
potential scalability bottlenecks that could cause a crash under heavy load.

### Load Testing with Real Browsers

Some load testing tools generate load at the protocol layer (automating a bunch of painstakingly scripted HTTP
requests), while a few of the newer tools including Loadster can test with real web browsers (headless Chrome or Firefox
web browsers).

Load testing at the protocol layer is suitable for HTTP APIs and even simple websites, but it can be challenging for
complex websites and web applications that use client-side JavaScript or WebSockets or convoluted authentication flows.

Load testing with real browsers is the easiest and most realistic way to load test complex websites, even though real
browsers are heavier and typically cost more than just firing off a bunch of HTTP requests. Real browsers do more of the
work for you.

### Measuring Response Times Under Load

Beyond simply generating load on your site, a load testing tool should also measure the site's response times so you can
see in real time if your site is running fast, bogging down, or altogether broken.

It helps to have a load testing tool that reports separate response times for each individual page or feature on your
site, instead of just lumping the response times of all pages together into one big average. Outliers can easily be
hidden in an average or aggregate.

It's common in a load test for part of a site to perform normally, while another part of the site is broken. For
example, a shopping site might as well be down if the home page loads but customers can't add items to their cart or
check out. It's always a good idea to measure each page or action separately in your load test, so you can identify
which parts are failing and don't miss anything.

### Handling Errors in a Load Test

If you load test any site with enough traffic, errors will result. The nature of these errors can tell you a lot about
what is broken in the site and help you identify the *bottleneck*, or the slowest part of the system that is grinding
everything else to a halt.

For example, socket timeouts or connection timeouts usually mean the network or the servers are saturated and can't
respond to incoming requests. The client waits for a certain amount of time and then times out.

Similarly, an HTTP 502, 503, or 504 error usually means that the server or load balancer is still answering requests,
but is unable to service them because its backends are down or broken or overloaded. An HTTP 401, 403, or 404 error
often means something is wrong in your load testing setup, like it might be using an invalid user login or trying to hit
a page that no longer exists.

Other load test errors manifest more like functional errors but might still be load-related. Some dynamic sites return
HTTP 200 OK responses, but the resulting web page is missing a section or has human-readable error messages displayed on
it. This type of error is harder to test for because tools don't interpret it automatically.

Some load testing tools allow you to add custom validation or assertions to your test script to evaluate the response
content or body, to help you catch these sneaky on-page errors. For example, right after adding an item to your shopping
cart, your load test script could look at the cart and validate that the item is really in there, throwing an explicit
error if it's not.

Load testing can also produce unforeseen errors that you might not have anticipated or handled in your script. It might
not be clear at first what the problem is, so it helps to have a tool that captures as much detail as possible. This
includes screenshots (if you're testing with real browsers) as well as detailed error logs, request and response traces,
the URL and method that generated the error, and overall context of where the bot was in the test script when the error
happened.

Chasing down errors from a load test is one area where powerful tools can save you a lot of time.

### Reporting and Sharing Test Results

A load test's outcome is only as valid as the assumptions that went into it. These assumptions include what exact user
behavior patterns you are testing, the number of concurrent users or total user visits simulated, the cadence in which
the users arrive, and what kinds of response times and page load times and error rates are acceptable.

Afterwards, when your team and stakeholders ask how the load tests went, try to share as much information and nuance as
possible. You wouldn't simply want to reassure them that the site passed the load test... only to have it fail later in
a real-life traffic spike.

To avoid instilling a false sense of confidence, or worse yet, getting blamed when things go sideways, you should always
share load test results with *as much detail as possible* about the test outcome. Along with the detailed test results
should be *clearly documented assumptions* that informed the behavior and load patterns that you tested.

In fact, all you can really safely say after a successful load test is that *given this specific set of assumptions
about user behavior and concurrency*, the site met (or did not meet) your performance and scalability requirements.

Load testing tools vary widely in the scope and quality of automatically generated reports. Some tools generate reports
with lots of interactive graphs and charts, while others take the view that the tester should process the data manually
or store it into a time series database for further analysis.

### Your Testing Budget (Time and Money)

All load testing projects are limited by some combination of time and money. Sometimes time is the scarcer resource.

Your time budget might be explicit if you're facing a deadline, or it may be flexible if your company just wants to get
useful results sooner or later. In either case, few of us want to make it our life's work to fiddle around with load
testing tools and frameworks. For a balanced perspective on this, see [Weighing the Costs of Load Testing](https://loadster.com/guides/weighing-the-costs-of-load-testing/).

Of course, it's possible to run load tests for no more than the cost of the cloud instances and bandwidth. There are
several free and open source tools that are highly flexible. That said, if you have budget to spend on load testing
tools that do more of the chores for you, you'll likely get to a successful outcome in less time.

Shortening the testing feedback loop is crucial because load testing websites is an iterative process. You'll need to
run a round of load tests, analyze and interpret the results to determine the bottleneck, make changes to your site
based on your findings, and load test again. You might need to repeat your tests many times in quick succession, so if
your tool can eliminate chores between iterations it can greatly accelerate the process.

## Step 2: Gather Your Load Testing Requirements

Sometimes it's okay to run load tests without a specific requirement, just to explore how your website responds to
increased load. Exploratory load testing can be a helpful way to approximate the "breaking point" at which your site can
no longer take additional traffic.

But in most cases you'll be load testing in preparation for a high traffic event, so it helps for you and your
colleagues to be on the same page about what the load test should simulate, how much traffic it needs to generate, and
what response times and error rate are acceptable.

### Assumptions About Website Visitor Behavior

For the load test to be realistic, the steps your bots take through the site should accurately mimic the behavior of
real users.

Obviously, a load test that only hits the home page will not test the impact of users adding items to their carts and
completing orders. A load test that just hammers a single URL over and over won't be equivalent to a test that loads the
full page with all internal and 3rd party page resources. A load test that simulates anonymous users won't have the same
impact on your servers as a load test where every bot is logged in as a different user.

Load testing requirements aren't complete unless they describe the *specific user behaviors* to be simulated in the load
test. Make sure your assumptions about real user behavior are documented and well-represented by your tests.

### Site Analytics Data (Visitors, Visits, and Concurrent Users)

You probably have some kind of website analytics or logging in place already, so you know how much traffic your site
experiences day-to-day. With these analytics tools you can look back at historical usage and find your busiest day or
even your busiest hour to date. Perhaps you can hazard a guess at future usage trends based on past usage.

If at all possible, your analytics data should inform your load testing requirements, but it's not always
straightforward. You'll need to convert the site visitor rates into "concurrent bots" or "virtual users" or "peak users"
which are the terms that most load testing tools use.

You might need to work backwards to figure out the number of concurrent users your tool will need to simulate. For
example, if your test script simulating a site visit takes 3 minutes (1/20th of an hour) and you know from your
analytics that the site had 5000 visits per hour, your load testing tool will need to run approximately 250 bots (
virtual users), each executing your script over and over, to achieve a rate of 5000 iterations per hour.

When you're interpreting your site analytics data, keep in mind that the rate of site visits is probably not constant!
Just because there were 5000 unique site visits in an hour doesn't mean there were 83 visits every minute. Rather, it's
much more likely there were peaks and valleys throughout the hour, and your site took much more traffic at the busier
minutes than at the quieter minutes. If your analytics tools can only tell you visitor data in hourly or daily
resolution, make sure to pad your site traffic assumptions to allow for fluctuations.

Whatever load testing requirements you derive from your visitor data, make sure to share them widely with your team and
stakeholders! If you work with a product manager or a client, *get them to provide the final sign-off* on whatever
traffic requirements you are plan to load test. Otherwise, you as the tester risk your assumptions being wrong if the
site later crashes in production. Even if you work in a friendly and blame-free organization, your colleagues might have
valuable insights about site usage that can help inform your requirements.

### Performance & Error Rate Acceptance Criteria

What page load times and response times are deemed acceptable for *your* site? This varies depending on your business,
your users, and what they are trying to accomplish.

It's during a customer's first contact with your site or brand that they are especially sensitive to slowness and
errors. If site visitors are browsing for a new product or service and your site is slow or broken, they'll simply move
on.

If you have a more captive audience, like SaaS customers who are already paying for your service, you may have a little
more leeway around temporary slowness... however, this type of customer rightfully has high expectations of your service
since they are paying for it, and you could lose them if you don't deliver a good experience.

When you begin load testing, it's helpful to consider what level of performance is acceptable for your site under peak
load. Include this threshold in your load testing requirements. Here are a few examples of how a performance requirement
might be phrased:

- The average response time must not exceed 750ms
- The 95th percentile page load time (p95) must not exceed 2.5 seconds
- The Shopping Cart must load fully in a median (p50) load time of 1.0 seconds
- Final checkout submission should never take more than 5.0 seconds

Similarly, think about what types of errors are acceptable (if any) and what error rate is acceptable under peak load.
Here are a few examples of how that requirement could be phrased:

* The overall request error rate must be less than 0.1%
* There should be no socket timeouts or connection timeouts
* No errors are acceptable

If in doubt, treat all errors as a requirements failure and aim for an error-free load test.

The key to writing load test acceptance criteria is that it should address the things that really matter (performance
and stability), and that all acceptance criteria should be testable with a pass/fail outcome.

### Website Load Testing Requirements Checklist

To recap what we've covered on load testing requirements, here is a short checklist you can use to make sure your
requirements are thorough and testable.

<ul class="checklist">
  <li>My requirements describe the specific user behavior(s) to be tested in a way that my team members and I can clearly understand.</li>
  <li>If multiple user behaviors are to be tested simultaneously, the requirements say what percentage of users are doing each behavior.</li>
  <li>My calculation of how many concurrent bots (or virtual users) are needed is correlated to transaction throughput, visitor throughput, site visits in a period, or some other relevant throughput metric.</li>
  <li>Requirements include acceptable performance thresholds under peak load, in terms of response times (as an average, median, percentile, or other aggregate).</li>
  <li>My requirements specify what error rate, if any, is acceptable under peak load.</li>
  <li>All the thresholds and criteria are testable with pass/fail outcomes.</li>
  <li>I've shared the load testing approach and acceptance criteria with colleagues, stakeholders, clients, etc.</li>
</ul>

As a tester, being explicit about these requirements and sharing them with your colleagues is a good way to make sure
you are testing the right things in a methodical manner.

Sharing requirements is also (for lack of a better term) a good way to "cover your ass" so you aren't blamed if the site
crashes in production because you tested the wrong requirements.

## Step 3: Create Load Test Scripts and Scenarios

Different load testing tools use different terminology for key concepts, but they are mostly analogous.

In this guide, we'll use the word *script* to describe the steps an individual bot (or virtual user) takes when
interacting with your site. We'll use the term *scenario* to describe the recipe for assembling groups of bots into a
load test.

### Load Test Scripts

Scripts are executed by a bot (or virtual user) to generate test traffic against your site. Typically, a script should
mimic the steps that a real user would take.

Before you even create your load test scripts, you might want to scribble down what steps matter for testing *your*
site. For simple websites, there might just be a single thing that all users do. For more complicated sites and web
applications, there could be multiple important user flows, each deserving of its own script.

Here are some examples of user steps for different types of sites.

* Home page -> exit
* Home page -> submit contact form -> exit
* Home page -> click login button -> fill out login form -> view dashboard -> click open order -> track order -> log
  out -> exit
* Home page -> search for a product -> view search results -> click a search result -> add to cart -> view cart ->
  checkout -> confirmation page -> exit

Of course, the above are just human readable steps and not yet any kind of executable script, but they are in a concise
format for sharing with human stakeholders to make sure you're on the same page.

When it comes to creating the actual executable script, every load testing tool is different. Some tools like Loadster
have a browser extension that can record you stepping through your website in a new browser tab and turn that into a
recorded script. Other tools use various programming languages or YAML files for manual scripting.

Once you have an executable script, run it with a single user or a small batch of users to make sure it works reliably
before starting a load test. This is a quick way to work out bugs in your script itself without the time and expense of
running a bigger load test.

### Load Test Scenarios

A load test scenario is kind of like a test plan. It tells how many groups of bots (virtual users) should run in the
load test, how long they should run for, what script each bot group should be executing, and so on.

When you create your load test scenario, it should be based on the load testing requirements you are trying to test.

Take into account the intended user behavior when deciding how many bots should run each script. For example, if you're
load testing a big e-commerce site, you might want 70% of users to be just browsing, 10% adding items to their cart and
abandoning it, 10% adding items to their cart and completing checkout, 5% searching for a specific item using the search
bar, and 5% managing their account and viewing order status. In a load test scenario, each of these behaviors can be
tested simultaneously by appropriately-sized groups of bots. Of course, for simpler sites you might only need a single
group of bots all doing the same thing.

Think about the script duration and whether it correctly mimics a real site visit. For example, if your average site
visitor takes 6 minutes, add wait times between the steps in your script so a bot takes about 6 minutes to do the same
thing.

Using realistic wait times in your script creates a more accurate simulation, and also makes it easier to achieve the
right cadence and throughput in your load test. Based on the duration of your script you can calculate how many bots you
need to produce the right number of visits (script iterations) in a period.

It usually takes a little trial and error to get the distribution of bots and the cadence just right, so you might need
to run a few smaller tests to check your configuration before scaling up.

### Load Test Datasets

Most load testing tools can pull dynamic data from a *dataset* so that each bot submits different values each time.
Datasets are useful if your site has a login feature, a search field, many different products for sale, etc.

For dynamic sites, making all bots use the same account or search for the same thing or purchase the same product could
result in an inaccurate load test because your site might cache the data. Or it might break the load test altogether
because the bots would all be making changes in the same user account and tripping over each other.

Once you've created a dataset and filled it with whatever dynamic values you need (like a set of usernames and
passwords, for example), you can bind it to your load test script and reference the values with variables. Of course,
different tools have different approaches for mapping the dataset to the script, but the concepts are broadly similar.

## Step 4: Run Load Tests on Your Site

As soon as you have a working load test script, it's tempting to run a load test with the maximum amount of load at
once. You could do it this way, but often it's better to start smaller and work your way up.

Running short preliminary load tests helps you confirm whether your scripts and scenarios are working before you incur
the costs of running a bigger test. The preliminary tests might also reveal problems with your site that you can fix
before going for the big one.

When you're ready to run a longer test, it's often a good idea to ramp up the bots gradually. A linear ramp from zero to
maximum bots over 10 minutes or longer can often tell you at what point your site starts having problems. If you just go
for the maximum load immediately, without a gradual ramp up, the site might either pass or fail but you won't know the
breaking point.

After preliminary tests have validated your test scripts and configuration, and you have a decent notion that your site
will handle the load, you can go ahead and run a full-scale load test to validate your acceptance criteria.

## Step 5: Analyze Your Load Test Results

When you run a test, the load testing tool will typically show you performance metrics in real time or close to real
time. These metrics include things like:

### Response Times

Aggregated response times (average, maximum, minimum, p50, p95, etc) tell you how fast your site is responding to the
load testing tool. Since your load test acceptance criteria has to do with response times, this is an important section.

If the load testing tool is reporting fast response times at the average and 95th percentile, in the absence of errors,
it's likely that your site is handling the load pretty well. If response times get unacceptably high, the site is
probably overloaded and needs changes before it can handle the amount of traffic the tool is generating.

### Errors

A good load testing tool will surface any errors it detects while running the test. These can include errors from
different layers, such as:

* Socket errors from TCP, like socket timeouts, connection timeouts, connection resets, etc.
* HTTP error status codes such as 403, 500, 503, etc.
* Script errors like if the bot couldn't find the next element that it was supposed to click on.
* Validation errors, which might require special effort on your part to enable but are often worth doing (like making
  sure the word "Success" appears on the order confirmation page, and so on).
* Internal errors from the load testing tool itself, which normally shouldn't happen but are certainly worth
  investigating if they do.

Watch the error count and error breakdown closely while a load test is running so you can stop the test if it's failing
badly.

### Throughput

The concept of throughput in a load test can refer to quite a few different things, like iteration throughput,
transaction throughput, or network throughput.

If your load testing tool reports on *Iterations* you can watch this number so you know how many times a bot has
executed your script from start to finish. The number of iterations in a load test is equivalent to the number of
distinct visits or user journeys on your website. If you have a requirement to simulate a certain number of visits in a
time period, watch the *Iterations* count in your load test to make sure it's simulating the right number of visits.

At the transaction level, you can watch the number of requests (*Hits*) or page views (*Pages*) to get a more precise
count of interactions with your site. These metrics are easy to correlate with your website analytics tool so you can
compare the load test with real world usage patterns.

At the network level, many tools will tell you how many bytes have been transferred (upload and download) and a rolling
average of bytes per second or bits per second, so you can tell how busy the network is and whether it might get
saturated under heavy load.

### Graphs

Not all load testing tools produce graphs, but if you're lucky enough to be using one that does, you can use these to
view how the metrics changed at specific times throughout the test.

For example, you could use a *Response Times* graph to see your site's average response time (possibly broken down by
unique URL) as the test progressed, so as to tell if the site became slower under sustained load.

You might also want to correlate multiple graphs so you can see the relationship between different metrics. For example,
you could overlay the *Running Bots* graph with the *Response Times* and *Errors* graphs to see how the response times
and error rate increased as more bots ramped up.

Graphs can also be a great way to notice spikes or anomalies that happened during the test that might be hidden in an
overall average or aggregate.

### Evaluating Load Test Acceptance Criteria

After a load test finishes, you can review the test report to see if the results met the acceptance criteria you were
testing for.

First of all, examine whether whether the load test simulated the right amount of load on your site, by counting the
total number of iterations for each script or bot group. If it's lower than planned, it means the site wasn't tested
with the intended amount of throughput. If it's higher than planned, maybe your load test pushed the site a little too
hard. Don't be surprised if you have to run a few tests and apply a little trial and error to dial in the throughput.

Compare the response time aggregates (average, maximum, minimum, p50, p95, etc) with those in your requirements. If your
requirements were stated in a testable manner, it should be easier to say with certainty whether the metrics from the
load test pass or fail the acceptance criteria.

Similarly, you can review the breakdown of errors (if any) from your load test and cross-check that with your acceptance
criteria.

If your load test acceptance criteria was clearly stated, you should be able to arrive at one of the three outcomes
after each load test:

1. **RETRY** - Didn't test the requirements (too few bots, too many bots, wrong traffic mix, broken scripts, etc)
2. **FAIL** - Accurately tested the requirements and the site failed (too slow, too many errors)
3. **PASS** - Accurately tested the requirements and the site passed (fast and error-free)

Again, load testing websites is an iterative process, so don't get too frustrated with any particular outcome. It
sometimes takes a few tests to get everything right.

## Step 6: Improve Your Website's Scalability

If your load testing determines that the site falls short of the performance and scalability requirements, what next?
Usually it depends on where the bottleneck is in the first place.

### Frontend Performance Tuning

Even though website scalability bottlenecks occur on the server, it's a good idea to reduce the load by optimizing
frontend performance as much as possible. Fewer and smaller requests to your servers mean less load on the server.
For a deeper look at where to focus your optimization efforts, read our guide on [front-end vs. back-end performance](https://loadster.com/guides/front-end-vs-back-end-performance/).

First, see if you can eliminate unnecessary dependencies from your site altogether. If you're loading a JavaScript
library that is no longer needed in modern browsers, maybe you can drop it altogether. If your CSS is bloated, consider
slimming it down. If your site has superfluous images that do nothing for the end user, remove them or reduce their
size.

Second, make sure your site sets appropriate cache headers. If a piece of content or a media file rarely changes, allow
the browser to cache it so it doesn't result in too many requests to your servers. These little requests can really add
up when they're repeated unnecessarily on every page load.

Third, see if you can offload cacheable resources (images, JS, CSS, etc) to a CDN or a caching reverse proxy or WAF, so
your servers don't work as hard to serve them. This will only help if you've already set appropriate cache headers to
indicate what is cacheable.

Of course, when it comes to eliminating backend bottlenecks, frontend performance tuning only goes so far... but it does
help to improve the baseline user experience while also lessening the incremental load on your servers from each
concurrent user.

### Backend Performance Tuning

Scalability bottlenecks can occur at any point in the system, by limiting throughput. Bottlenecks have a non-linear
impact on your site's performance: it might be fast and efficient up to a certain amount of load, and then slow to a
crawl once the bottleneck becomes saturated.

Hard bottlenecks are things like the CPU, memory, disk, and network. These are physical (or virtual) limitations on the
underlying machinery that powers your site. All sites are served by a finite amount of hardware, even if it's buried
under layers of abstraction, and when these finite limits are reached a site can no longer service additional load.

Soft bottlenecks are things like database connection pools, TCP connections, server threads or workers, process heap
memory, queues, asynchronous background workers, and so on. They are implemented in software but nonetheless they
restrict your site's ability to handle additional requests beyond a certain rate. The nature of these soft bottlenecks
depends on your stack and the design of your site. A simple web server serving static files has at least a few potential
soft bottlenecks, while a complicated web application might have hundreds.

Backend performance tuning is easier if you have some kind of application performance monitoring tool, so you don't have
to guess at what your site's scalability bottleneck might be. Observing an APM tool while your load tests run can help
you pinpoint the bottleneck faster and more accurately than guessing through trial and error. Of course, hard limits
like CPU and memory are easy to monitor at the OS level with tools like `top` for Unix/Linux or `perfmon` for Windows or
other built-in tools for other platforms, but for soft limits it helps to have an APM tool or custom instrumentation
that fits with your technology stack and application.

When you're tuning a website or web application for the first time, the bottleneck is more likely due to a soft limit (
configuration) than a hard limit (physical resources).

An initial goal of backend performance tuning should be to *remove all soft bottlenecks until a hard bottleneck is
reached*. Once the load test maxes out hardware resources like CPU, and your software is working efficiently, you can
think about scaling the environment. Our [quick and dirty performance tuning](https://loadster.com/guides/quick-and-dirty-performance-tuning/) guide walks through this iterative process.

### Scaling Vertically and Scaling Horizontally

Scaling a hosting environment typically means bigger servers or more servers, or some combination of the two. Replacing
the servers with bigger ones with more resources is called *scaling vertically* or scaling up, and adding more servers
to help share the load is called *scaling horizontally* or scaling out.

Should you scale up or scale out? It depends.

#### Scaling Up Vertically

Scaling up is usually simpler than scaling out, if you can get away with it. To scale up you just move to a bigger
version of the same server with more resources.

For example, if you're running on AWS EC2 and hit a CPU bottleneck, you could just move from a `c5.large` to
a `c5.xlarge` to double your CPU. This is a straightforward way to address a CPU bottleneck.

Beware of assuming you can always double your CPU and it will double your throughput! Even if CPU was the initial
bottleneck, there might be another bottleneck (hard or soft) lurking right behind it. For example, you might double the
available CPU but only achieve a 10% increase in throughput, because you then start maxing out your database connections
with just a little more load.

You should always load test again after scaling up an environment to make sure the upgrade resolved the bottleneck (and
discover the next bottleneck).

#### Scaling Out Horizontally

Scaling out works well with most websites and many web applications, but it is more complicated than scaling up because
now you need a way to distribute the load between multiple servers.

If you have two or more servers, you'll need a *load balancer* to route incoming requests to one of the servers. For
serving a static site, the load balancer doesn't need to be very sophisticated, because it can forward any request to
any server and it will get handled. But for web applications that store some kind of user state on the server, the load
balancer will need to be aware which user each request belongs to and send it to a server instance that knows about that
user.

In general, try to design your web applications so that the requests are stateless so it doesn't matter which server
they get sent to. This will make scaling out easier.

Although horizontal scaling is more complicated than vertical scaling, it can also add redundancy if done right because
now you have multiple server instances available to service requests.

The big cloud platforms offer virtual load balancers and autoscaling features that make scaling out much more
approachable than it used to be.

## Get Started With Load Testing

Load testing a website is an iterative process that requires load testing tools to simulate the traffic. To recap, if
you're ready to get started...

1. Nail down your load testing goals and your performance and scalability requirements, working closely with your
   colleagues if possible.
2. Select a load testing tool and start scripting, preferably without spending much money until you know if the tool
   will work for you.
3. Run initial exploratory load tests to validate your testing setup, so you know if your scripts and scenarios and
   datasets are working to simulate the right traffic conditions.
4. Run larger load tests to test your performance and scalability requirements.
5. Analyze the results to see if your site passed or failed the load test.
6. If the site failed the load test, make changes to the site and environment and test again.

Hopefully this guide helps you with load testing your website, but the rabbit holes sometimes go deep and we've barely
scratched the surface in some areas! We'd like to hear from you at help@loadster.com if you have any follow-up questions
or ideas how this guide could be better.

---

**Next Steps:** Ready to load test your website? Try [Load Testing with Loadster](https://loadster.com/use-cases/load-testing/).
You can record a script with the browser extension, ramp to peak with thousands of bots, and get your first
test results in minutes.

#### Related Guides

* [Load Testing Best Practices & Pitfalls](https://loadster.com/guides/load-testing-best-practices/) — practical tips and common mistakes to avoid.
* [API Performance Testing](https://loadster.com/guides/api-performance-testing/) — if you also need to load test a REST or GraphQL API.
* [Capacity Planning for Web Apps](https://loadster.com/guides/capacity-planning-for-web-apps/) — plan the right infrastructure for your expected traffic.


## Frequently Asked Questions

### How do you load test a website?

Define your traffic goals, choose a load testing tool, create a script that simulates real user behavior, configure a scenario with a realistic number of concurrent users and a gradual ramp-up, run a small rehearsal test, then run the full test and analyze response times, errors, and throughput.

### How long does a load test take?

The test itself typically runs 30 minutes to a few hours, with a ramp-up, a sustained plateau, and a ramp-down. Plan extra time for scripting and rehearsal: your first load test usually takes a few hours end to end, and repeat runs are much faster.

### Can I run a load test against production?

You can, and mature teams often do, but start carefully: test during a low-traffic window, warn your team, watch error rates closely, and make sure third parties in the request path (payment providers, email services) are stubbed out or rate-limited so you don't disrupt them.

### How many concurrent users should a load test simulate?

Work backwards from your peak traffic. If you expect 5,000 visits per hour and an average visit lasts about 3 minutes, that's roughly 250 concurrent users. Test at your expected peak first, then push higher to find your safety margin.

### Do I need to write code to run a load test?

Not necessarily. Some tools are code-first (k6, Gatling, Locust), while others let you record a browser session or compose scripts in a web-based editor, with code available when you need custom logic. Loadster supports both approaches, including Playwright scripts for real browser tests.



