plow Documentation

A high-performance HTTP benchmarking tool that includes a real-time web UI and terminal display

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy plow on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name plow --restart always six-ddc/plow:latest

Technical Documentation: six-ddc/plow

โ„น๏ธ Provenance: In-Tree Documentation (4 Chapters) ยท CodeWiki Reference ยท Recency: Active (< 180 days)

File: README.md

plow




Plow is an HTTP(S) benchmarking tool, written in Golang. It uses
excellent fasthttp instead of Go's default
net/http due to its lightning fast performance.

Plow runs at a specified connections(option -c) concurrently and real-time records a summary statistics, histogram
of execution time and calculates percentiles to display on Web UI and terminal. It can run for a set duration(
option -d), for a fixed number of requests(option -n), or until Ctrl-C interrupted.

The implementation of real-time computing Histograms and Quantiles using stream-based algorithms inspired
by prometheus with low memory and CPU bounds. so it's almost no
additional performance overhead for benchmarking.

text
โฏ ./plow http://127.0.0.1:8080/hello -c 20
Benchmarking http://127.0.0.1:8080/hello using 20 connection(s).
@ Real-time charts is listening on http://[::]:18888

Summary:
  Elapsed        8.6s
  Count        969657
    2xx        776392
    4xx        193265
  RPS      112741.713
  Reads    10.192MB/s
  Writes    6.774MB/s

Statistics    Min       Mean     StdDev      Max
  Latency     32ยตs      176ยตs     37ยตs     1.839ms
  RPS       108558.4  112818.12  2456.63  115949.98

Latency Percentile:
  P50     P75    P90    P95    P99   P99.9  P99.99
  173ยตs  198ยตs  222ยตs  238ยตs  274ยตs  352ยตs  498ยตs

Latency Histogram:
  141ยตs  273028  โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– 
  177ยตs  458955  โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– 
  209ยตs  204717  โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– 
  235ยตs   26146  โ– โ– 
  269ยตs    6029  โ– 
  320ยตs     721
  403ยตs      58
  524ยตs       3

Installation

Binary and image distributions are available through the releases
assets page.

Via Go

bash
go install github.com/six-ddc/plow@latest

Via Homebrew

sh
# brew update
brew install plow

Via Docker

bash
docker run --rm --net=host ghcr.io/six-ddc/plow
# docker run --rm -p 18888:18888 ghcr.io/six-ddc/plow

Usage

Options

bash
usage: plow [<flags>] <url>

A high-performance HTTP benchmarking tool with real-time web UI and terminal displaying

Examples:

  plow http://127.0.0.1:8080/ -c 20 -n 100000
  plow https://httpbin.org/post -c 20 -d 5m --body @file.json -T 'application/json' -m POST

Flags:
      --help                     Show context-sensitive help.
  -c, --concurrency=1            Number of connections to run concurrently
      --rate=infinity            Number of requests per time unit, examples: --rate 50 --rate 10/ms
      --ramp-up=-1               Concurrently will increase pre seconds
  -n, --requests=-1              Number of requests to run
  -d, --duration=DURATION        Duration of test, examples: -d 10s -d 3m
  -i, --interval=200ms           Print snapshot result every interval, use 0 to print once at the end
      --seconds                  Use seconds as time unit to print
      --json                     Print snapshot result as JSON
  -b, --body=BODY                HTTP request body, if body starts with '@' the rest will be considered a file's path from which to read the actual body content
      --stream                   Specify whether to stream file specified by '--body @file' using chunked encoding or to read into memory
  -m, --method="GET"             HTTP method
  -H, --header=K:V ...           Custom HTTP headers
      --host=HOST                Host header
  -T, --content=CONTENT          Content-Type header
      --cert=CERT                Path to the client's TLS Certificate
      --key=KEY                  Path to the client's TLS Certificate Private Key
  -k, --insecure                 Controls whether a client verifies the server's certificate chain and host name
      --listen=":18888"          Listen addr to serve Web UI
      --timeout=DURATION         Timeout for each http request
      --dial-timeout=DURATION    Timeout for dial addr
      --req-timeout=DURATION     Timeout for full request writing
      --resp-timeout=DURATION    Timeout for full response reading
      --socks5=ip:port           Socks5 proxy
      --http-proxy=username:password@ip:port
                                 Set HTTP proxy
      --auto-open-browser        Specify whether auto open browser to show web charts
      --[no-]clean               Clean the histogram bar once its finished. Default is true
      --output-errors=OUTPUT-ERRORS  
                                 Output errors to file
      --summary                  Only print the summary without realtime reports
      --unix-socket=UNIX-SOCKET  Unix domain socket path to use for connection
      --version                  Show application version.

  Flags default values also read from env PLOW_SOME_FLAG, such as PLOW_TIMEOUT=5s equals to --timeout=5s

