Metadata-Version: 2.3
Name: aiolocust
Version: 0.7.9
Summary: High performance Python-based load testing tool
Author: Lars Holmberg
Author-email: Lars Holmberg <lars.holmberg@redshirt.se>
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: Testing :: Traffic Generation
Requires-Dist: aiohttp>=3.13.3
Requires-Dist: rich>=14.2.0
Requires-Dist: uvloop>=0.22.1 ; sys_platform == 'linux'
Requires-Dist: uvloop>=0.22.1 ; sys_platform == 'darwin'
Requires-Dist: typer>=0.21.1
Requires-Dist: opentelemetry-api>=1.40.0
Requires-Dist: opentelemetry-sdk>=1.40.0
Requires-Dist: opentelemetry-instrumentation-aiohttp-client>=0.61b0
Requires-Dist: opentelemetry-instrumentation-logging>=0.61b0
Requires-Dist: pymongo>=4.16.0 ; extra == 'pymongo'
Requires-Python: >=3.14
Provides-Extra: pymongo
Description-Content-Type: text/markdown

# aiolocust

[![PyPI](https://img.shields.io/pypi/v/aiolocust.svg)](https://pypi.org/project/aiolocust/)
![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fcyberw%2Faiolocust%2Fmaster%2Fpyproject.toml)
[![Downloads](https://static.pepy.tech/personalized-badge/aiolocust?period=total&units=INTERNATIONAL_SYSTEM&left_color=GREY&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/aiolocust)
[![Build Status](https://github.com/cyberw/aiolocust/workflows/Tests/badge.svg)](https://github.com/cyberw/aiolocust/actions?query=workflow%3ATests)

This is a 2026 reimagining of the load testing tool [Locust](https://github.com/locustio/locust/).

It has a ton of [advantages over its predecessor](#simple-and-consistent-syntax), but is still in alpha and missing many of Locust's more advanced features. Do let us know if you find any major issues or want to contribute though!

## Installation

We recommend using [uv](https://docs.astral.sh/uv/getting-started/installation/)

```text
uv tool install aiolocust
aiolocust
```

There are also some [alternative ways to install](#alternative-ways-to-install).

## Create a locustfile.py

```python
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](examples/), or keep reading to learn how to create one based on a recording.

## Run a test

```text
❯ 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:

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

## Record a locustfile from browser session or other app

If you don't want to code your locustfile from scratch, you can use [mitmproxy](https://docs.mitmproxy.org/stable/api/events.html) and our custom script to easily generate locustfiles from live traffic:

### Install mitmproxy & trust its certificate authority

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

### Start the proxy

This (at the moment) requires a checked out copy of this repo or at least a copy of [mitmproxy_addon.py](examples/mitmproxy_addon.py):

```text
mitmdump -s examples/mitmproxy_addon.py
```

### Use the proxy from your browser or app

Using curl:

```text
curl -x http://localhost:8080 -k https://www.google.com
```

Using Chrome:

```text
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](examples/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 "gotcha's" 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, 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](https://opentelemetry.io/docs/zero-code/python/). You can also do it [from code](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/aiohttp_client/aiohttp_client.html#usage) for increased flexibility.

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

```text
OTEL_TRACES_EXPORTER=console aiolocust
```

Here's a more complete example, for Splunk:

```text
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 it's two main gains come from:

### 1. [asyncio](https://docs.python.org/3/library/asyncio.html) + [aiohttp](https://docs.aiohttp.org/en/stable/)

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](examples/playwright/locustfile.py)), which are becoming more and more common.

### 2. [Freethreading/no-GIL Python](https://docs.python.org/3/howto/free-threading-python.html)

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 this doesn't have compared do Locust (at least not yet)

* A WebUI
* Support for distributed tests

## Alternative ways to install

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

```text
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:

```text
git clone https://github.com/cyberw/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:

```text
pip install aiolocust
aiolocust
```

## API docs

See [documentation](https://cyberw.github.io/aiolocust/).
