Warning
Work In Progress (WIP): Gork is currently under active development and is not yet ready for production environments. APIs, configuration, and structures are subject to breaking changes.
Contractual design, functionality, and security parameters are documented in the local openspec directory:
- Functional Specs
- Architecture Details
- Security Profile
When working with AI coding agents:
- Agents consult the root
AGENTS.mdfile for global workspace design constraints. - Specifications must be updated in
openspec/prior to any code modifications. - Local capabilities, agent commands, or custom workspace settings must remain in the private root
.agents/folder and never leak into this public submodule repository.
Gork is an asynchronous, high-performance HTTP web benchmarking tool written in Go.
The extreme speed and throughput of Gork are primarily driven by the event-driven, non-blocking gnet/v2 networking engine.
Unlike Go's standard netpoll scheduler (which allocates one goroutine per connection, causing high thread-context switching and stack memory overhead under massive concurrency), gnet utilizes a clean, loop-multiplexed epoll/kqueue network model (inspired by Netty and libuv). It processes millions of concurrent network events on a small, pinned OS thread pool, acting as the foundational backbone for Gork's high-concurrency capability.
The htparser package is a custom Go translation of the classic Joyent C http_parser state machine (originally copied by Joyent from the Nginx HTTP parser and used extensively by the popular wrk benchmarking tool).
While modern Node.js has moved to a parser generator (llhttp), Gork relies on this classic, ultra-robust C state machine. Optimized with a zero-heap-allocation memory architecture, it copies header and status tokens directly into a recycled bytebufferpool buffer, keeping the hot I/O path completely GC-allocation-free.
-
Event-Driven Non-Blocking I/O: Leverages
gnet/v2multicore loop multiplexing, handling massive connection counts with a constant thread footprint. - Classic C State Machine Parser: Translates the Nginx/wrk HTTP state machine to Go, ensuring standard compliance and parsing resilience.
-
Lock-Free Telemetry: Updates success/failure counters and throughput atomically (
sync/atomic) without mutex contention. -
$O(1)$ Space Latency Histogram: Maps durational latencies directly into 2000 linear buckets of 100 microseconds (0 to 200ms range) to calculate precise percentiles (P50, P90, P99) and mean latencies with zero allocations. -
HTTP/1.0 Connection Close & Keep-Alive Support: Gracefully tracks
Connection: closeheaders and automatically handles standard HTTP/1.0 response streams by closing and redialing sockets asynchronously to maintain target concurrency.
Ensure you have Go 1.26.3+ installed.
# Clone the repository
# (Follow standard git clone instructions)
# Clean and build the binary via Makefile
make build
# Run the unit tests to verify the parser
make testGork targets are fully automated using the Makefile during development:
# Format source files
make fmt
# Clean dependencies
make tidy
# Run a quick local benchmark test (10 concurrent connections for 3 seconds)
make run
# Clean build outputs
make cleanFor advanced runs, build the binary and execute it specifying your parameters:
./gork -url http://localhost/pixel.gif -c 100 -d 5s| Flag | Default | Description |
|---|---|---|
-url |
http://localhost:80/pixel.gif |
The target HTTP URL to benchmark. |
-c |
10 |
Concurrency level (number of active concurrent TCP connections to maintain). |
-n |
0 |
Total number of requests to complete. If set to 0, execution is bound only by the duration limit. |
-d |
10s |
Duration of the benchmark (e.g., 10s, 1m, 500ms). |
Both stop criteria (-n and -d) are supported. The benchmark will terminate as soon as either condition is met.
Each active socket maintains a persistent connContext that wraps:
- A
buf []byteslice that dynamically accumulates fragmented TCP packets. - An instance of
htparser.Parserrecycled viaReset(). - Flag states
headerParsedandbodyOffsetthat isolate header parsing from body streaming, completely eliminating re-parsing overhead when response payloads arrive in chunks.
All request counters, throughput sizes, and latency boundaries (minLatency and maxLatency) are updated concurrently by event loop goroutines using atomic lock-free CAS (Compare-And-Swap) loops, preventing execution bottlenecks across CPU cores.
Latencies are mapped directly to histogram buckets in constant time:
This project is distributed under the Apache License 2.0 - see the LICENSE file for full redistribution, patent grant, and liability details.