Sign in

    molt

    Simple HTTP load testing CLI built with MoonBit

    load-testing
    http
    benchmark
    Download zip
    Author
    Version
    0.1.8
    License
    Apache-2.0
    Last updated
    6 months ago
    Downloads
    32

    Dependencies

    #molt

    CI codecov License Release Devin Wiki

    Simple HTTP load testing CLI built with MoonBit.

    demo

    A lightweight, fast HTTP load testing tool inspired by oha and hey. Built entirely in MoonBit using the native backend for direct I/O without WASM overhead.

    #Features

    Load Generation
    • Configurable concurrent connections (-c)
    • Duration (-d 30s) or request count (-n 10k) modes
    • Fixed-rate mode with token bucket (--rate)
    • Warm-up phase excluded from stats (--warm-up)
    • Built-in test server (--serve)

    Measurement
    • Gil Tene HDR Histogram (3 significant figures, O(1) per record)
    • TTFB (Time to First Byte) tracked separately
    • Coordinated Omission correction under rate-limited load
    • Custom percentiles (--percentiles 50,90,99,99.99)
    • Response size tracking (bytes/sec)

    HTTP
    • All common methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
    • Custom headers (-H), request body (-b, -B)
    • Basic Auth (--auth), redirect following (-L)
    • Per-request timeout (-t), keep-alive control

    Output
    • Real-time TUI dashboard (default)
    • Plain text with periodic status (--no-tui)
    • JSON with time-series data (--json)
    • Streaming CSV per request (--csv)
    • Debug mode: single request dump (--debug)

    CI/CD
    • SLA thresholds with exit codes (--latency-threshold, --error-threshold)
    • Exit 0 (success), 1 (config error), 2 (test failures), 3 (threshold violation)
    • Automated releases via release-please

    #Installation

    #Pre-built binary

    Download from GitHub Releases:

    # macOS (Apple Silicon) curl -sL https://github.com/paveg/molt/releases/latest/download/molt-darwin-arm64.tar.gz | tar xz sudo mv molt /usr/local/bin/ # Linux (x86_64) curl -sL https://github.com/paveg/molt/releases/latest/download/molt-linux-amd64.tar.gz | tar xz sudo mv molt /usr/local/bin/

    #Build from source

    Requires MoonBit toolchain.

    git clone https://github.com/paveg/molt.git && cd molt moon build --target native --release cp _build/native/release/build/src/cmd/main/main.exe /usr/local/bin/molt

    #Quick Start

    # Start the built-in test server molt --serve 127.0.0.1:8080 & # Run a load test against it molt -c 10 -d 5s http://127.0.0.1:8080/ # Or test against your own server molt -c 50 -d 30s http://localhost:3000/api/health

    #AI Agent Integration

    molt is available as a Vercel Skill — AI coding agents (Claude Code, Copilot, Cursor, etc.) can learn to use molt for load testing.

    # Install the molt skill for your agent npx skills add paveg/molt

    Once installed, you can ask your AI agent things like:
    • "Load test this API endpoint at 100 RPS for 30 seconds"
    • "Run a quick smoke test on localhost:3000"
    • "Benchmark the /api/users endpoint with POST requests"

    The agent will construct and run molt commands, then analyze the results.

    #Usage Examples

    # Basic GET (50 connections, 10 seconds) molt http://localhost:8080/ # POST with JSON body molt -m POST -H 'Content-Type: application/json' \ -b '{"name":"test"}' -c 20 -d 15s http://localhost:8080/api/users # Fixed rate: 500 RPS molt -r 500 -c 50 -d 30s http://localhost:8080/ # Request count with suffix molt -n 10k -c 50 http://localhost:8080/ # SLA enforcement in CI molt --latency-threshold 100ms --error-threshold 1.0 \ -c 50 -d 30s http://localhost:8080/api/health # JSON output for pipelines molt --json -d 10s http://localhost:8080/ > results.json # Warm-up: skip first 5 seconds molt --warm-up 5s -c 20 -d 30s http://localhost:8080/ # Basic auth + custom timeout molt --auth admin:secret -t 5s -c 10 -d 10s http://localhost:8080/api/protected # Debug: inspect single request molt --debug http://localhost:8080/api/health

    #Sample Output

    #Text mode (--no-tui)

    molt v0.1.0 -- MoonBit HTTP Load Tester Target: http://127.0.0.1:9998/ Method: Get Connections: 5 Duration: 3s Running... [0.9s] 20118 requests | 20118 req/s | p50: 0.19ms | p99: 1.05ms | errors: 0 [1.9s] 40996 requests | 20498 req/s | p50: 0.18ms | p99: 1.16ms | errors: 0 Summary: Total requests: 57727 Successful: 57727 (100.0%) Failed: 0 (0.0%) Total time: 3.0s Requests/sec: 19240.57 Latency Distribution: p50.00 0.20ms p90.00 0.39ms p75.00 0.30ms p95.00 0.48ms p99.00 1.21ms p99.90 4.35ms max 12.56ms mean 0.25ms stdev 0.31ms TTFB (Time to First Byte): p50 0.19ms p99 1.20ms max 12.56ms Status Codes: 200: 57727

    #JSON mode (--json)

    { "config": { "url": "http://127.0.0.1:9998/", "connections": 2, "duration_sec": 1.00, "rate_rps": null, "timeout_ms": 30000, "method": "GET" }, "summary": { "total_requests": 19155, "successful": 19155, "failed": 0, "total_time_sec": 1.00, "requests_per_sec": 19162.76 }, "latency": { "p50_ms": 0.09, "p75_ms": 0.10, "p90_ms": 0.13, "p95_ms": 0.18, "p99_ms": 0.31, "p99_9_ms": 0.77, "max_ms": 2.05, "min_ms": 0.06, "mean_ms": 0.10, "stdev_ms": 0.06 }, "ttfb": { "p50_ms": 0.09, "p99_ms": 0.30, "max_ms": 2.04 }, "status_codes": { "200": 19155 }, "errors": {}, "custom_percentiles": { "p50.00_ms": 0.09, "p99.00_ms": 0.31 }, "throughput": { "total_bytes": 0, "bytes_per_sec": 0.00 }, "time_series": [ { "elapsed_sec": 1.0, "requests": 19155, "rps": 19155.0, "p50_us": 91, "p99_us": 311, "errors": 0 } ] }

    #CLI Reference

    Usage: molt [options] <url>

    OptionShortDefaultDescription
    Load Control
    --connections-c50Concurrent connections
    --duration-d10sTest duration (10s, 1m, 1m30s)
    --requests-n--Total request count, supports 10k/1m suffixes
    --rate-r--Target requests per second
    --warm-up--Exclude initial period from stats (3s)
    HTTP
    --method-mGETHTTP method
    --header-H--Custom header, repeatable
    --body-b--Request body string
    --body-file-B--Request body from file
    --auth--Basic auth (user:password)
    --timeout-t30sPer-request timeout
    --redirect-LoffFollow 3xx redirects (up to 10 hops)
    --disable-keepaliveoffNew connection per request
    --insecure-koffSkip TLS verification (pending upstream)
    Output
    --no-tuioffPlain text with periodic status
    --json-joffJSON output (implies --no-tui)
    --csvoffStreaming per-request CSV
    --percentiles50,75,90,95,99,99.9Custom percentiles
    CI/CD
    --latency-threshold--Fail if p99 exceeds value (100ms), exit 3
    --error-threshold--Fail if error rate exceeds % (1.0), exit 3
    Other
    --debugoffSingle request with full response dump
    --serve--Start built-in test server (127.0.0.1:8080)

    #Architecture

    graph TD CLI["CLI Parser<br/>(argparse)"] -->|Config| COORD["Coordinator<br/>(TaskGroup)"] COORD --> W1["Worker 1<br/>HTTP Client"] COORD --> W2["Worker 2<br/>HTTP Client"] COORD --> WN["Worker N<br/>HTTP Client"] COORD -->|optional| RL["Rate Limiter<br/>(Token Bucket)"] RL -.->|acquire| W1 RL -.->|acquire| W2 RL -.->|acquire| WN W1 -->|RequestResult| COLL["Collector<br/>(HDR Histogram)"] W2 -->|RequestResult| COLL WN -->|RequestResult| COLL COLL -->|live stats| TUI["TUI / Plain"] COLL -->|Stats| REP["Reporter<br/>(text / JSON / CSV)"] COLL -->|Stats| THR["Threshold<br/>Check"]

    #Packages

    PackageDescription
    cmd/mainCLI parsing (cli.mbt) and orchestration (main.mbt)
    lib/typesConfig, Stats, RequestResult, HttpMethod, base64_encode
    lib/workerAsync HTTP loop, TTFB, redirect, reconnection
    lib/coordinatorTaskGroup orchestration, warm-up, time-series capture
    lib/collectorResult aggregation with dual HDR Histogram (latency + TTFB)
    lib/histogramGil Tene HDR Histogram (3 sig fig, 1us-1h, O(1) record)
    lib/reporterText (text.mbt), JSON (json.mbt), CSV (csv.mbt), format helpers
    lib/tuiReal-time TUI via mizchi/tui
    lib/durationDuration/count parser ("10s", "1m30s", "10k")
    lib/rate_limiterAbsolute-deadline token bucket
    lib/thresholdSLA threshold checking

    #Development

    moon build --target native # build moon build --target native --release # release build (~2.3 MB) moon test --target native # all 241 tests moon test # wasm-gc subset moon fmt # format moon check --target native # type check

    #Comparison

    moltohaheyk6
    LanguageMoonBitRustGoGo
    HDR HistogramYes (3 sig fig)YesNoYes
    TUIYesYesNoNo
    TTFBYesYesNoNo
    CO correctionYesYesNoYes
    SLA thresholdsYes (exit 3)PartialNoYes
    CSVYes (streaming)YesYesNo
    HTTP/2No (planned)Yes (+HTTP/3)YesYes
    ScenariosNoNoNoYes (JS)
    Binary~2.3 MB~3 MB~5 MB~40 MB

    #Roadmap

    #License