LoadForge
Forge realistic load tests as Python code.
LoadForge is a Python load testing framework for crafting realistic API load tests with code-first scenarios, seven traffic patterns, multi-core execution, interactive HTML reports, and a live React dashboard.
Features
- Code-first scenarios — define load tests as Python classes with
@scenarioand@taskdecorators - 7 traffic patterns — constant, ramp, step, spike, diurnal,
composite, plus custom patterns via
LoadPatternABC - Multi-core engine — distributes virtual users across CPU cores via multiprocessing with shared metric queues
- Live dashboard — real-time React + Recharts WebSocket dashboard
- Interactive reports — self-contained HTML with Plotly charts, plus JSON and CSV exports
- HDR histograms — percentile-accurate latency tracking (p50 / p95 / p99 / p99.9)
- Fully typed — PEP 561 typed, zero
Any, strict mypy
Quick Start
Installation
pip install loadforge
1. Create a scenario
loadforge init my_api_test
Or write one directly:
from loadforge import HttpClient, scenario, task
@scenario(name="My API", base_url="http://localhost:8080")
class MyScenario:
@task(weight=1)
async def get_root(self, client: HttpClient) -> None:
await client.get("/", name="Root")
2. Run it
loadforge run my_api_test.py --users 50 --duration 60
3. View results
An HTML report is generated in ./results/report.html. For live
monitoring, add --dashboard:
loadforge run my_api_test.py --users 50 --duration 60 --dashboard
Then open http://localhost:8089 in your browser.
Traffic Patterns
| Pattern | CLI Flag | Description |
|---|---|---|
| Constant | --pattern constant |
Fixed user count (default) |
| Ramp | --pattern ramp --ramp-to N |
Linear ramp up/down |
| Step | --pattern step --step-size N |
Staircase increments |
| Spike | --pattern spike |
Sudden burst + decay |
| Diurnal | --pattern diurnal |
Sine-wave day/night cycle |
| Composite | (programmatic) | Chain patterns sequentially |
Architecture
graph TD
A[Scenario .py File] --> B[CLI / LoadTestRunner]
B --> C[Coordinator]
C --> D1[Worker 1]
C --> D2[Worker 2]
C --> DN[Worker N]
D1 --> E[Metric Queues]
D2 --> E
DN --> E
E --> F[Aggregator]
F --> G[MetricStore]
F --> H[Dashboard WebSocket]
G --> I[Report Generator]
I --> J[HTML / JSON / CSV]
H --> K[React Dashboard]
How it works:
- The CLI loads a scenario file and builds a traffic pattern
- The Coordinator spawns worker processes (one per CPU core)
- Each Worker runs an async event loop driving virtual users
- Virtual users execute weighted
@taskmethods against the target API - Request metrics flow through queues to the Aggregator
- The aggregator feeds the live dashboard (WebSocket) and MetricStore (time-series)
- After the test, the Report Generator produces HTML/JSON/CSV
CLI Reference
loadforge run <scenario.py> [OPTIONS]
Options:
-u, --users INT Target concurrent users (default: 10)
-d, --duration FLOAT Test duration in seconds (default: 60)
-p, --pattern TEXT Traffic pattern (default: constant)
--ramp-to INT Ramp pattern: target user count
--step-size INT Step pattern: users added per step
--step-duration FLOAT Step pattern: seconds between steps
-w, --workers INT Worker processes (default: CPU count)
-o, --output PATH Output directory (default: ./results)
-f, --format TEXT Report format: html, json, csv (default: html)
--no-report Skip report generation
--dashboard Start live dashboard server
--dashboard-port INT Dashboard port (default: 8089)
--fail-on-error-rate F Exit non-zero if error rate exceeds threshold
-v, --verbose Enable debug logging
loadforge init [name] Scaffold a new scenario file
loadforge report <dir> Regenerate reports from saved data
loadforge dashboard <dir> Replay results in the live dashboard
loadforge --version Show version
Examples
| Example | File | Demonstrates |
|---|---|---|
| Basic GET | basic_get.py |
Minimal single-endpoint scenario |
| REST API | rest_api.py |
Multi-endpoint with weighted tasks |
| Auth flow | auth_flow.py |
Setup / teardown hooks |
| Spike test | spike_test.py |
Spike traffic pattern |
| Diurnal | diurnal_simulation.py |
Day/night traffic cycle |
| Composite | composite_pattern.py |
Multi-phase load profile |
Comparison
| Feature | LoadForge | Locust | k6 | JMeter |
|---|---|---|---|---|
| Language | Python | Python | JavaScript | XML / GUI |
| Async I/O | aiohttp | gevent | Go runtime | Threads |
| Multi-core | multiprocessing | distributed | goroutines | threads |
| Traffic patterns | 7 built-in | manual shape | manual | plugins |
| Live dashboard | React + WS | built-in | Grafana | built-in |
| HTML reports | Plotly | built-in | — | built-in |
| HDR histograms | yes | no | yes | partial |
| Typed (mypy strict) | yes | no | N/A | N/A |
| Custom patterns | LoadPattern ABC |
shape class | — | — |
Development
git clone https://github.com/aqasim81/api-load-testing-framework.git
cd api-load-testing-framework
uv sync --all-extras
make validate # Format, lint, type-check, test (80%+ coverage)
Running tests
uv run pytest tests/unit/ -v # Unit tests
uv run pytest tests/integration/ -v # Integration tests
uv run pytest tests/e2e/ -v # End-to-end CLI tests
License
Release files for loadforge 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| loadforge-0.2.0.tar.gz | 385.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| loadforge-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 626.4 kB
Release files / loadforge-0.2.0.tar.gz
| Download URL | loadforge-0.2.0.tar.gz |
|---|---|
| Size | 385.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
af54dc3968ba46d3865a339d1a10e1260dfb5443fb2f62d0d6461fdcd78b2b02
|
|
BLAKE2b-256 checksum How to use checksums |
141dca513f6cec9150c3aef707cd15ed44f69c67be191b82d2774d64350ff0ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / loadforge-0.2.0-py3-none-any.whl
| Download URL | loadforge-0.2.0-py3-none-any.whl |
|---|---|
| Size | 240.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3eef2d8ad870426e93bba2271cdd323df24d493673de1c4de8177adecd889aa8
|
|
BLAKE2b-256 checksum How to use checksums |
d5ea315ec8703d7d9f39929aea895285f2e7ece44c2735df8aa627073d065e42
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log