Nothing has been indexed for 0.2.0 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.

Installation

# Add this to your shard.yml
dependencies:
  cryload:
    github: sdogruyol/cryload
    version: ~> 0.2.0

Then run:

shards install

shard.yml

No shard.yml has been indexed for 0.2.0. You can read it on the repository.

Dependencies

Unknown: the shard.yml for this version has not been read yet.

README

This README is the one indexed from the repository at its latest ref, not from the tag for this version.

<p align="left">
  <img src="assets/logo.png" alt="cryload logo" width="180">
</p>

# 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.

[![Stars](https://img.shields.io/github/stars/sdogruyol/cryload?style=flat-square&label=%20&color=gold)](https://github.com/sdogruyol/cryload)
[![CI](https://img.shields.io/github/actions/workflow/status/sdogruyol/cryload/ci.yml?style=flat-square)](https://github.com/sdogruyol/cryload/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/sdogruyol/cryload?style=flat-square)](https://github.com/sdogruyol/cryload/releases)
[![Downloads](https://img.shields.io/github/downloads/sdogruyol/cryload/total?style=flat-square)](https://github.com/sdogruyol/cryload/releases)
![Crystal](https://img.shields.io/badge/Crystal-1.19+-%23000?style=flat-square&logo=crystal)
[![License](https://img.shields.io/github/license/sdogruyol/cryload?style=flat-square)](LICENSE)

---

## Quick start

```bash
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.

<p align="center">
  <img src="assets/cryload.png" alt="cryload demo" width="700">
</p>

---

## 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:**
```bash
curl -sSfL https://raw.githubusercontent.com/sdogruyol/cryload/master/scripts/install.sh | sh -s
```

**Windows (PowerShell):**
```powershell
iwr -useb https://raw.githubusercontent.com/sdogruyol/cryload/master/scripts/install.ps1 | iex
```

### Option 2: Prebuilt binary

Download from [Releases](https://github.com/sdogruyol/cryload/releases):
```bash
chmod +x cryload-linux
./cryload-linux --help
```

### Option 3: Docker

```bash
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.1`, `5.2`, `5`, `latest`.

### Option 4: GitHub Action

```yaml
- uses: sdogruyol/cryload@v5
  with:
    url: http://127.0.0.1:3000/api
    requests: 500
    max_p99: "250"
```

See [docs/github-action.md](docs/github-action.md) for all inputs and outputs.

### Option 5: Build from source

Requires Crystal >= 1.19.0.
```bash
git clone https://github.com/sdogruyol/cryload.git && cd cryload
shards build --release
```

---

## Usage

```bash
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

```bash
# 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](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:

```yaml
- 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](docs/github-action.md) for all inputs and outputs. Or install the binary directly:

```yaml
- 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](https://crystal-lang.org/). Ruby-like syntax, compiled speed, single-binary deployment.

![Crystal](https://img.shields.io/badge/Built%20with-Crystal-776791?style=flat-square&logo=crystal)

---

## 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](https://github.com/sponsors/sdogruyol). Every dollar helps me keep building open source tools full time.

[![Sponsor](https://img.shields.io/badge/Sponsor-30363D?style=flat-square&logo=githubsponsors&logoColor=white)](https://github.com/sponsors/sdogruyol)

---

## License

MIT