Skip to main content

aiolocust

PyPI Python Version from PEP 621 TOML Downloads Build Status

This is a 2026 reimagining of the load testing tool Locust.

It has a ton of advantages over its predecessor and is more narrow in scope.

Installation

We recommend using uv for installation. aiolocust requires a freethreading Python build, which is often the default, but it is sometimes necessary to be explicit, using the --python flag:

> uv tool install --python 3.14t aiolocust
...
> aiolocust
Welcome to aiolocust! Create a locustfile.py in your current directory or specify a different one as an argument.

There are also some alternative ways to install.

Create a locustfile.py

import asyncio
from aiolocust import HttpUser


async def run(user: HttpUser):
    async with user.client.get("http://example.com/") as resp:
        pass
    async with user.client.get("http://example.com/") as resp:
        # extra validation, not just HTTP response code:
        assert "expected text" in await resp.text()
    await asyncio.sleep(0.1)

See more examples, or keep reading to learn how to create one based on a recording.

Run a test

aiolocust --duration 30 --users 100
 Name                   ┃  Count ┃ Failures ┃    Avg ┃    Max ┃       Rate
━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━
 http://example.com/    │ 120779 │ 0 (0.0%) │  1.6ms │ 22.6ms │ 60372.44/s
────────────────────────┼────────┼──────────┼────────┼────────┼────────────
 Total                  │ 120779 │ 0 (0.0%) │  1.6ms │ 22.6ms │ 60372.44/s

 Name                   ┃  Count ┃ Failures ┃    Avg ┃    Max ┃       Rate
━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━
 http://example.com     │ 243411 │ 0 (0.0%) │  1.6ms │ 22.6ms │ 60800.63/s
────────────────────────┼────────┼──────────┼────────┼────────┼────────────
 Total                  │ 243411 │ 0 (0.0%) │  1.6ms │ 22.6ms │ 60800.63/s
...
 Name                   ┃   Count ┃ Failures ┃    Avg ┃    Max ┃       Rate
━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━
 http://example.com/    │ 1836384 │ 0 (0.0%) │  1.6ms │ 22.6ms │ 61154.84/s
────────────────────────┼─────────┼──────────┼────────┼────────┼────────────
 Total                  │ 1836385 │ 0 (0.0%) │  1.6ms │ 22.6ms │ 61154.87/s

To save the final Rich summary as a static HTML report:

aiolocust --duration 30 --users 100 --html-report report.html

Rate limiting

If you want to set a target request rate, rather than relying solely on user count and static sleeps to control the load, use pyrate.

For convenience, aiolocust provides a pre-packaged decorator:

from aiolocust import HttpUser, rate_limit

class MyUser(HttpUser):
    @rate_limit(10)
    async def run(self):
        ...

Record a locustfile from browser session or other app

If you don't want to code your locustfile from scratch, you can use mitmproxy and our custom script to easily generate locustfiles from live traffic:

Install mitmproxy & trust its certificate authority (macOS)

Note: these steps makes the mitmproxy's CA trusted system wide.

uv tool install -p 3.14+gil --with aiolocust mitmproxy # mitmproxy dependencies don't like freethreading atm
mitmproxy   # Run it once to generate ~/.mitmproxy (quit by pressing 'q')

Start the proxy

See mitmproxy_addon.py for details.

mitmdump -s $(uv tool dir)/mitmproxy/lib/python3.14/site-packages/aiolocust/mitmproxy_addon.py

Use the proxy from your browser or app

Using curl:

CURL_CA_BUNDLE=~/.mitmproxy/mitmproxy-ca-cert.pem HTTPS_PROXY=http://localhost:8080 curl https://www.google.com

Using Chrome:

Install certificates at system level:

sudo security add-trusted-cert -d -p ssl -p basic -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem

Record session:

open -na "Google Chrome" --args --proxy-server="http://127.0.0.1:8080" --incognito --user-data-dir="/tmp/chrome-proxy-session" --no-first-run --no-default-browser-check --disable-component-update --disable-extensions --new-window --proxy-bypass-list="<-loopback>" http://localhost/some-url

... and now click around doing your stuff!

--proxy-server is of course the most key parameter for recording. You should be able to make this setting in other apps or even at OS level if necessary.

Look at the generated locustfile.py (it is updated while recording)

For details and additional options, see mitmproxy_addon.py.

Why a rewrite instead of just expanding Locust?

Locust was created in 2011, and while it has gone through several major overhauls, it still has a lot of legacy-style code, and has accumulated a lot of non-core functionality that makes it very hard to maintain and improve. It has over 10,000 lines of code, with a mix of procedural, object oriented and functional programming, with several confusing abstractions.

aiolocust is built to be smaller in scope, but still capture the learnings from Locust. It is possible that this could be merged into Locust at some point, but for now it is a completely separate package.

Simple and consistent syntax

Tests are expressed in modern, explicitly asynchronous code, instead of relying on gevent monkey patching, and implicit concurrency.

