Skip to main content

Write load tests in Python. Run them at Rust speed.

Project description

LoadPilot

CI License: MIT

Write load tests in Python. Run them at Rust speed.

LoadPilot — CheckoutFlow  [01:42]  steady: 100/100 RPS

  Requests/sec:     100.0      Total:     9,812
  Errors:             0.0%     Failed:         0

  Latency:
    p50:   12ms
    p95:   28ms
    p99:   41ms
    max:  203ms

  [████████████████████] 100%

LoadPilot is a load testing tool for teams that want to write scenarios in Python without the throughput ceiling of a pure-Python engine.

Scenarios are plain Python classes. HTTP execution runs in async Rust.


Install

pip install loadpilot

No Rust required — the coordinator binary is bundled in the wheel.

Supported platforms: Linux x86_64 · macOS Intel · macOS Apple Silicon · Windows x86_64


Quick Start

# scaffold a project
loadpilot init my-load-tests
cd my-load-tests

# run a scenario
loadpilot run scenarios/example.py --target https://your-api.example.com

Or run without arguments to pick a scenario interactively:

loadpilot run --target https://your-api.example.com

Getting Started in 5 minutes


Write a Scenario

from loadpilot import VUser, scenario, task, LoadClient

@scenario(rps=100, duration="2m", ramp_up="30s")
class CheckoutFlow(VUser):

    def on_start(self, client: LoadClient):
        resp = client.post("/auth/login", json={"user": "test", "pass": "secret"})
        self.token = resp.json()["access_token"]

    @task(weight=5)
    def browse(self, client: LoadClient):
        client.get("/api/products", headers={"Authorization": f"Bearer {self.token}"})

    def check_browse(self, status_code: int, body) -> None:
        assert status_code == 200
        assert isinstance(body, list)

    @task(weight=1)
    def purchase(self, client: LoadClient):
        client.post("/api/orders", json={"product_id": 42, "qty": 1},
                    headers={"Authorization": f"Bearer {self.token}"})
  • on_start — runs once per virtual user before tasks start (login, setup)
  • @task — weighted HTTP task; multiple tasks run in proportion
  • check_{task} — assertion after each request; fail = error counted

Features

Python DSL @scenario, @task, on_start, check_* — no new syntax to learn
Load profiles ramp (default), constant, step, spike
SLA thresholds fail CI with exit code 1 on p99/p95/error-rate breach
Distributed mode coordinator + N agents over NATS; local or remote, free
HTML report self-contained, open in any browser, no server required
Prometheus metrics live Grafana dashboards while the test runs
Interactive TUI loadpilot run with no args opens a scenario browser
pip install coordinator binary bundled in the wheel, no Rust needed

Performance

LoadPilot is benchmarked against k6 and Locust against a Rust/axum echo server in Docker. LoadPilot runs in PyO3 mode — with on_start (login) and check_* (assertion per task) — a realistic workload with Python callbacks active.

Precision — 500 RPS target

Tool RPS actual p50 p99 Errors CPU avg
LoadPilot (PyO3) 478 4ms 15ms 0% 14%
k6 491 8ms 118ms 0% 129%
Locust 498 150ms 1500ms 0% 88%

LoadPilot uses 9× less CPU than k6 at the same load. Locust reaches the RPS target but its Python/GIL scheduler adds significant latency (p99 ≥ 1500ms at only 500 RPS).

Max throughput — 30s, no cap

Tool RPS p50 p99 Errors CPU avg
LoadPilot (PyO3) 2205 11ms 38ms 0% 165%
k6 1799 14ms 175ms 0% 212%
Locust 677 100ms 170ms 0% 117%

1.2× k6 and 3.3× Locust at max throughput. 1.6× better CPU efficiency per request vs k6.

Full benchmark details and methodology


SLA Thresholds

@scenario(
    rps=100, duration="2m",
    thresholds={"p99_ms": 500, "p95_ms": 300, "error_rate": 1.0},
)
class CheckoutFlow(VUser): ...
Thresholds
  ✓  p99 latency       41ms  <  500ms
  ✓  p95 latency       28ms  <  300ms
  ✓  error rate         0%   <    1%

