Frequently Asked Questions
- 1. Basic Terminology
- 2. Hardware Requirements
- 3. Building curl-loader
- 4. Creating Loading Configuration
- 5. What about FTP load and mixed FTP/HTTP load?
6. Running Load
- 6.1. What are the running environment requirements?
- 6.2. How I can run the load?
- 6.3. Which loading modes are supported?
- 6.4. How I can monitor loading progress status?
- 6.5. Why I am getting "Connection time-out after 5108 ms" like errors in the log file?
- 6.6. Where is the detailed log of all virtual clients activities and how to read it?
- 6.7. Which statistics is collected and how to get to it?
- 7. Advanced Issues
1. Basic Terminology
1.1. What is the batch?
Batch is a group of clients (virtual clients emulating real clients) with the same characteristics and loading behavior. Meaning of the word "batch" is also overloaded and is used for a batch configuration file, representing a test plan.
1.2. What is the batch configuration file?
Batch configuration file is a test plan for a batch of clients.
1.3. For which version are these FAQs applicable?
We are keeping these FAQs updated and applicable for the latest version of curl-loader.
1.4. What is the maximum possible number of virtual clients (VCs) with a dedicated IP-address?
You can use the same IP-address for all VCs or a dedicated address for each client. A clear
limitation of "the same IP" is that you can reach only 64K of clients (64K is the number of
ports to bind).
When using a dedicated IP address per client, the address is added by curl-loader to the loading network interface as a secondary IP. Talking 32-bits, linux kernel allocates for IPv4 structure in_ifaddr, which is is ~55-60 bytes (depending on config options, arch, etc) from slab-64, which means, that something above 64 bytes are used. IPv6 address takes a chunk from slab-128 and uses above 128 bytes of kernel memory.
We got at least 100K IPv4 and 8K IPv6 addresses using a machine with 1G memory. The more memory you have, the more you can get, whereas it depends on the number of chunks in slab-64 and slab-128 allocators.
The situation can be worse for 64-bit kernels, whereas such machines are normally enjoying more memory.
2. Hardware Requirements
2.1. What are the minimal HW requirements?
A PC with Pentium-III and 200 MB may be used for loads with hundreds simultaneous loading clients.
2.2. What is the recommended HW configuration?
Note, that each virtual client takes about 30-35 K memory in user-space plus some none-pageable
memory in kernel mainly for send and recv buffers.
Our PC with Pentium-4 2.4 GHz and 480 MB memory is capable to support 3000-4000 simultaneously loading clients. To reach 10K simultaneously loading clients we would recommend a PC with a single 3.2 GHz Intel or 2.2 GHz AMD and 1.5-2 GB of memory.
When loading from a multi-CPU (or multi-core) systems, a loading model with the number of curl-loader threads equal to the number of logical CPUs seen in /proc/cpuinfo (command-line option -t <thread-num>) may be the most effective and deliver very high numbers (20K-50K-100K) of simultaneously loading clients from a single PC. To run a batch in several threads use the command line option -t <number-of-threads>.
If you are thinking, tuning, optimizing and getting our advise, thus, the sky is the limit.
3. Building curl-loader
3.1. Which operating systems are supported by curl-loader?
You can use any operating system of your choice, providing that this is linux with kernel 2.4 or 2.6. We are building, developing and testing on Debian and kernel 2.6 is recommended. If you have any compilation issues on any other linux distributions, please, report them to the mailing list.
3.2. What are the building pre-requirements?
General C development environment with bash, gcc, make, etc on a linux machine
is required. We are supporting gcc of series 3 and 4.
The Building pre-requirements are:
1. glibc include files, which are normally in /usr/include;
2. openssl binaries;
3. openssl development package with include files (on debian libssl-dev);
Adjust Makefile variables to point to the openssl headers and libraries. To specify an openssl development directory with include files (e.g. crypto.h), export environment variable OPENSSLDIR with the value of that directory.
Another known issue is libidn.so, which means, that some linux distributions do have some libidn.so.11, but not libidn.so. Resolve it by creating a softlink or in some cases exclude -lidn from the linking string, which requires commenting a string in Makefile and uncommenting another.
Tarball of curl is included to the current release. When libcurl or curl-loader has building issues, correct them in the Makefile.
3.3. How to make (build) curl-loader?
Run the following commands from your bash linux shell:
$tar zxfv curl-loader-<version>.tar.gz
By default, we are building both libcurl and curl-loader without optimization and with debugging -g option. To build with optimization and without debugging, please, run:
$make optimize=1 debug=0
Y can optionally install the loader by running as a root:
and enjoy our man pages by $man curl-loader and $man curl-loader-config.
A known building issue is libidn.so, which means, that some linux distributions do have some libidn.so.11 or libidn.so.10, but not libidn.so, and it breaks linking. Resolve the issue by creating a softlink:
#cd to the directory, where e.g. libidn.so.11 is installed and run
#ln -s libidn.so.11 libidn.so
If the above was not helpful, try editing the Makefile and removing -lidn from the linking string.
If still any building issues, please, fill you free to contact us for assistance using placed in download tarball PROBLEM-REPORTING form and its instructions.
4. Creating Loading Configuration
4.1. How can I create loading configuration file?
To run a load create your configuration file to be passed to
curl-loader using -f command line option, e.g.
#curl-loader -f ./conf-examples/bulk.conf
For more examples, please, look at the files in "conf-examples" directory. You may copy an example file and edit it by using the next FAQ guidelines.
4.2. What are the loading configuration file tags and semantics?
Configuration file or "batch configuration file" consists from tag=value
strings, grouped into the 2 sections:
Section General contains common for the batch parameters, whereas section URLs has one or more URL subsections each starting with a certain URL and containing more tags.
An example of a simple configuration file to be used for traffic generation client side against e.g. lighttpd web server: ----------------------------------------------------------------------------
########### GENERAL SECTION ##################
########### URLs SECTION #######################
TIMER_URL_COMPLETION = 0
TIMER_AFTER_URL_SLEEP = 0
The name of the batch is "10K-clients" with the maximum number of clients to be 10000; load will be started with initial 100 clients and each seconds will be added 50 more clients.
Network interface eth0 will be used for the load with unique IP-address for each client taken from 192.168.1.1 up to 192.168.53.255 with netmask 255.255.0.0. Number of cycles is to be performed by each client in not limited (CYCLES_NUM= -1) and load will proceed till user presses Cntl-C to stop it. Each client fetches a single url (URLS_NUM= 1) http://localhost/index.html.
The url was given a short name "local-index", and this name will appear at the Load Status GUI. The url will be fetched using HTTP GET request method and the download will not be limited by time (TIMER_URL_COMPLETION = 0). If we would like to limit this operation by time, we could place here some number in milli-seconds, e.g. TIMER_URL_COMPLETION=3000; the timer will be monitored, enforced and reported, if missed, at Load Status GUI and other statistics. By default all missed url-completion timers are considered as errors and added to statistics as T-err. Each client after accomplishing a url, including possible protocol redirections, waits/sleeps for 0 ms (TIMER_AFTER_URL_SLEEP = 0, which means, that actually client does not wait/sleep) and goes to the next URL, if any, to fetch.
Yet a one more example of a configuration file used for login to a web-service, perform some activity and logoff, all in cycles, is presented below:
########### GENERAL SECTION ###################
########### URLs SECTION #######################
### Login URL - cycling
TIMER_URL_COMPLETION = 10000
TIMER_URL_COMPLETION = 4000
### Cycling URL
TIMER_URL_COMPLETION = 3000
### Logoff URL - cycling, uses GET and cookies to logoff.
TIMER_URL_COMPLETION = 0
The name of the batch is "web-service", maximum number of clients 100, load will started with initial 2 clients and each seconds will be added 2 more clients.
Eth0 will be used with the same IP-address for each client 192.168.0.2 with netmask 255.255.255.0 (24 in CIDR notation). If we would like to assign to each client a unique IP, it could be done by providing a range of at least 100 IP-address, e.g. IP_ADDR_MIN=192.168.0.10 and IP_ADDR_MAX=192.168.0.110. Number of cycles is to be performed by each client is limited to 200, and the load stops, when each client accomplishes 200 cycles. A client fetches up to 4 urls, specified in section URLs
The first URL operation, which is doing a simulated user/client, is login. Login is performed by GET-ing the page (with 3xx HTTP redirections handled inside) with the first url http://192.168.0.1:8888/vax/root/Admin, called shortly "Login-GET". Maximum time considered appropriate for this operation is 10000 msecs. The 2000 msec "sleep" timer simulates here the time taken by a user to fill username and password to the POST-form received by the GET.
The second url is empty and is used for POST-ing to the "current" url, using the form. Such empty string urls are allowed only, when URL_USE_CURRENT=1 is specified. The url is named as "Login-POST". Username "admin" and password "admin-passphrase" are used as the single user type and "filled" to the FORM_STRING= username=%s&password=%s. The resulting form, which is sent to the web-service, is "username=admin&password=admin-passphrase". There are other options available for the tag FORM_STRING, such as unique generated users, unique generated passwords or credentials loaded from a file; these options will be described later. The maximum time allowed for this POST operation is 4000 msecs, and the time of waiting/sleeping till the next url is 1000 msecs. Worth to mention, that when the authentication is accomplished successfully, server sets to client cookies and redirects the client to the service page, which is the next url (note, that all redirections are handled internally).
The third url is http://192.168.0.1:8888/vax/Admin/ServiceList.do with a short name "Service List". After the url is fetched a client comes to the forth url http://192.168.0.1:8888/vax/Admin/Logout.do for logoff. This batch (testing plan) does not control and limit time for logoff as indicated by TIMER_URL_COMPLETION = 0. After 1000 msecs sleeping a client comes back to the first url to repeat the sequence till the number of cycles is expired.
If we would like, that login and logoff to be done for each client only once, we would add to the first, second and forth url the tag URL_DONT_CYCLE=1 to mark the urls as not-cycled to be fetched only once.
Note, that both quoted and non-quoted strings are supported as the tags values.
For more examples, please, look at the files in "conf-examples" directory.
4.3. What are the exact meanings of all these tags?
Tags of the sections GENERAL:
BATCH_NAME requires a string value; it is used to name the batch. The name is displayed, while the program is running, and as the base word for the three generated log and statistics filenames.
CLIENTS_NUM_MAX - is the maximum number of clients to be used for this load. Any positive number is valid here. Note, that each loading client requires about 30 K of RAM plus some non-pageable memory in kernel. We have already tried loads with up to 100 K clients. Loads above 1000 client is recommended to start with a some lower starting number, managed by the next tag CLIENTS_NUM_START and ramped-up each second by adding CLIENTS_RAMPUP_INC clients to the loading set.
CLIENTS_NUM_START - is the number of clients to start the load with. If the tag is absent or zero, the value of CLIENTS_RAMPUP_INC will be taken instead. If neither CLIENTS_NUM_START nor CLIENTS_RAMPUP_INC are possessing a valid positive value, the loader takes CLIENTS_NUM_MAX as the number of clients to start with.
CLIENTS_RAMPUP_INC - number of clients to be added to the load in the auto mode every second till CLIENTS_NUM_MAX number will be reached. For machines with a single CPU we would recommend not to keep the number above 50-100, whereas for dual-CPU machines you may try as large as 200-300.
INTERFACE - name of the loading network interface, like eth0. Find the network interface names by running /sbin/ifconfig.
NETMASK - netmask for the loading IP-addresses of virtual clients (from IP_ADDR_MIN to IP_ADDR_MAX). For IPv4 you can use either quad-dotted netmask string or CIDR number from 0-32. For IPv6 only CIDR values from 0 to 128 are supported.
IP-addresses from IP_ADDR_MIN up to IP_ADDR_MAX are the interval of addresses to be used for loading clients. The interval of addresses should be large enough to supply a dedicated IP for each client. Another mode that can be used is "single IP address" for all clients. When IP_ADDR_MIN and IP_ADDR_MAX have the same valid IP-address, it will be used for all clients. If the IP-addresses specified by the tags do not exist, curl-loader adds them as the secondary IPs to the loading network interface.
Remember, that you should ensure smooth routing from the addresses used to server and from server back to the client addresses. Another route to ensure, when is appropriate, is to/from DNS server for resolving. Firewalling (netfilter/iptables) settings are also among those to check.
IP_SHARED_NUM is the positive number of IP-addresses, that will be assigned by the program to its virtual clients evenly. When the number is one, it is equivalent to the single common IP-address, described in the IP_ADDR_MIN tag section. If, for example, IP_SHARED_NUM is 3, the first client gets the first address, second the second, third gets the third IP-address, whereas the forth client gets back the first address and so on. This option enables to overcome the limit of 64K clients per IP without using a dedicated IP-address for each client. Without the tag the program follows the behavior described for tag IP_ADDR_MIN.
CYCLES_NUM is the number of cycles to be performed. Any positive value is valid here as well as (-1), which means cycle indefinitely. Loading can be normally stopped at any moment by pressing Cntl-C; all statistics will be collected properly and files will be closed. Note, that cycling relates only to the URLs without tag URL_DONT_CYCLE = 1. Curl-loader enables two optional non-cycling areas: the first area before the cycling url/s area and the second area after the cycling url/s area.
USER_AGENT provides an option to over-write the default MSIE-6-like HTTP header User-Agent. Place here a quoted string to emulate the browser that you need. The header is entered globally. If you need an option to customize it on a per-URL bases, please, use the tag HEADER="User-Agent: the string of my favorite browser".
URLS_NUM is the number of urls to be used in URLs Section.
Tags of the section URLs:
URL - is the first tag of each url-subsection; it marks the beginning of a new url. The tag should be either a valid url or an empty string, which is allowed only when URL_USE_CURRENT=1. "Current url" is useful, for example, when POST-ing page with a url, resulting from the previous GET. HTTP redirections are handled internally, and there is no need to use "current url" approach for that purpose. Note, that URL used for file uploading should include a filename and not only a directory.
URL_SHORT_NAME - is an optional up to 12 ASCII string long name, which will appear at a Load Status GUI. It improves appearance of the current operational status at the console. We are recommending to configure it.
URL_USE_CURRENT - is used in combination with an empty string URL="" to indicate, that the current url page, fetched by the previous operation, should be used. "Current url" is useful e.g., when POST-ing page of a url, resulting from the previous GET. Note, that HTTP redirections are handled internally, and there is no need to use "current url" approach for that purpose.
URL_DONT_CYCLE - marks a url as non-cycling. Curl-loader enables two optional non-cycling areas: the first area before the cycling url/s area and the second after it. The first non-cycling area may be useful for login, authentication, etc. single time operations, whereas the second non-cycling area may be good for a single time logoff, for example.
REQUEST_TYPE - HTTP request method to be chosen from GET, POST or PUT.
UPLOAD_FILE - a filename, including path, of a file to be used for uploading. The path should be taken from the curl-loader place, e.g. ./conf-examples/bax.conf
HEADER - is assisting to customize/add/over-write HTTP/FTP headers. If a header already exits by default, the custom header over-writes it. USER_AGENT tag is for User-Agent header only, whereas by HEADER may be added or over-written any header, including User-Agent. To prevent from sending "Expect: 100-continue", please, pass HEADER="Expect: "
Look at the example ./conf-examples/custom_hdrs.conf.
USERNAME and PASSWORD are the tags to provide credentials for login operations. The strings may be used either as is or as the base-words to append numbers and to generate some unique credentials. The behavior is governed by the tag FORM_USAGE_TYPE. Note, that PASSWORD may be an empty string.
FORM_USAGE_TYPE governs user login process. "UNIQUE_USERS_AND_PASSWORDS" is used to generate unique usernames and passwords by appending client sequence numbers (starting from 1) to USERNAME and PASSWORD tags within FORM_STRING template. "UNIQUE_USERS_SAME_PASSWORD" to be used when generating unique users with the same password. "SINGLE_USER" is useful, when all clients are making login using the same USERNAME and PASSWORD. "RECORDS_FROM_FILE" means, that user credentials to be loaded from the file specified by FORM_RECORDS_FILE value. "AS_IS" means, that the FORM_STRING template to be used just AS IS and without any usernames or passwords either from the relevant tags or from file.
FORM_STRING is the configurable template form to be used for POST-ing credentials or any other records.
To generate multiple unique users with unique passwords FORM_USAGE_TYPE= "UNIQUE_USERS_AND_PASSWORDS", and the FORM_STRING to be a template like "username=%s%d&password=%s%d". First '%s' will be substituted by the value of USERNAME tag and '%d' by the client number. Second '%s' will be substituted by PASSWORD tag value and second '%d' by the same client number. For example, if USERNAME=robert, PASSWORD=stam and FORM_STRING "username=%s%d&password=%s%d", the final POST string, used for the client number 1, will be "username=robert1&password=stam1".
In this case USERNAME and PASSWORD strings are used just as base-words for generating unique user credentials by appending a client sequence number.
When FORM_USAGE_TYPE="UNIQUE_USERS_SAME_PASSWORD" template of FORM string to be something like "username=%s%d&password=%s", where only username will be unique using the same approach as described above.
When FORM_USAGE_TYPE="SINGLE_USER", provide FORM_STRING without %d symbols, e.g. "user=%s&secret=%s". Thus, all clients will have the same POST credentials with the string looking like "user=robert&secret=stam".
When FORM_USAGE_TYPE= "RECORDS_FROM_FILE" FORM_STRING to be also without %d symbols, because the credentials uniqueness is supposed to be ensured by the file content.
FORM_USAGE_TYPE="AS_IS" means, that FORM_STRING will not be validated and POST-ed indeed AS IS.
FORM_RECORDS_FILE specifies path to the file with credentials or any other tokens. (full-path or relative to curl-loader location). A text file with usernames and passwords with the structure of each string like: <teken1><separator><token2> can be used as an input. According to RFC1738, only reserved ':', '@', '/' and probably ' ' (space) are safe to use as separators between username and password. An example of batch configuration is ./conf-examples/post-form-token-fr-file.conf and an example of credentials is in ./conf-examples/credentials.cred. Current version supports up to 16 tokens in the file.
FORM_RECORDS_FILE_MAX_NUM allows to load from a file with records, specified by tag FORM_RECORDS_FILE, any number of records, and not only the default number of records, which is equal to the maximum number of virtual clients CLIENTS_NUM_MAX. The tag is required by FORM_RECORDS_RANDOM.
FORM_RECORDS_RANDOM allows to use for each virtual client a randomly chosen record, whereas without the tag the program uses for a client with index I always record number I. One can load e.g. 10000 records from a file, specified by FORM_RECORDS_FILE tag, and use the records in a random fashion for e.g. 100 clients. The tag does not ensure uniquickness of the records used for each virtual client. To use the tag properly, please, specify number of the records to be loaded, using tag FORM_RECORDS_FILE_MAX_NUM.
WEB_AUTH_METHOD to be configured from the "BASIC", "DIGEST", "GSS_NEGOTIATE", "NTLM" or "ANY". The configured method will be used for authentication on HTTP 401 response. When "ANY" is configured, libcurl will choose a method. To use "GSS_NEGOTIATE" the libcurl should be re-compiled with support for GSS.
WEB_AUTH_CREDENTIALS to be provided in the form "user:password". If not configured, the loader uses USERNAME and PASSWORD tags value to synthesize the credentials.
PROXY_AUTH_METHOD to be configured from the "BASIC", "DIGEST", "GSS_NEGOTIATE", "NTLM" or "ANY". The configured method will be used for authentication on HTTP 407 response. When "ANY" is configured, libcurl will choose a method. To use "GSS_NEGOTIATE" the libcurl should be re-compiled with support for GSS.
PROXY_AUTH_CREDENTIALS to be provided in the form "user:password". If not configured, the loader uses USERNAME and PASSWORD tags value to synthesize the credentials.
FRESH_CONNECT is used to define on a per url bases, whether the connection should be re-used or closed and re-connected after request-response cycle. When 1, the TCP connection will be re-established. The system default is to keep the connection and re-use it as much as server and protocol allow it. Still the system default could be changed by the command-line option -r.
TIMER_TCP_CONN_SETUP is the time in seconds for DNS resolving and TCP connection setup on a per url bases. The global default is 5 seconds, which can be changed using -c command-line option.
TIMER_URL_COMPLETION is the time in milli-seconds to allow a url fetching operation, including all internal re-directions. The legal values are 0, which means no limit on url-completion time, or above 20 (milli-seconds). When a value of the tag is above 0, we are monitoring the progress of url-fetching and canceling it, if not accompliched within the the specified value of milliseconds. The results are presented at the Load Status GUI as the operation "Timed Out" statistics and logged to all statistics files as T-Err number.
TIMER_AFTER_URL_SLEEP is the time in milli-seconds for client to sleep after fetching a URL prior to dealing with the next URL. Zero (0) means don't wait and schedule client immediately. Random timer values are a legal option to be specified as e.g. 0-2000, which means, that a client will sleep for some random time from 0 to 2000 milliseconds.
FTP_ACTIVE, when defined as 1, is forcing FTP protocol to use an active mode (the default is passive).
LOG_RESP_HEADERS, when defined as 1, the program logs response headers to a file. Directory <batch-name> is created with subdirs url0, url1, url<n> Headers of responses are logged to the files named: cl-<client-num>-cycle-<cycle-num>.hdr
LOG_RESP_BODIES, when defined as 1, the program logs response headers to a file. Directory <batch-name> is created with subdirs url0, url1... url<n> Headers of responses are logged to the files named: cl-<client-num>-cycle-<cycle-num>.body
RESPONSE_STATUS_ERRORS supports changes to the default set of per-url responses considered as errors. By default most 4xx (without 401 and 407) and all 5xx response codes are treated as errors. Now you can either add a status to the errors set or remove it. Sign + (plus) adds, - (minus) removes. The syntax is a line of tokens separated by ',', where each tokens begins with either + or - and is followed by the response status number from 0 up to 600.
For example, the effect of RESPONSE_STATUS_ERRORS="+200,-404" is that 200 responses will be considered for that url as errors, whereas 404 will be considered as success.
MULTIPART_FORM_DATA tag adds initial support for multipart form data POST-ing as in RFC1867.
Several tags MULTIPART_FORM_DATA can be used for a url to post, e.g. as in ./conf-examples/multipart-formdata-post.conf:
MULTIPART_FORM_DATA="filedescription=Cool text file with cool text inside"
The files to be uploaded are indicated by @ and to be located in the same directory as curl-loader. Content type could be added as e.g. ;type=text/html. Currently, the feature uses the strings provided AS_IS and does not generate any unique users, unique passwords or loads tokens from file.
To prevent from sending "Expect: 100-continue", pass as a custom HTTP header HEADER="Expect: "
TRANSFER_LIMIT_RATE - limits client maximum throughput for a url. The value of the tag to be provided as bytes (! not bits) per second.
FETCH_PROBABILITY - allows to fetch a url not as a must, but with a certain run-time probability. The allowed values are in the range from 1 to 100 percents.
FETCH_PROBABILITY_ONCE when set to 1 configures each client to make the decision regarding whether to fetch a URL marked by a FETCH_PROBABILITY or not, to be done only once, namely, at the first cycle.
4.4. How does the loader support login, logoff and authentication flavors?
curl-loader performs login and logoff operations using the following HTTP methods:
- GET+POST (server response to GET provides a post-form to be filled and posted by POST);
- POST only;
- GET only.
The loader also supports multipart form data POST-ing as in RFC1867.
The loader supports HTTP Web Authentication and Proxy Authentication. The supported authentication methods are Basic, Digest (RFC2617) and NTLM. When responded 401 or 407, libcurl will choose the most safe method from those, supported by the server, unless the batch configuration (test plan) is explicitly indicating the method to be used by the tags WEB_AUTH_METHOD and/or PROXY_AUTH_METHOD.
To support GSS Web-Authentication, add in Makefile building of libcurl against appropriate GSS library, see libcurl pages for detailed instructions.
5. What about FTP load and mixed FTP/HTTP load?
To generate FTP/FTPS load, please, pass user credentials via ftp-url according to
the RFC 1738 like: ftp://username:password@hostname:port/etc-str
Tag FTP_ACTIVE serves to switch from the default passive FTP to active. Please, look at the examples in conf-examples directory, e.g. ftp.conf, ftp_http.conf, ftp_upload.conf.
6. Running Load
6.1. What are the running environment requirements?
Running hundred and thousand of clients, please, do not forget:
- to increase limit of descriptors (sockets) by running e.g.
#ulimit -n 100 000;
- optionally, to set reuse of sockets in time-wait state: by setting
#echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle and/or
#echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse;
In some cases you may need to increase the system limits for open descriptors (sockets):
echo 150 000 > /proc/sys/fs/file-max
Note, that your linux distribution may require editing of some other files like /etc/security/limits.conf, etc
6.2. How I can run the load?
Usage: run as a root user:
#./curl-loader -f <configuration filename> [other options]
Other possible options are:
-c[onnection establishment timeout, seconds]
-d[etailed logging; outputs to logfile headers and bodies of requests/responses. Good for text pages/files]
-e[rror drop client. Client on error doesn't attempt to process the next cycle]
-i[ntermediate (snapshot) statistics time interval (default 3 sec)]
-f[ilename of configuration to run (batches of clients)]
-l[ogfile max size in MB (default 1024). On the size reached, file pointer is rewinded]
-m[ode of loading, 0 - hyper (the default, epoll () based ), 1 - smooth (select () based)]
-r[euse connections disabled. Closes TCP-connections and re-open them. Try with and without]
-t[hreads number. Use it for high loads and when running at SMP/multi-core HW]
-v[erbose output to the logfiles; includes info about headers sent/received]
-u[rl logging - logs url names to logfile, when -v verbose option is used]
Connection Reuse Disable Option (-r):
The default behavior of curl-loader after HTTP response is to re-use the tcp-connection for the next request. If you are specifying -r command-line option, the TCP connection will be closed and re-opened for the next request. Whether it is appropriate for you to work with -r option or without, it depends on your server support of Keep-Alive and the purpose of your testing. Try with and without -r and see, what you get.
Connection reuse (which is the default, without -r option) has advantages due to the decreased consumption of opened descriptors (sockets) and ports.
Threads number -t option. This option is helpful, when running at a multiple CPUs or multiple core CPU HW. We are recommending to use the option only for loads with 1000 clients and more, where the number of threads is kept about the same as the number of the linux logical CPUs seen by cat /proc/cpuinfo.
6.3. Which loading modes are supported?
Hyper-mode (command line -m0) is the default mode . The mode is using for event
demultiplexing epoll() or /dev/epoll.
Another loading mode is called "smooth" (-m1 command line), and it is basically the same as hyper, but uses poll() system call for demultiplexing.
6.4. How I can monitor loading progress status?
curl-loader outputs to the console loading status and statistics as the
Load Status GUI output, where the left column is for the latest interval
and the right is for the summary numbers since load start.
A copy of the output is also saved in the file <batch-name>.txt
6.5. Why I am getting "Connection time-out after 5108 ms" like errors in the log file?
This means, that the connections cannot be established within 5 seconds
(which is the default). If some of clients are getting such errors, this means,
that the server is overloaded and cannot establish TCP connection within
the time. Y may wish to increase the connection timeout globally by e.g. -c 10 or to
specify an increased timeout using tag TIMER_TCP_CONN_SETUP=10.
When all your clients have such errors, in most cases this is due either to resolving or routing problems or other network problems. Y can set any addresses to your clients in IP_ADDR_MIN and IP_ADDR_MAX tags, providing, that you ensure a smooth route from client and from server for the addresses you use.
Please, start with a single client and see that it works, than progress further. When you are specifying any addresses here, they are added by curl-loader initialization to the network interface of your choice and may be seen by the command:
Command ping (man ping) has an option -I to force the ping to be issued from a certain ip-address. To test, that your routing is OK, you may use, e.g.:
#ping -I <the client address you wish to use> url-target
When it works - it will be OK.
Please, also pay attention to the firewalling/NAT settings at your linux loading machine (netfilter/iptables), at the tested servers and through the whole packets route.
Y may also wish to read a bit about linux routing/networking/iptables and DNS resolving HOWTOS.
6.6. Where is the detailed log of all virtual clients activities and how to read it?
Detailed log is written to the file named:
The semantics of logfile output, using command line options -v (verbose) and -u (url print):
"Cycle number", "Client number (ip-address)" - some information string, e.g.:
4 39 (192.168.0.39) :== Info: Trying 10.30.6.42... : eff-url: http://10.30.6.42:8888/server/Admin/ServiceList.do, url:
Which means: cycle: 4, client number 39 with ipv4 address (192.168.0.39), status of the message is Info, eff-url - is the url, used right now, "url:" is empty, which means, that it is the same as effective.
Effective url may be a result of redirection and, thus, "url:"
(target url, specified in batch configuration file) will be printed as well.
Please, note, that when the logfile reaches 1024 MB size, curl-loader rewinds it and starts to overwrite it from the beginning. Y may tune the rewinding file size by using command line option:
6.7. Which statistics is collected and how to get to it?
Currently HTTP/HTTPS statistics includes the following counters:
- run-time in seconds;
- requests num;
- 1xx success num;
- 2xx success num;
- 3xx redirects num;
- client 4xx errors num;
- server 5xx errors num;
- other errors num, like resolving, tcp-connect, server closing or empty responses number (Err);
- url completion time expiration errors (T-Err);
- average application server Delay (msec), estimated as the time between HTTP request and HTTP response without taking into the account network latency (RTT) (D);
- average application server Delay for 2xx (success) HTTP-responses, as above, but only for 2xx responses. The motivation for that is that 3xx redirections and 5xx server errors/rejects may not necessarily provide a true indication of a testing server working functionality (D-2xx);
- throughput in, batch average, Bytes/sec (T-In);
- throughput out, batch average, Bytes/sec (T-Out);
The statistics goes to the screen (both the interval and the current summary statistics for the load) as well as to the file with name <batch_name>.txt When the load completes or when the user presses CTRL-C (sometimes some clients may stall), the final load report is printed at the console as well as to the statistics file.
Some strings from the file:
2, Appl , 100, 155, 0, 0, 96, 0, 0, 0, 0, 1154, 1154, 2108414, 15538
2, Sec-Appl, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
4, Appl, 100, 75, 0, 32, 69, 0, 0, 0, 0, 1267, 1559, 1634656, 8181
4, Sec-Appl, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
36, Appl , 39, 98, 0, 35, 58, 0, 0, 0, 0, 869, 851, 1339168, 11392
36, Sec-Appl, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
38, Appl , 3, 91, 0, 44, 62, 0, 0, 0, 0, 530, 587, 1353899, 10136
38, Sec-Appl, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
*, *, *, *, *, *, *, *, *, *, *, *
38, Appl , 0, 2050, 0, 643, 1407, 0, 213, 0, 0, 725, 812, 1610688, 11706
38, Sec-Appl, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
The bottom strings after asterisks are for final averages.
At the same time a clients dump file with name <batch_name>.ctx is generated to provide detailed statistics about each client state and statistics counters.
One string from the file:
1 (192.168.0.1) ,cycles:124,cstate:1,b-in:22722029,b-out:174605,req:745,2xx:497,3xx:248,4xx:0,5xx:0,err:0
1 (192.168.0.1)- is the index of the client and its ip-address;
cycles- number of loading cycles done;
cstate - is the number of the client state (-1 - error, 0 - init, 1- urls, 2-final-ok);
b-in - bytes passed in;
b-out - bytes passed out;
req- number of requests done;
2xx, 3xx, 4xx, 5xx - number of responses Nxx received;
err - number of libcurl errors at the resolving, TCP/IP and TLS/SSL levels;
The following conditions are considered as errors:
- error at the level of libcurl, which includes resolving, TCP/IP and, when applicable, TLS/SSL errors;
- all HTTP 5xx server errors;
- most of HTTP 4xx client errors, excluding 401 and 407 authentication responses not considered real errors;
When the above error conditions occur, a virtual client is marked as being in the error state.
By default we "recover" such client by scheduling it to the next loading cycle, starting from the first operation of the cycle. You may use command line option -e to change the default behavior to another, so that clients once arriving at error state will not be scheduled for load any more.
7. Advanced Issues
7.1. What about performance?
The loader was already used for loads with up to 60000 HTTP 1.1 clients,
whereas HW issues, mainly memory resources, start to be counting.
7.2. How to run a really big load?
0. Every big load starts with a small load. First, see, that you have a working
configuration file. Run it with a 1-2-3 clients and commandline option -v, and
look into the l<batch-name>.log logfile.
Look into the HW issues, discussed in the FAQs and mind, that each client requires 30-35 K of memory.
1. Compile with optimization;
Since you need performance compile with optimization and without debugging.
$make optimize=1 debug=0
Y may add to Makefile optimization for your particular processor by -match /-mcpu gcc option directives to OPT_FLAGS.
2. Login as a su;
3. Increase the default number of allowed open descriptors (sockets);
Run e.g. #ulimit -n 100 000
When running several instances of curl-loader, consider increase of system limits for open descriptors, if necessary. Take your own account of the socket usage in the system, considering sockets faster recycling (less time in the time-wait state), by setting, optionally, something like this:
#echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle and/or
#echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse;
Correct, if required, the value of CURL_LOADER_FD_SETSIZE (set to 20000 in Makefile) to control the maximum fd, that may be used for select. This is not required to be cared about for the default hyper mode.
Increase the maximum number of open descriptors in your linux system, if required, using linux HOWTOS.
echo 100 000 > /proc/sys/fs/file-max
Note, that your linux distribution may require editing of some other files like /etc/security/limits.conf, etc
4. Relax routing checks;
Relax routing checks for your loading network interface. When "eth0" used for loading run:
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter
5. Increase memory available for kernel tcp;
Read the maximum available TCP memory and sysctl or echo as a root the number to the kernel tcp, e.g.:
cat /proc/sys/net/core/wmem_max - the output is 109568.
/sbin/sysctl net.ipv4.tcp_mem="109568 109568 109568" or
echo "109568 109568 109568" > /proc/sys/net/ipv4/tcp_mem
6. Create configuration files for each instance of curl-loader to run.
What is important is to give a unique value for tag BATCH_NAME, which is in use by a separate instance of curl-loader. Logfile, report file, etc have name, which are the derivatives of the BATCH_NAME value. Therefore, when several instances of curl-loader are writing to the same file, this is not helpful and may be even "crashful". Please, use in your configuration batch files non-overlapping ranges of IP-addresses, else libcurl virtual clients will compete for the IP-addresses to bind to.
Use CLIENTS_RAMPUP_INC tag in smooth or hyper mode to increase number of your clients gradually at start-up in order not boom the server and not to burn out the CPU at your loading machine. Addition of new clients is a CPU-expensive operation, therefore keep CLIENTS_RAMPUP_INC below 100 clients per second per each CPU/core.
7. Connections re-use.
The default behavior of curl-loader now is to re-use the tcp-connection for the next request. This default decreases consumption of CPU and open sockets. If you are specifying -r command-line option, the connection will be closed and re-opened for the next request.
8. Running curl-loader in multiple threads on several CPUs/cores.
SMP-support can be gained by using option -t <threads-num>. We can recommend to use number of threads as the number of logical CPUs seen by cat /proc/cpuinfo. Sometimes curl-loader crashes on start with the option used due to suspected bugs in libevent library. Re-run it optionally changing/decreasing number of threads used. Note, that total statistics is written to the file $batch-name_0.txt, whereas logs are per-thread and are written to the files $batch-name_<thread-num>.log.
Run the first loading attempt with a small number of clients using command-line options -v (verbose) and -u (url in logs). Grep to look for the errors and their reasons. If an error is "Connection timeout", you may try to increase the connection establishment timeout (the default is 5 seconds), using -c command-line option. When all your clients fail to connect with "Connection timeout" error, this may be due to routing or resolving problems.
If any assistance required, please, don't hesitate to contact us using PROBLEM-REPORTING form in the download tarball.
10. Logs and statistics.
After end of a run, or after SIGINT (Cntl-C), the final results are calculated and printed to the console as well as to the file <batch-name>.txt. Current results are presented in each row, and average summary as the last raws, separated from the rest by asterisks.
Pay attention, that <batch-name>.log log file may become huge, particularly, when using verbose output (-v -u). Command-line option -l <maxsize in MB> may be useful, whereas the default policy is to rewind the logfile (writing from the file start), when it reaches 1 GB. Do not use -v and -u options, when you have performance issues.
11. Monitoring of the loading PC.
Please, use top or vmstat commands to monitor the memory usage, swapping and CPU. Intensive swapping is a good indication, that your PC is short in user-space memory. If you see "memory pressure" counters in netstat -s output, this is a good indication, that the PC is short in kernel memory for TCP.
Zero idle CPU is not the show stopper, but when you see, that Load Status GUI on your console prints its output with delays higher than it should be (the default is 3 seconds and may be adjusted by -i command-line option), you need stronger CPU or run several curl-loader processes on a multi-CPU machine. Note, that for a load with several curl-loader processes you need to arrange different configuration files with different batch-names and not overlapping ranges of IP-addresses for each curl-loader process.
7.3. How to calculate CAPS numbers for a load?
When number of clients is defined by CLIENTS_NUM_MAX tag, number of
CAPS (call attempts per seconds) is resulting from the clients number and
load duration for each cycle, comprising from url time for each url with possible
redirections, intervals betwee urls and after url interval.
The actions and time intervals are configurable in batch file, whereas url retrival time is server and network dependent and not always easy to predict. The result is that number of clients/requests is a known parameter, and number of CAPS is something to be estimated from the time of test and number of requests.
Smooth and hyper modes are presenting at the LOAD STATUS GUI the output of calculated current and average CAPS.