surgesurge

What surge is

A load tester in one static Go binary. You describe who your users are — roles, weighted tasks, a login, think time — as YAML or as a Go program, and surge answers the questions a load test is usually run to answer and usually cannot:

The shape of it

bash
surge init my.yaml            # a commented starter
surge validate my.yaml        # the file
surge preflight my.yaml       # the world: DNS, TLS, data, monitors, this machine
surge verify my.yaml          # one real pass of every role
surge run my.yaml -html report.html

A scenario is a file:

yaml
name: checkout
type: load
base_url: https://staging.example.com

load: { vus: 200, duration: 5m, warmup: 30s }

users:
  - name: shopper
    weight: 7
    wait: 2s..8s
    flow:
      - { name: api/items, get: /api/items }
      - { name: api/cart,  post: /api/cart }

thresholds:
  - "p95 < 500ms"
  - "error_rate < 1%"

Or a program, when the thing under test is not HTTP — gRPC, SQL, a queue, a vendor SDK. See the Go library.

What makes it different

It states a verdict and then its reasons. Not a colour: which threshold broke and by how much, how many requests failed, how many checks — and underneath, the caveats that decide whether the run is worth anything at all. A generator that ran out of CPU, arrivals that were never applied, a feeder too small for the load. A confident reading of a bad run is worse than no reading.

Percentiles that are percentiles. Log-linear histograms at about 3% error, merged bucket-wise across machines. Two nodes' p99 is the p99 and never the average of two of them.

Failures keep their evidence. Each distinct failure holds one real example: the role, the URL, the status, which checks gave way and the first 512 bytes the server replied. That is what catches a checkout answering 200 with "status":"pending" — invisible to an error rate, and the expensive one.

It knows what kind of test this is. smoke, load, stress, spike, soak or capacity. It changes nothing about the traffic and everything about how the result should be read, and surge adds a caveat when the thresholds do not suit the kind: a soak judged on a whole-run p95 passes while the service leaks.

One user action, not three calls. A checkout that is three API calls is one thing the user did, and "checkout under a second" is the sentence the SLA is written in. Group them and surge times the journey end to end, keeps it out of the totals so the throughput stays right, and lets a threshold name it.

It checks before it spends an hour. surge preflight is one request per target, monitor and agent, ending in GO or NO-GO: does the name resolve, is the certificate about to expire, is "staging" actually this laptop, are there enough rows in the CSV.

Where to go next

You want toRead
run something in the next five minutesGetting started
get the binaryInstalling surge
write a scenarioScenario reference
test something that is not HTTPRecipes · the Go library
know every flagCommand reference
read the outputReading the report
run it from a pipelineRunning in CI
find the ceilingFinding capacity
stop regressionsCatching regressions
run across machinesAcross several machines
drive it from Claude CodeThe plugin
see everything it doesFeature map