All thresholds passed.

Exit code 1 on breach — drop into any CI pipeline. Override without editing the file:

loadpilot run scenarios/checkout.py --target https://staging.example.com \
  --threshold p99_ms=800 --threshold error_rate=2

Distributed Mode

# 4 local processes
loadpilot run scenarios/checkout.py --target https://api.example.com --agents 4

# external agents on remote machines
loadpilot run scenarios/checkout.py \
  --target https://api.example.com \
  --external-agents 4

The CLI output is identical to single-machine mode — the coordinator aggregates everything transparently. on_start (login, setup) runs on the coordinator and ships per-user auth headers to agents, so distributed tests can authenticate without Python running on each agent.

Distributed mode guide


Live Monitoring

# scaffolded by `loadpilot init`
docker compose -f monitoring/docker-compose.yml up -d
# Grafana → http://localhost:3000   (LoadPilot dashboard auto-imported)
# Prometheus → http://localhost:9091

Use Grafana to correlate load test metrics with your service's own metrics (CPU, DB latency, error rates) on the same timeline.


Documentation


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

loadpilot-0.1.3.tar.gz (58.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

loadpilot-0.1.3-cp312-cp312-win_amd64.whl (2.4 MB view details)

Uploaded CPython 3.12Windows x86-64

loadpilot-0.1.3-cp312-cp312-manylinux_2_38_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.38+ x86-64

loadpilot-0.1.3-cp312-cp312-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file loadpilot-0.1.3.tar.gz.

File metadata

  • Download URL: loadpilot-0.1.3.tar.gz
  • Upload date:
  • Size: 58.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for loadpilot-0.1.3.tar.gz
Algorithm Hash digest
SHA256 d1e1846a748aa38f3ac9d217bb876d2130f449fa65509c2d47776e189a011de5
MD5 17a1fae029ca661f326b2f8c30a54fba
BLAKE2b-256 dd089cbe9ecc352fa04d492b3a931782bf6da658fc56da66d6c6bfa863991098

See more details on using hashes here.

Provenance

The following attestation bundles were made for loadpilot-0.1.3.tar.gz:

Publisher: release.yml on VladislavAkulich/loadpilot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file loadpilot-0.1.3-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: loadpilot-0.1.3-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 2.4 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for loadpilot-0.1.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 33ae3057c5c171eba82eb8d731fffb620afecab61a6e046f8988dfebb595ee46
MD5 508a39c131be65b39a17f7e9ab185949
BLAKE2b-256 29e801720d317346663167876e37b15ff5193c230ac859ef01a16e1dfd094a16

See more details on using hashes here.

Provenance

The following attestation bundles were made for loadpilot-0.1.3-cp312-cp312-win_amd64.whl:

Publisher: release.yml on VladislavAkulich/loadpilot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file loadpilot-0.1.3-cp312-cp312-manylinux_2_38_x86_64.whl.

File metadata

File hashes

Hashes for loadpilot-0.1.3-cp312-cp312-manylinux_2_38_x86_64.whl
Algorithm Hash digest
SHA256 e0255160e41e0f4c5f47ac1d790518b5690c75727dcca6988196b32302fc345c
MD5 3aab3012289ad6c9bca04382ff7645dd
BLAKE2b-256 ab1c9adecf99e79714eb38a619444f066e402e212be9c20c6638f932633de738

See more details on using hashes here.

Provenance

The following attestation bundles were made for loadpilot-0.1.3-cp312-cp312-manylinux_2_38_x86_64.whl:

Publisher: release.yml on VladislavAkulich/loadpilot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file loadpilot-0.1.3-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for loadpilot-0.1.3-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b1d33ecbd4941e7bdd88c5ccddcfe684be1f83e4c7dabde60c7aed025db04f3a
MD5 be51bd29de0ffe7c155036a9dbf67555
BLAKE2b-256 f6ee361456224247e9bf3838d8c3359b23ebe17bc0748d9602968a7bdceb680f

See more details on using hashes here.

Provenance

The following attestation bundles were made for loadpilot-0.1.3-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on VladislavAkulich/loadpilot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page