cryload
cryload - HTTP load testing for CI/CD
Cross-platform, single-binary HTTP load testing CLI. A modern alternative to ab / wrk / hey, written in Crystal.
Quick start
curl -sSfL https://raw.githubusercontent.com/sdogruyol/cryload/master/scripts/install.sh | sh
cryload https://example.com -n 1000 -c 50
1000 requests, 50 concurrent connections, JSON/CSV/plain output. That's it.
Why cryload?
Existing tools work fine on your laptop. cryload is built for the one place that matters most: CI/CD pipelines.
| Problem | Solution | |---------|----------| | "Did my deploy break performance?" | Set latency thresholds that fail your build | | "Where do I put the results?" | JSON and CSV output, ready to parse | | "Different OS in CI vs local?" | Single binary for Linux, macOS, Windows | | "Which tool works in all three?" | cryload does |
If you need a graph on your laptop, use wrk. If you need to fail a pipeline when p99 goes over 200ms, use cryload.
Features
- ⚡ Concurrent load with configurable connection count
- ⏱️ Duration or request count mode
- 📊 Latency percentiles: p50, p75, p90, p95, p99, p999 + histogram
- 🎯 CI thresholds:
--max-p99,--max-fail-rate,--fail-on-error - 📦 JSON / CSV / quiet output for pipelines
- 🔒 Rate limiting, warmup, keep-alive, TLS skip
- 🌐 Multi-URL, redirects, custom success codes
- 🖥️ Cross-platform: Linux, macOS, Windows - single binary
Performance
cryload is fast. Written in Crystal and compiled to native code.
| Test | Results | |------|---------| | Localhost (100 conn, 10s) | ~50,000 req/sec, p99 < 1ms | | Local nginx (100 conn, 10s) | ~12,000 req/sec, p99 < 3ms | | Remote API (50 conn, 30s) | ~2,000 req/sec, p99 < 80ms | | Binary size | ~3 MB (single file, no dependencies) | | Memory per 10K requests | ~15 MB |
No JVM, no Node. Just a single binary that starts instantly and uses almost no memory.
Installation
Option 1: Install script (recommended)
Linux / macOS:
curl -sSfL https://raw.githubusercontent.com/sdogruyol/cryload/master/scripts/install.sh | sh -s
Windows (PowerShell):
iwr -useb https://raw.githubusercontent.com/sdogruyol/cryload/master/scripts/install.ps1 | iex
Option 2: Prebuilt binary
Download from Releases:
chmod +x cryload-linux
./cryload-linux --help
Option 3: Docker
docker run --rm ghcr.io/sdogruyol/cryload https://example.com -n 1000 -c 50
Multi-arch (amd64/arm64) image, ~9 MB. Use --network host on Linux to reach services on the host's localhost. Tags follow the release version without the v prefix: 5.2.0, 5.2, 5, latest.
Option 4: GitHub Action
- uses: sdogruyol/cryload@v5
with:
url: http://127.0.0.1:3000/api
requests: 500
max_p99: "250"
See docs/github-action.md for all inputs and outputs.
Option 5: Build from source
Requires Crystal >= 1.19.0.
git clone https://github.com/sdogruyol/cryload.git && cd cryload
shards build --release
Usage
cryload <url> [options]
| Option | Description |
|--------|-------------|
| -n, --numbers | Number of requests |
| -d, --duration | Test duration in seconds |
| -c, --connections | Concurrent connections (default: 10) |
| -m, --method | HTTP method (default: GET) |
| -b, --body | Request body |
| --body-file | Read body from file |
| --body-stdin | Read body from stdin |
| -H, --header | Repeatable header (-H "Key: Value") |
| -a, --basic-auth | Basic auth (user:password) |
| --timeout | Connect/read timeout in seconds |
| -q, --rate | Rate limit (req/sec) |
| -L, --follow-redirects | Follow redirects |
| --output-format | text, json, csv, quiet |
| --success-status | Custom success codes/ranges |
| --insecure | Skip TLS verification |
| --warmup | Warmup seconds before benchmark |
| --proxy | HTTP(S) proxy |
| --cookie | Repeatable cookie (name=value) |
| --urls-file | Load target URLs from file |
| --random-path | Append random path per request |
Common examples
# 10K requests, 100 concurrent
cryload http://localhost:3000 -n 10000 -c 100
# 30 seconds, 50 connections
cryload http://localhost:3000 -d 30 -c 50
# POST with JSON body
cryload http://localhost:3000/api -n 500 -m POST \
-H "Content-Type: application/json" \
-b '{"name":"cry"}' --timeout 5
See docs/examples.md for more.
CI/CD
cryload is built for pipelines. Use --json or --output-format csv for structured output, --output-format quiet for exit-code-only checks.
| Flag | Effect |
|------|--------|
| --fail-on-error | Exit 1 on any HTTP/transport error |
| --max-fail-rate 5 | Exit 1 if failure rate > 5% |
| --max-p99 200 | Exit 1 if p99 > 200 ms |
GitHub Actions example
Use the official action — it installs cryload, runs the benchmark, and exposes the JSON results as step outputs:
- name: Latency SLA
id: bench
uses: sdogruyol/cryload@v5
with:
url: http://localhost:3000/api
requests: 500
max_p99: "250"
- name: Show p99
if: always()
run: echo "p99 was ${{ steps.bench.outputs.p99 }} ms"
See docs/github-action.md for all inputs and outputs. Or install the binary directly:
- name: Install cryload
run: curl -sSfL https://raw.githubusercontent.com/sdogruyol/cryload/master/scripts/install.sh | sh -s
- name: Latency SLA
run: |
cryload http://localhost:3000/api -n 500 --max-p99 250 --json > result.json
jq -e '.latency_ms.p99 <= 250' result.json
How cryload compares
| Feature | cryload | ab | hey | wrk |
|---------|:-------:|:--:|:---:|:---:|
| CI/CD output (JSON/CSV/quiet) | ✅ | - | JSON | - |
| CI threshold exit codes | ✅ | - | - | - |
| Rate limiting (--rate) | ✅ | - | partial | - |
| Cross-platform binary | ✅ | Linux | ✅ | Linux |
Built with Crystal
cryload is written in Crystal. Ruby-like syntax, compiled speed, single-binary deployment.
FAQ
Why not just use ab / hey / wrk?
Those tools are great for local benchmarks. cryload is built for CI/CD. JSON output, threshold exit codes, cross-platform binaries. If you want to fail a pipeline when p99 goes over 200ms, use cryload.
Can I use cryload for DDoS?
No. cryload is designed for testing your own servers and CI pipelines. Do not use it against targets you don't own.
Does cryload support HTTP/2?
Not yet. HTTP/1.1 only for now. HTTP/2 is on the roadmap.
Is there a Docker image?
Yes: docker pull ghcr.io/sdogruyol/cryload. The single binary is still the lightest option, but the image is handy for containerized pipelines (GitLab CI, Kubernetes jobs, etc.).
Why is it written in Crystal?
Crystal compiles to a single native binary with no runtime. It starts instantly, uses minimal memory, and delivers C-like performance with Ruby-like syntax.
Sponsors
If cryload helps your CI pipeline, consider sponsoring. Every dollar helps me keep building open source tools full time.
License
MIT