Args:
  <url>  Request url

Examples

Basic usage:

bash
plow http://127.0.0.1:8080/ -c 20 -n 10000 -d 10s

POST a json file:

bash
plow https://httpbin.org/post -c 20 --body @file.json -T 'application/json' -m POST

Bash/ZSH Shell Completion

bash
# Add the statement to their bash_profile (or equivalent):
eval "$(plow --completion-script-bash)"
# Or for ZSH
eval "$(plow --completion-script-zsh)"

Stargazers

License

See LICENSE.


File: .goreleaser.yaml

project_name: plow
builds:

  • env: [CGO_ENABLED=0]
    goos:
    • linux
    • windows
    • darwin
      goarch:
    • amd64
    • arm64
      dockers:
  • image_templates: ["ghcr.io/six-ddc/plow:{{ .Version }}"]
    dockerfile: Dockerfile
    build_flag_templates:
    • --label=org.opencontainers.image.title={{ .ProjectName }}
    • --label=org.opencontainers.image.description={{ .ProjectName }}
    • --label=org.opencontainers.image.url=https://github.com/six-ddc/plow
    • --label=org.opencontainers.image.source=https://github.com/six-ddc/plow
    • --label=org.opencontainers.image.version={{ .Version }}
    • --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }}
    • --label=org.opencontainers.image.revision={{ .FullCommit }}
    • --label=org.opencontainers.image.licenses=Apache-2.0
  • image_templates: ["ghcr.io/six-ddc/plow"]
    dockerfile: Dockerfile
    build_flag_templates:
    • --label=org.opencontainers.image.title={{ .ProjectName }}
    • --label=org.opencontainers.image.description={{ .ProjectName }}
    • --label=org.opencontainers.image.url=https://github.com/six-ddc/plow
    • --label=org.opencontainers.image.source=https://github.com/six-ddc/plow
    • --label=org.opencontainers.image.version={{ .Version }}
    • --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }}
    • --label=org.opencontainers.image.revision={{ .FullCommit }}
    • --label=org.opencontainers.image.licenses=Apache-2.0
      nfpms:
  • maintainer: six-ddc@github
    homepage: https://github.com/six-ddc/plow
    license: Apache-2.0
    formats:
    • deb
    • rpm
    • apk

File: .github/dependabot.yml

To get started with Dependabot version updates, you'll need to specify which

package ecosystems to update and where the package manifests are located.

Please see the documentation for all configuration options:

https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:

  • package-ecosystem: gomod
    directory: "/"
    schedule:
    interval: weekly

  • package-ecosystem: "github-actions"
    directory: "/"
    schedule:
    interval: weekly


File: .github/workflows/release.yml

name: build

on:
push:
branches:
- 'main'
tags:
- 'v*'
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.23
- name: Cache Go modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
# -
# name: Tests
# run: |
# go mod tidy
# go test -v ./...
- name: Docker Login
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
if: success() && startsWith(github.ref, 'refs/tags/')
with:
version: latest
args: release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

--- METRICS ---