It has fewer "gotchas" and better type hinting, that should make it easier for humans as well as AIs to understand and write tests.

We also plan to further emphasize the "It's just Python"-approach. For example, if you want to take precise control of the ramp up and ramp down of a test, you shouldn't need to read the documentation, you should only need to know how to write code. We'll still provide the option of using prebuilt features too of course, but we'll make an effort not to box users in, which was sometimes the case with Locust.

OTEL Native

aiolocust uses OTel for metrics internally and exporting them into your own monitoring solution is easy. By default, it creates a locust.client.duration histogram and a locust.current_users gauge, as well as basic trace spans for every request and logs.

If you also want to propagate spans, and standard metrics, you can either use the --instrument command line option or use an agent for zero-code instrumentation. You can also do it from code for increased flexibility.

aiolocust supports standard OTel env vars for exporter configuration, for example:

OTEL_TRACES_EXPORTER=console aiolocust

Here's a more complete example, for Splunk:

OTEL_METRIC_EXPORT_INTERVAL=1000 OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://ingest.us1.signalfx.com/v2/trace/otlp" OTEL_EXPORTER_OTLP_METRICS_ENDPOINT="https://ingest.us1.signalfx.com/v2/datapoint/otlp" OTEL_EXPORTER_OTLP_HEADERS="X-SF-TOKEN=..." OTEL_EXPORTER_OTLP_METRICS_PROTOCOL="http" OTEL_METRIC_EXPORT_INTERVAL=500 aiolocust --instrument

High performance

aiolocust is more performant than "regular" Locust because it has a smaller footprint/complexity, but its two main strengths come from:

1. asyncio + aiohttp

aiolocust's performance is much better than HttpUser (based on python-requests), and even slightly better than FastHttpUser (based on geventhttpclient). Because it uses asyncio instead of monkey patching it allows you to use other asyncio libraries (like Playwright), which are becoming more and more common.

2. Freethreading/no-GIL Python

This means that you don't need to launch one Locust process per CPU core. And even if your scripts happen to do some heavy computations, they are less likely to impact each other, as one thread will not block Python from concurrently working on another one.

Users/threads can also communicate easily with each other, as they are in the same process, unlike in the old Locust implementation where you were forced to use ZeroMQ messaging between master and worker processes and worker-to-worker communication was nearly impossible.

Things aiolocust doesn't have compared to Locust (at least not yet)

  • A WebUI
  • Support for distributed tests (although with OTEL you can aggregate independent concurrent test runs in a single dashboard)

Alternative ways to install

If your tests need additional packages, or you want to structure your code in a complete Python project:

uv init --python 3.14t
uv add aiolocust
uv run aiolocust

Install for developing the tool itself, or just getting the latest changes before they make it into a release:

git clone https://github.com/locustio/aiolocust.git
cd aiolocust
uv run aiolocust

You can still use good ol' pip as well, just remember that you need a freethreading Python build:

pip install aiolocust
aiolocust

API docs

See documentation.

Contributions

Do let us know if you want to contribute or have feedback on any design choices!

You can reach us on the same Discord as the main Locust project.

Metadata

Release files for aiolocust 0.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aiolocust 0.10.1
File Size Uploaded
aiolocust-0.10.1.tar.gz 23.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aiolocust 0.10.1
File Interpreter ABI Platform
aiolocust-0.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 50.9 kB

Release files / aiolocust-0.10.1.tar.gz

Download URL aiolocust-0.10.1.tar.gz
Size 23.4 kB
Tags Source
SHA-256 checksum
How to use checksums
67c57a56ecdaa5283191f246b856c59bc584fa4add6871645473abaa6157e121
BLAKE2b-256 checksum
How to use checksums
c370ad469cba777967c759c3638d13c3ac971f1c46f8b9f62bb2bb0034c7bd5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / aiolocust-0.10.1-py3-none-any.whl

Download URL aiolocust-0.10.1-py3-none-any.whl
Size 27.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d1ff435ff48c8a64f9753b32aff155802136876ce0cf32196c52db52245ed847
BLAKE2b-256 checksum
How to use checksums
10b1ffb5d5bba010fac6081d332143878d5c8a0258000513a08a9e1bfa54afa2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.12.6

2 release files

0.12.5

2 release files

0.12.4

2 release files

0.12.2

2 release files

0.12.1

2 release files

0.12.0

2 release files

This release

0.10.1 This release

2 release files

0.10.0

2 release files

0.9.17

2 release files

0.9.16

2 release files

0.9.15

2 release files

0.9.14

2 release files

0.9.13

2 release files

0.9.12

2 release files

0.9.11

2 release files

0.9.10

2 release files

0.9.9

2 release files

0.9.6

2 release files

0.9.5

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.5

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.19

2 release files

0.7.18

2 release files

0.7.15

2 release files

0.7.14

2 release files

0.7.13

2 release files

0.7.11

2 release files

0.7.10

2 release files

0.7.9

2 release files

0.7.8

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page