← Back home · Compare
rpytest vs pytest-xdist
The parallel-pytest standard
pytest-xdist parallelizes pytest by spawning workers. rpytest ships an `-n` surface that matches it but doesn't pay xdist's per-worker startup cost.
| Feature | rpytest | pytest-xdist | Advantage |
|---|---|---|---|
| Parallel flag surface | `-n N`, `-n auto` | `-n N`, `-n auto` | Comparable |
| Worker startup cost | Paid once at daemon start | Paid per worker per invocation | rpytest |
| Collection cost | Once per daemon lifetime | Once per worker per invocation | rpytest |
| 500-test bench, -n 4 | 0.25 s (BENCHMARK.md) | 0.87 s (BENCHMARK.md) | rpytest |
| 500-test bench, -n auto | 0.20 s (BENCHMARK.md) | 1.90 s (BENCHMARK.md) | rpytest |
| Load-balancing strategy | Duration-aware (built-in) | Configurable: load/loadscope/loadfile/loadgroup | pytest-xdist |
| Plugin install footprint | None (built into rpytest) | pip install pytest-xdist | rpytest |
| Stateful-test distribution | Standard grouping | dist=loadfile / loadgroup is mature | pytest-xdist |
| Behavior under low test counts | Daemon stays warm, parallel is cheap | Worker overhead can exceed test runtime | rpytest |
| Configuration | `-n` flag, defaults sensible | `-n` plus `--dist`, addopts in pytest.ini | Comparable |
| Verifies equivalence to pytest | `--verify-dropin` | N/A (it is a pytest plugin) | rpytest |
Benchmark numbers cited are from rpytest's BENCHMARK.md on a 500-test synthetic suite (AMD Ryzen 7 5700U, Python 3.12.3, pytest 9.0.2, pytest-xdist 3.8.0). Your suite will differ.
Pick rpytest when
- ▸Your suite is small-to-medium and xdist's worker startup eats your parallel gain (this happens often under ~1000 tests)
- ▸You want `-n auto` to work without an additional dependency in your pytest environment
- ▸Your CI workers spawn pytest more than once per job (last-failed, sharded retries) and want the daemon to stay warm
- ▸You want duration-aware load balancing without configuring an xdist scheduler
Pick pytest-xdist when
- ▸You depend on xdist-specific features (loadscope/loadfile/loadgroup distribution, dist=loadfile semantics for stateful tests)
- ▸You're running on a CI runner that can't keep a daemon alive between invocations and you only ever run pytest once per job
- ▸You've already tuned xdist to your suite and the marginal gain isn't worth the swap
Want to verify the swap before you commit?
Run rpytest --verify-dropin on your suite. It runs both pytest and rpytest and diffs the collection, results, and exit codes. If anything disagrees, you find out before CI does.