Overview
A minimal wrk clone written in Go for learning purposes. This is a simple HTTP load testing tool that demonstrates concurrent programming and performance measurement. The tool sends concurrent HTTP requests to a target URL and provides detailed statistics about latency, throughput, and success rates.
Technology Stack
- Language: Go
-
Key Libraries:
net/http,flag,sync,time - Tools: Command-line interface
Learning Goals
What I aimed to learn from this project:
- Go goroutines and channels for concurrent programming
- Semaphore pattern for controlling concurrency
- HTTP client configuration and timeout handling
- Performance measurement and statistics collection
- Command-line interface design with flag parsing
Key Features
- HTTP load testing with configurable concurrency
- Configurable request count and timeout
- Real-time statistics (latency, throughput, success/failure rates)
- Simple command-line interface
- Safe concurrency with semaphore pattern
Technical Challenges & Solutions
Challenge 1: Managing concurrent requests safely
Problem: Needed to control the number of concurrent HTTP requests to avoid overwhelming the system and the target server.
Solution: Implemented a semaphore pattern using buffered channels. Created a worker pool that limits concurrent goroutines by passing "tokens" through a channel. This ensures exactly the specified number of requests run concurrently.
Challenge 2: Accurate timing measurements
Problem: Needed to measure individual request latencies while also calculating overall throughput.
Solution: Used time.Now() before each HTTP request and calculated duration after completion. For overall throughput, measured total time from start to finish and divided by completed requests.
Challenge 3: Proper resource cleanup
Problem: HTTP response bodies needed to be closed to prevent memory leaks, especially with many concurrent requests.
Solution: Used defer resp.Body.Close() immediately after checking for errors to ensure resources are always cleaned up, even if panics occur.
Code Architecture
The project follows a clean separation of concerns:
- main.go: Entry point, argument parsing, and result reporting
- cli.go: Command-line flag definitions and parsing logic
- worker.go: Core concurrent execution logic using semaphore pattern
- stats.go: Statistical calculations and result aggregation
Key design patterns:
- Semaphore Pattern: Buffered channel controls concurrent access
- Worker Pool: Goroutines execute tasks from a shared channel
- Sync.WaitGroup: Ensures all goroutines complete before exiting
Installation & Usage
# Clone and build
git clone https://github.com/Azizham66/loadtest.git
cd loadtest
go build -o loadtest .
# Basic usage
./loadtest -url=https://example.com -requests=100
# High concurrency test
./loadtest -url=https://api.example.com -requests=1000 -concurrency=50
# Custom timeout
./loadtest -url=https://slow-server.com -requests=500 -timeout=10
Options
-
-url string: URL to stress test (required) -
-requests int: Number of requests to send (default: 10) -
-concurrency int: Number of concurrent requests (default: 10) -
-timeout int: Timeout in seconds (default: 5)
What I Learned
Technical Skills
- Go Concurrency: Basic understanding of goroutines, channels, and select statements
- Semaphore Pattern: How to implement resource limiting using buffered channels
- HTTP Client Configuration: Custom timeouts and connection management in Go
- Performance Measurement: Accurate timing and statistical calculations
- CLI Development: Flag parsing and user-friendly command-line interfaces
Concepts & Patterns
- Concurrent Programming: Safe coordination between multiple goroutines
- Resource Management: Proper cleanup in concurrent environments
- Error Handling: Graceful failure handling in distributed systems
- Statistics: Latency distribution and throughput calculations
Areas of Improvement
-
Better Code Organization: Implement proper Go package structure with
cmd,internal, andpkgdirectories, plus interface abstractions for testability and configuration management - Enhanced Error Handling: Create custom error types for different failure scenarios, implement error aggregation for better categorization, and add retry logic for transient failures
Project Statistics
- Duration: 1 day
- Lines of Code: ~200 lines across 4 files
- Difficulty: Beginner/Intermediate
- Technology Area: System Programming / Open Source Tooling
Related Resources
This is Project #1 of my 100 Projects Challenge. Read more about the challenge here.
Top comments (0)