> ## Documentation Index
> Fetch the complete documentation index at: https://hitspec.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Stress Testing

> Load test your APIs with configurable rate, virtual users, ramp-up phases, and pass/fail thresholds.

hitspec includes a built-in stress testing engine. You do not need a separate tool -- the same `.http` files you use for functional tests can drive load tests. This tutorial covers rate-based testing, virtual user mode, multi-phase profiles, and threshold-based pass/fail.

## Prerequisites

* hitspec installed ([Installation](/installation))
* A test file to stress test (see [Basic CRUD](/examples/basic-crud))

## Quick Start

The simplest way to stress test is with CLI flags:

```bash theme={null}
hitspec run api.http --stress --duration 30s --rate 10
```

This sends 10 requests per second for 30 seconds against the requests defined in `api.http`.

<Steps>
  <Step title="Create a test file for stress testing">
    Create `stress.http` with a simple request:

    ```http stress.http theme={null}
    @baseUrl = https://httpbin.org

    ### Health check
    # @name healthCheck
    # @tags smoke

    GET {{baseUrl}}/get

    >>>
    expect status 200
    expect duration < 2000
    <<<

    ### Create item
    # @name createItem
    # @tags write

    POST {{baseUrl}}/post
    Content-Type: application/json

    {
      "name": "Load test item",
      "timestamp": "{{$timestamp()}}"
    }

    >>>
    expect status 200
    <<<
    ```

    <Tip>
      Use `{{$timestamp()}}` or `{{$uuid()}}` to generate unique values on every request. This avoids caching effects and simulates realistic traffic.
    </Tip>
  </Step>

  <Step title="Run a rate-based stress test">
    Rate mode sends a fixed number of requests per second:

    ```bash theme={null}
    hitspec run stress.http --stress --duration 1m --rate 20
    ```

    This runs for 1 minute at 20 requests per second. hitspec distributes the load across all requests in the file.

    Output:

    ```
    Stress test: rate=20 rps, duration=1m0s

      Requests:  1200 total, 1195 passed, 5 failed
      Duration:  1m0.2s
      RPS:       19.92 avg

      Latency:
        p50:   45ms
        p95:   123ms
        p99:   287ms
        max:   412ms

      Error Rate: 0.42%
    ```
  </Step>

  <Step title="Run a virtual user stress test">
    VU mode simulates concurrent users, each sending requests sequentially:

    ```bash theme={null}
    hitspec run stress.http --stress --duration 1m --vus 10 --think-time 500ms
    ```

    This creates 10 virtual users, each waiting 500ms between requests. Unlike rate mode, VU mode models real user behavior where each user completes a request before starting the next.
  </Step>

  <Step title="Add ramp-up">
    Ramp up gradually to avoid overwhelming the server at startup:

    ```bash theme={null}
    hitspec run stress.http --stress --duration 2m --rate 50 --ramp-up 30s
    ```

    The rate increases linearly from 0 to 50 rps over the first 30 seconds, then holds at 50 for the remaining 90 seconds.
  </Step>

  <Step title="Set pass/fail thresholds">
    Thresholds let you define success criteria. The test exits with code 1 if any threshold is violated:

    ```bash theme={null}
    hitspec run stress.http --stress --duration 1m --rate 20 \
      --threshold "p95<200ms,errors<1%,rps>15"
    ```

    Available threshold metrics:

    | Metric   | Operator  | Example     | Description                 |
    | -------- | --------- | ----------- | --------------------------- |
    | `p50`    | `<`, `<=` | `p50<100ms` | 50th percentile latency     |
    | `p95`    | `<`, `<=` | `p95<200ms` | 95th percentile latency     |
    | `p99`    | `<`, `<=` | `p99<500ms` | 99th percentile latency     |
    | `max`    | `<`, `<=` | `max<1s`    | Maximum latency             |
    | `errors` | `<`, `<=` | `errors<1%` | Error rate percentage       |
    | `rps`    | `>`, `>=` | `rps>50`    | Minimum requests per second |

    Combine multiple thresholds with commas.
  </Step>
</Steps>

## Configuration File

For repeatable stress test configurations, define profiles in `hitspec.yaml`.

### Rate-based Profile

```yaml hitspec.yaml theme={null}
stress:
  profiles:
    smoke:
      duration: 30s
      rate: 5
      thresholds:
        p95: "500ms"
        errors: "0%"

    load:
      duration: 5m
      rate: 50
      rampUp: 1m
      maxVUs: 200
      thresholds:
        p95: "200ms"
        p99: "500ms"
        errors: "1%"
        rps: "45"

    spike:
      duration: 2m
      rate: 200
      rampUp: 10s
      maxVUs: 500
      thresholds:
        p99: "1s"
        errors: "5%"
```

