Skip to main content

HTTP load testing you can feel. Every request is a particle; watch your server take the hit, live in your terminal.

Project description

wallop

CI tests python license

HTTP load testing you can feel. Every request is a particle. Watch them fly across your terminal and slam into your server — successes spark green, 404s ricochet, 500s explode, timeouts dissolve into smoke. Latency is literally flight time.

Think Logstalgia meets oha: a real load generator with real stats (RPS, p50/p95/p99, status codes), rendered as a live physics scene instead of yet another line chart.

wallop demo

One full incident, live in the terminal: healthy traffic → latency creep (particles stalling mid-air) → error storm (red explosions, embers) → meltdown → recovery.

Why

Load tests produce the most dramatic data in software — a server being hammered, degrading, recovering — and we render it as the world's most boring line charts. You stare at a p99 number and feel nothing.

wallop makes load visceral while staying a real tool:

  • Latency is flight time. Fast servers feel like a laser stream. Slow servers make particles visibly hang mid-air, piling up in front of the wall.
  • Failures are physical. 4xx ricochet off in orange arcs. 5xx detonate with debris, screen shake, and embers that smolder on the ground. Timeouts never reach the wall — they fade into grey smoke.
  • The wall is your server's mood ring. It glows green when healthy and burns red as the error rate climbs.
  • The numbers are still there. Live RPS, p50/p95/p99, per-class status counts, error rate, in-flight count, and an RPS sparkline — plus a vegeta-style summary when you're done.

It runs over SSH, in any modern terminal, with zero OpenGL, zero browser, one dependency.

Quickstart (60 seconds)

# with uv (recommended)
uv tool install wallop        # or: pipx install wallop

# the instant wow — spins up a built-in chaos server and hammers it
# through a scripted incident: healthy → latency creep → error storm
# → meltdown → recovery
wallop demo

# hammer your own service
wallop http://localhost:8080/api/health -c 100 -d 30s

Running from a clone instead:

git clone https://github.com/siam-hossain9/wallop && cd wallop
uv run wallop demo

Press q or Ctrl+C to stop. You get a clean summary either way:

  ─────────────────────────────────────────────
  wallop summary — http://localhost:8080/api/health
  ─────────────────────────────────────────────
  duration   30.0s
  requests   45,231  (1,507.7 req/s)
  latency    p50 12ms   p90 33ms   p95 48ms   p99 130ms
             min 4ms    max 1.21s
  status     2xx 44,903 · 4xx 210 · 5xx 118
  data read  12.4 MB

Usage

wallop URL [options]          hammer a URL
wallop demo                   built-in chaos server + load run (the GIF maker)
wallop serve [--port 8089]    run only the chaos server, point anything at it
Option Default Meaning
-c, --concurrency 50 concurrent workers
-d, --duration until q e.g. 30s, 2m, 500ms
-n, --requests stop after N total requests
-r, --rate unlimited cap request rate (req/s)
-m, --method GET HTTP method
-H, --header 'Name: value', repeatable
-b, --body request body, or @file
-t, --timeout 10 per-request timeout (seconds)
-k, --insecure off skip TLS verification
--fps 30 render frame rate

Reading the scene

You see It means
Yellow streaks crossing fast requests completing quickly
Particles hovering near the wall responses are slow (they stall at ~96% until the response lands)
Green sparks on the wall 2xx
Orange particles bouncing back under gravity 4xx
Red explosions, screen shake, embers on the ground 5xx
Grey smoke rising mid-field timeouts / connection errors
Wall turning from green to red recent error rate climbing

Architecture

            ┌────────────────────────────────────────────────┐
            │                  asyncio loop                  │
            │                                                │
  workers   │  engine.py ──on_start/on_complete──▶ app.py    │
  (aiohttp) │  LoadEngine                          │    │    │
            │   · N workers                        ▼    ▼    │
            │   · token-bucket rate          stats.py  physics.py
            │   · timeout/error taxonomy     RPS, p50  World: particles,
            │                                p95, p99  debris, gravity,
            │                                EMA       embers, shake
            │                                  │         │
            │                                  ▼         ▼
            │                              renderer.py            │
            │                              half-block (▀▄) pixel  │
            │                              framebuffer → one      │
            │                              ANSI write per frame   │
            └────────────────────────────────────────────────┘
  • One process, one event loop. Engine callbacks mutate the world directly — no queues, no threads.
  • The renderer doubles vertical resolution with half-block characters and 24-bit color, composing each frame into a single write.
  • Physics is decoupled from frame rate (dt-based), so it looks right at any --fps and any terminal size, and survives window resizes mid-run.
  • ~1,300 lines of Python, one runtime dependency (aiohttp).

Honest limits

  • Python load generation comfortably drives a few thousand req/s per core. For saturating a 10 Gbps NIC, use wrk/vegeta — for watching and understanding realistic load, use wallop.
  • At high RPS, impact effects are sampled (debris budget) so rendering never lies about your machine's ability to generate load.

Roadmap

  • --replay mode: pipe an access log (or tail -f) in and watch production traffic instead of generated load
  • Per-endpoint lanes when hammering multiple URLs
  • HTTP/2 + WebSocket targets
  • Latency histogram wall: impact height encodes response time
  • A --record flag that writes asciinema casts for sharing

Development

uv sync          # install with dev deps
uv run pytest    # 40 tests covering stats, physics, renderer, engine, CLI

Contributions welcome — see CONTRIBUTING.md.

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

wallop-0.1.0.tar.gz (8.8 MB view details)

Uploaded Source

Built Distribution

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

wallop-0.1.0-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

Details for the file wallop-0.1.0.tar.gz.

File metadata

  • Download URL: wallop-0.1.0.tar.gz
  • Upload date:
  • Size: 8.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for wallop-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4b1d06739d3a08ad8c5ec2dc0ae30944d7d0bb1ce91a4cb5d3b2bc73b05b6a19
MD5 16f47d716e08045780457c5be7227166
BLAKE2b-256 e5454dfda4d2bdb39326389d90d15381e6ee18519fdf6b30f7925b5f94860c1d

See more details on using hashes here.

File details

Details for the file wallop-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: wallop-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for wallop-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a0d8947140d553a5ab2786bcccdde00b5642b99828538794898129ef4fdca394
MD5 d3c39f53564e85d1348427963dd59b7b
BLAKE2b-256 cadf06eb5910d82bfc4caeee67370c5daacdaef8834d9c631402a9ef9b4e011d

See more details on using hashes here.

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