Loadtest
Runs a load test on the selected URL. Fast and easy to use. Can be integrated in your own workflow using the API.
Install / Use
/learn @alexfernandez/LoadtestREADME
loadtest
Runs a load test on the selected HTTP or WebSockets URL. The API allows for easy integration in your own tests.
Installation
Install globally as root:
# npm install -g loadtest
On Ubuntu or Mac OS X systems install using sudo:
$ sudo npm install -g loadtest
For access to the API just install it in your npm package as a dev dependency:
$ npm install --save-dev loadtest
Compatibility
Versions 6 and later should be used at least with Node.js v16 or later:
- Node.js v16 or later: ^6.0.0
- Node.js v10 or later: ^5.0.0
- Node.js v8 or later: 4.x.y
- Node.js v6 or earlier: ^3.1.0
- ES5 support (no
let,constor arrow functions): ^2.0.0.
Usage
Why use loadtest instead of any other of the available tools, notably Apache ab?
loadtest allows you to configure and tweak requests to simulate real world loads.
Basic Usage
Run as a script to load test a URL:
$ loadtest [-n requests] [-c concurrency] [-k] URL
The URL can be "http://", "https://" or "ws://".
Set the max number of requests with -n, and the desired level of concurrency with the -c parameter.
Use keep-alive connections with -k whenever it makes sense,
which should be always except when you are testing opening and closing connections.
Single-dash parameters (e.g. -n) are designed to be compatible with
Apache ab,
except that here you can add the parameters after the URL.
To get online help, run loadtest without parameters:
$ loadtest
Usage Dos
The set of basic options are designed to be compatible with Apache ab.
But while ab can only set a concurrency level and lets the server adjust to it,
loadtest allows you to set a rate or requests per second with the --rps option.
Example:
loadtest -c 10 --rps 200 http://mysite.com/
This command sends exactly 200 requests per second with concurrency 10,
so you can see how your server copes with sustained rps.
Even if ab reported a rate of 200 rps,
you will be surprised to see how a constant rate of requests per second affects performance:
no longer are the requests adjusted to the server, but the server must adjust to the requests!
Rps rates are usually lowered dramatically, at least 20~25% (in our example from 200 to 150 rps),
but the resulting figure is much more robust.
loadtest is also quite extensible.
Using the provided API it is very easy to integrate loadtest with your package, and run programmatic load tests.
loadtest makes it very easy to run load tests as part of systems tests, before deploying a new version of your software.
The result includes mean response times and percentiles,
so that you can abort deployment e.g. if 99% of all requests don't finish in 10 ms or less.
Usage Don'ts
loadtest performance has improved significantly,
but it is still limited.
loadtest saturates a single CPU pretty quickly,
so it uses half the available cores in your processor.
The Node.js processes can reach 100% usage in top,
which happens approx. when your load is above 4000~7000 rps per core.
In this case please adjust the number of cores.
So for instance with eight cores you can expect to get a maximum performance of
8 * 5000 = 40 krps.
You can measure the practical limits of loadtest on your specific test machines by running it against a simple
test server
and seeing when it reaches 100% CPU. Run the following commands on two different consoles:
$ node bin/testserver.js
$ node bin/loadtest.js -n 1000000 -c 100 http://localhost:7357/
If you have reached the limits of loadtest even after using all cores,
there are other tools that you can try.
- AutoCannon: also an
npmpackage, awesome tool with an interface similar towrk. - Apache
abhas great performance, but it is limited by a single CPU performance. Its practical limit is somewhere around ~40 krps. - weighttp is also
ab-compatible and is supposed to be very fast (the author has not personally used it). - wrk is multithreaded and highly performance.
It may need installing from source though, and its interface is not
ab-compatible. - wrk2: evolution of
wrk.
Regular Usage
The following parameters are compatible with Apache ab.
-t, --maxSeconds
Max number of seconds to wait until requests no longer go out.
Default is 10 seconds, applies only if no --maxRequests is specified.
Note: this is different than Apache ab, which stops receiving requests after the given seconds.
Warning: max seconds used to have no default value,
so tests would run indefinitely if no --maxSeconds and no --maxRequests were specified.
Max seconds was changed to default to 10 in version 8.
-n, --maxRequests
Number of requests to send out.
Default is no limit;
will keep on sending until the time limit in --maxSeconds is reached.
Note: the total number of requests sent can be bigger than the parameter if there is a concurrency parameter;
loadtest will report just the first n.
-c, --concurrency
loadtest will create a certain number of clients; this parameter controls how many. Requests from them will arrive concurrently to the server. Default value is 10.
Note: requests are not sent in parallel (from different processes),
but concurrently (a second request may be sent before the first has been answered).
Does not apply if --requestsPerSecond is specified.
Beware: if concurrency is too low then it is possible that there will not be enough clients
to send all the supported traffic,
adjust it with -c if needed.
Warning: concurrency used to have a default value of 1, until it was changed to 10 in version 8.
-k, --keepalive
Open connections using keep-alive:
use header Connection: keep-alive instead of Connection: close.
Note: Uses agentkeepalive, which performs better than the default node.js agent.
-C, --cookie cookie-name=value
Send a cookie with the request. The cookie name=value is then sent to the server.
This parameter can be repeated as many times as needed.
-H, --header header:value
Send a custom header with the request. The line header:value is then sent to the server.
This parameter can be repeated as many times as needed.
Example:
$ loadtest -H user-agent:tester/0.4 ...
Note: if not present, loadtest will add a few headers on its own: the "host" header parsed from the URL,
a custom user agent "loadtest/" plus version (loadtest/1.1.0), and an accept header for "*/*".
Note: when the same header is sent several times, only the last value will be considered. If you want to send multiple values with a header, separate them with semicolons:
$ loadtest -H accept:text/plain;text-html ...
Note: if you need to add a header with spaces, be sure to surround both header and value with quotes:
$ loadtest -H "Authorization: Basic xxx=="
-T, --contentType
Set the MIME content type for POST data. Default: text/plain.
-P, --postBody
Send the string as the POST body. E.g.: -P '{"key": "a9acf03f"}'
-A, --patchBody
Send the string as the PATCH body. E.g.: -A '{"key": "a9acf03f"}'
-m, --method
Set method that will be sent to the test URL.
Accepts: GET, POST, PUT, DELETE, PATCH,
and lowercase versions. Default is GET.
Example: -m POST.
--data body
Add some data to send in the body. It does not support method GET.
Requires setting the method with -m and the type with -T.
Example: --data '{"username": "test", "password": "test"}' -T 'application/x-www-form-urlencoded' -m POST
-p, --postFile
Send the data contained in the given file in the POST body.
Remember to set -T to the correct content-type.
If POST-file has .js extension it will be imported. It should be a valid node module and it
should export a default function, which is invoked with an automatically generated request identifier
to provide the body of each request.
This is useful if you want to generate request bodies dynamically and vary them for each request.
Example:
export default function request(requestId) {
// this object will be serialized to JSON and sent in the body of the request
return {
key: 'value',
requestId: requestId
}
}
See sample file in sample/post-file.js, and test in test/body-generator.js.
-u, --putFile
Send the data contained in the given file as a PUT request.
Remember to set -T to the correct content-type.
If PUT-file has .js extension it will be imported. It should be a valid node module and it
should export a default function, which is invoked with an automatically generated request identifier
to provide the body of each request.
This is useful if you want to generate request bodies dynamically and vary them for each request.
For examples see above for -p.
-a, --patchFile
Send the data contained in the given file as a PATCH request.
Remember to set -T to the correct content-type.
If PATCH-file has .js extension it will be imported. It should be a valid node module and it
should export a default function, which is invoked with an automatically generated request identifier
to provide the body of each request.
This is useful if you want to generate request bodies dynamically and vary them for each request.
For examples see above for -p.


