Increase Locust’s performance with a faster HTTP client

Locust’s default HTTP client uses python-requests. The reason for this is that requests is a very well-maintained python package, that provides a really nice API, that many python developers are familiar with. Therefore, in many cases, we recommend that you use the default HttpLocust which uses requests. However, if you’re planning to run really large scale tests, Locust comes with an alternative HTTP client, FastHttpLocust which uses geventhttpclient instead of requests. This client is significantly faster, and we’ve seen 5x-6x performance increases for making HTTP-requests. This does not necessarily mean that the number of users one can simulate per CPU core will automatically increase 5x-6x, since it also depends on what else the load testing script does. However, if your locust scripts are spending most of their CPU time in making HTTP-requests, you are likely to see signifant performance gains.

How to use FastHttpLocust

Subclass FastHttpLocust instead of HttpLocust:

from locust import TaskSet, task, between
from locust.contrib.fasthttp import FastHttpLocust

class MyTaskSet(TaskSet):
    def index(self):
        response = self.client.get("/")

class MyLocust(FastHttpLocust):
    task_set = MyTaskSet
    wait_time = between(1, 60)


FastHttpLocust uses a whole other HTTP client implementation, with a different API, compared to the default HttpLocust that uses python-requests. Therefore FastHttpLocust might not work as a drop-in replacement for HttpLocust, depending on how the HttpClient is used.


SSL domain check is turned off in the FastHttpLocust’s client implementation. So it will let through invalid SSL certificates without complaining.


FastHttpSession class

class FastHttpSession(base_url, **kwargs)
__init__(base_url, **kwargs)

x.__init__(…) initializes x; see help(type(x)) for signature

get(path, **kwargs)

Sends a GET request

head(path, **kwargs)

Sends a HEAD request

options(path, **kwargs)

Sends a OPTIONS request

patch(path, data=None, **kwargs)

Sends a POST request

post(path, data=None, **kwargs)

Sends a POST request

put(path, data=None, **kwargs)

Sends a PUT request

request(method, path, name=None, data=None, catch_response=False, stream=False, headers=None, auth=None, **kwargs)

Send and HTTP request Returns locust.contrib.fasthttp.FastResponse object.

  • method – method for the new Request object.
  • path – Path that will be concatenated with the base host URL that has been specified. Can also be a full URL, in which case the full URL will be requested, and the base host is ignored.
  • name – (optional) An argument that can be specified to use as label in Locust’s statistics instead of the URL path. This can be used to group different URL’s that are requested into a single entry in Locust’s statistics.
  • catch_response – (optional) Boolean argument that, if set, can be used to make a request return a context manager to work as argument to a with statement. This will allow the request to be marked as a fail based on the content of the response, even if the response code is ok (2xx). The opposite also works, one can use catch_response to catch a request and then mark it as successful even if the response code was not (i.e 500 or 404).
  • data – (optional) Dictionary or bytes to send in the body of the request.
  • headers – (optional) Dictionary of HTTP Headers to send with the request.
  • auth – (optional) Auth (username, password) tuple to enable Basic HTTP Auth.
  • stream – (optional) If set to true the response body will not be consumed immediately and can instead be consumed by accessing the stream attribute on the Response object. Another side effect of setting stream to True is that the time for downloading the response content will not be accounted for in the request time that is reported by Locust.
class FastResponse(ghc_response, request=None, sent_request=None)

Unzips if necessary and buffers the received body. Careful with large files!

headers = None

Dict like object containing the response headers


Returns the text content of the response as a decoded string (unicode on python2)