Run a specific profile:

```bash theme={null}
hitspec run stress.http --stress --profile load
```

### Virtual User Profile

```yaml hitspec.yaml theme={null}
stress:
  profiles:
    realistic:
      duration: 10m
      vus: 50
      thinkTime: 1s
      rampUp: 2m
      maxVUs: 100
      thresholds:
        p95: "300ms"
        errors: "0.5%"
```

VU mode is better for simulating real user behavior, where each user thinks between requests. Rate mode is better for measuring raw throughput.

## Profile Strategies

### Smoke Test

Verify the system handles minimal load without errors. Run this on every deploy.

```yaml theme={null}
smoke:
  duration: 30s
  rate: 5
  thresholds:
    errors: "0%"
    p95: "500ms"
```

### Load Test

Sustained normal traffic levels. Verify performance under expected conditions.

```yaml theme={null}
load:
  duration: 10m
  rate: 100
  rampUp: 2m
  thresholds:
    p95: "200ms"
    p99: "500ms"
    errors: "0.5%"
```

### Stress Test

Push beyond normal limits to find the breaking point.

```yaml theme={null}
stress:
  duration: 5m
  rate: 500
  rampUp: 1m
  maxVUs: 1000
  thresholds:
    errors: "5%"
```

### Spike Test

Sudden traffic surge to test auto-scaling and recovery.

```yaml theme={null}
spike:
  duration: 3m
  rate: 1000
  rampUp: 5s
  thresholds:
    p99: "2s"
    errors: "10%"
```

## Per-Request Configuration

You can control how individual requests participate in stress tests using metadata:

```http theme={null}
### Setup: create test data
# @name setup
# @stress.setup true

POST {{baseUrl}}/test-data
Content-Type: application/json

{"name": "stress test fixture"}

>>>
expect status 201
<<<

### Main endpoint under test
# @name getItems
# @stress.weight 3

GET {{baseUrl}}/items

>>>
expect status 200
expect duration < 500
<<<

### Secondary endpoint
# @name getItem
# @stress.weight 1

GET {{baseUrl}}/items/1

>>>
expect status 200
<<<

### Teardown: clean up
# @name teardown
# @stress.teardown true

DELETE {{baseUrl}}/test-data

>>>
expect status 200
<<<
```

| Directive          | Description                                                           |
| ------------------ | --------------------------------------------------------------------- |
| `@stress.weight N` | Relative frequency (default 1). A weight of 3 means 3x more requests. |
| `@stress.think N`  | Think time in ms after this request (VU mode).                        |
| `@stress.skip`     | Exclude this request from stress testing.                             |
| `@stress.setup`    | Run once before the stress test starts.                               |
| `@stress.teardown` | Run once after the stress test ends.                                  |

## Stress Testing in CI

Combine stress profiles with the GitHub Action for automated performance gates:

```yaml .github/workflows/stress.yml theme={null}
name: Stress Tests

on:
  push:
    branches: [main]

jobs:
  stress:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Smoke load test
        uses: abdul-hamid-achik/hitspec@v1
        with:
          files: tests/api.http
          stress: true
          duration: 1m
          rate: 10
          threshold: "p95<500ms,errors<0.5%"
```

See the [CI/CD example](/examples/ci-cd) for complete workflow patterns.

## Reading the Output

A stress test run produces a summary like this:

```
Stress test: rate=50 rps, duration=2m0s, rampUp=30s

  Requests:  5847 total, 5812 passed, 35 failed
  Duration:  2m0.1s
  RPS:       48.72 avg

  Latency:
    p50:   32ms
    p95:   156ms
    p99:   342ms
    max:   891ms

  Error Rate: 0.60%

  Thresholds:
    p95 < 200ms .... PASS (156ms)
    p99 < 500ms .... PASS (342ms)
    errors < 1% .... PASS (0.60%)
    rps > 40 ....... PASS (48.72)

4/4 thresholds passed
```

If any threshold fails, the exit code is 1 and the failing threshold is marked:

```
  Thresholds:
    p95 < 200ms .... FAIL (267ms)
    errors < 1% .... PASS (0.60%)

1/2 thresholds passed
```

## Next Steps

<Columns cols={2}>
  <Card title="Stress Testing Reference" icon="bolt" href="/features/stress-testing">
    Full reference for all stress testing options.
  </Card>

  <Card title="CI/CD Integration" icon="circle-check" href="/examples/ci-cd">
    Run stress tests in your CI pipeline.
  </Card>
</Columns>
