Skip to content

Chapter 14 · asyncio Support ​

Chapter goals: Understand the relationship between Locust's gevent concurrency model and the asyncio ecosystem, master aiolocust usage, and choose the right approach for your scenario.

14.1 Locust's Concurrency Model: gevent ​

Locust's traditional concurrency is based on gevent — a Python cooperative concurrency library that monkey-patches standard library I/O operations into non-blocking versions. Each virtual User runs in a greenlet (lightweight coroutine):

python
# Executed automatically when Locust starts
from gevent import monkey
monkey.patch_all()  # Replace blocking calls in socket, time, threading, etc.

# Thereafter all User instances run in greenlets; CPU is yielded automatically on I/O wait

gevent's advantage: transparent to user code — you write sync code and Locust handles concurrency automatically. Its disadvantage: monkey-patching does not work on C-extension libraries (see Chapter 13).

14.2 aiolocust: Redesign with asyncio ​

aiolocust is a 2026-born project in the Locust ecosystem that replaces the gevent/requests stack entirely with asyncio/aiohttp, embracing modern Python async standards.

bash
pip install aiolocust

Basic usage:

python
import asyncio
from aiolocust import HttpUser

async def run(user: HttpUser):
    async with user.client.get("http://example.com/") as resp:
        pass  # Handle response

    async with user.client.get("http://example.com/") as resp:
        # Extra validation beyond just HTTP status:
        assert "expected text" in await resp.text()

    await asyncio.sleep(0.1)

Project status

aiolocust is currently maintained as a standalone project with fewer features than the Locust mainline (more minimalistic), relying on OTEL for visualization. It may merge into Locust or ship with a future major version.

14.3 gevent vs asyncio Comparison ​

Dimensiongevent (Locust)asyncio (aiolocust)
Concurrency Modelgreenlet + monkey-patchNative async/await
Learning CurveLow (write sync code)Medium (understand async)
C-extension compat❌ Cannot patch✅ Native support
HTTP clientrequestsaiohttp
WebSocketExtra library neededBuilt into aiohttp
EcosystemMature and stableRapidly developing
Best forTraditional HTTP API load testingHigh concurrency, C-lib deps, WebSocket

Decision tree ​

text
What does your load test need?
├── Only HTTP/HTTPS API → Use Locust (gevent), most mature ecosystem
├── Needs C-extension libs (psycopg2, etc.) → Consider aiolocust
├── Heavy WebSocket long connections → aiolocust or custom extension
├── Team familiar with asyncio → aiolocust feels more natural
└── Need full Web UI and distributed mode → Locust (more features)

14.4 Mixing Async Code in Regular Locust ​

Even without aiolocust, you can call async functions (e.g., asyncpg DB queries) inside Locust tasks:

python
import asyncio
from locust import User, task, between

class AsyncDbUser(User):
    wait_time = between(0.5, 2)

    @task
    def query_db(self):
        # Run async code in a separate event loop
        result = asyncio.get_event_loop().run_until_complete(
            self.async_query()
        )

However, this approach defeats the purpose of gevent's concurrent greenlets — each run_until_complete call blocks the greenlet. Use aiolocust instead for true async concurrency.

14.5 Chapter Summary ​

  • Locust's native model is gevent-based: write sync code, get concurrency for free;
  • aiolocust offers a modern asyncio/aiohttp stack for C-extension and WebSocket scenarios;
  • gevent cannot patch C extensions; asyncio handles them natively;
  • Mixing asyncio into gevent Locust blocks greenlets — prefer aiolocust for true async workloads.

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. What is gevent's core mechanism for achieving concurrency?

2. When should you choose aiolocust over standard Locust?

3. Why does mixing asyncio.run() inside a gevent greenlet block concurrency?

4. Which HTTP client does aiolocust use under the hood?

🛠️ Hands-On Exercises ​

  1. Write a standard Locust test with gevent; measure RPS on 1,000 concurrent users against httpbin.org.
  2. Install aiolocust; rewrite the same test in async style; compare RPS and code clarity.
  3. Try using psycopg2 in a standard Locust task; observe the blocking behavior and switch to aiolocust with asyncpg.

Proceed to Chapter 15: Using Locust as a Library.