Siege is a powerful open-source HTTP load testing tool designed for authorized performance testing of web servers. It allows penetration testers and system administrators to simulate multiple concurrent users, test server capacity, identify bottlenecks, and verify performance under load. Siege supports complex testing scenarios including URL lists, cookies, authentication, and detailed reporting.
- Concurrent Users: Simulate multiple simultaneous requests
- URL Lists: Test multiple endpoints from file
- Persistent Connections: HTTP keep-alive support
- Authentication: Basic, Digest, NTLM support
- Cookies: Session management and tracking
- Detailed Reports: Response times, throughput, success rates
- CSV Export: Data export for analysis
- Cross-platform: Linux, macOS, Windows (WSL)
# Apt repository
apt-get update
apt-get install siege
# Verify installation
siege -V
# Check version
siege --version
# Homebrew
brew install siege
# MacPorts
sudo port install siege
# Verify installation
siege -V
# WSL (Ubuntu)
wsl apt-get update
wsl apt-get install siege
# Git Bash with MinGW
pacman -S mingw-w64-x86_64-siege
# Download latest release
wget https://www.joedog.org/siege/siege-4.1.7.tar.gz
tar -xzf siege-4.1.7.tar.gz
cd siege-4.1.7
# Build and install
./configure
make
sudo make install
# Verify installation
siege -V
# Create Dockerfile
cat > Dockerfile << 'EOF'
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y siege
ENTRYPOINT ["siege"]
EOF
docker build -t siege .
docker run --rm siege -V
# Run with mounted reports
docker run --rm -v $(pwd):/reports siege -c 10 -t 300 http://example.com
Siege uses ~/.siegerc configuration file:
# Generate default config
siege -C
# View generated config
cat ~/.siegerc
# Use custom config file
siege -c /path/to/custom.rc http://example.com
| Option | Description | Default |
|---|
verbose | Verbose output mode | true |
csv | CSV logging | false |
logging | Log requests | false |
show-logfile | Show log location | false |
color | Colored output | on |
background | Run in background | false |
timestamp | Add timestamps | false |
csv-file | CSV output file | $HOME/.siege.csv |
logfile | Request log | $HOME/.siege.log |
url-escaping | Escape special chars | true |
keepalive | HTTP keep-alive | true |
gzip | Compression support | true |
cache-control | Honor cache headers | false |
follow-location | Follow redirects | true |
zero-data-ok | Accept 0 size responses | false |
cat > ~/.siegerc << 'EOF'
verbose = true
csv = true
logging = true
color = on
keepalive = true
gzip = true
follow-location = true
url-escaping = true
timestamp = true
csv-file = /tmp/siege.csv
logfile = /tmp/siege.log
EOF
# Basic test - default 1 user
siege http://example.com
# Test with specific number of concurrent users
siege -c 10 http://example.com
# Test for specific duration
siege -t T10M -c 5 http://example.com
# Test with repeat count
siege -r 100 -c 5 http://example.com
| Flag | Description | Example |
|---|
-c | Number of concurrent users | -c 25 |
-r | Repeat each URL N times | -r 10 |
-t | Test duration (S/M/H) | -t 10M |
-u | URL list file | -u urls.txt |
-f | URL file (same as -u) | -f targets.txt |
-m | Multiple request threads | -m |
-i | Internet simulation (random delay) | -i |
-d | Delay between requests (ms) | -d 100 |
-C | Generate config file | -C |
-R | Use config file | -R ~/.siegerc |
-v | Verbose output | -v |
-q | Quiet mode | -q |
-H | Add custom header | -H "Authorization: Bearer token" |
-A | User agent string | -A "Mozilla/5.0" |
# Create URL list file
cat > urls.txt << 'EOF'
http://example.com/
http://example.com/api/users
http://example.com/api/posts
http://example.com/api/comments
EOF
# Test all URLs in file
siege -f urls.txt -c 10 -r 5
# Test URLs with custom concurrency per URL
cat > urls_advanced.txt << 'EOF'
http://example.com/ # Homepage
http://example.com/api/v1/users # API endpoint
http://example.com/images/pic.jpg # Static file
EOF
siege -f urls_advanced.txt -c 20 -t 5M
# Basic auth (embedded in URL)
siege -c 10 http://username:password@example.com/protected
# Using header (recommended)
siege -c 10 -H "Authorization: Basic $(echo -n 'user:pass' | base64)" \
http://example.com/api
# From file
AUTH=$(cat /tmp/auth.txt)
siege -c 10 -H "Authorization: Bearer $AUTH" http://example.com
# Enable cookie support (automatic)
siege -c 10 http://example.com
# Custom cookie header
siege -c 10 \
-H "Cookie: sessionid=abc123; session_token=xyz789" \
http://example.com
# Multiple headers
siege -c 10 \
-H "Authorization: Bearer token123" \
-H "X-Custom-Header: value" \
-H "Content-Type: application/json" \
http://example.com/api
# Custom user agent
siege -c 10 -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" \
http://example.com
# Multiple custom headers
siege -c 10 \
-H "Authorization: Bearer abc123" \
-H "X-Request-ID: siege-test-001" \
-H "Accept: application/json" \
http://example.com/api
# Header from file
cat > headers.txt << 'EOF'
Authorization: Bearer token123
X-API-Key: sk_test_123456
Accept: application/json
EOF
while read header; do
HEADERS="$HEADERS -H \"$header\""
done < headers.txt
siege -c 10 $HEADERS http://example.com
# Internet simulation (random delay)
siege -c 5 -i http://example.com
# Fixed delay (milliseconds)
siege -c 5 -d 500 http://example.com
# Delay between requests (0.5 seconds)
siege -c 5 -d 500 http://example.com
# Variable delay pattern
for delay in 100 200 500; do
echo "[*] Testing with ${delay}ms delay"
siege -c 10 -d $delay -t 1M http://example.com
done
#!/bin/bash
# Gradually increase load
TARGET="http://example.com"
DURATIONS=("1M" "2M" "3M" "5M" "10M")
USERS=(5 10 20 30 50)
for i in "${!USERS[@]}"; do
CONCURRENT=${USERS[$i]}
DURATION=${DURATIONS[$i]}
echo "[*] Testing with $CONCURRENT users for $DURATION"
siege -c $CONCURRENT -t $DURATION "$TARGET" -q
done
#!/bin/bash
# Sudden spike in traffic
TARGET="http://example.com"
# Normal load
echo "[*] Normal load (10 users)"
siege -c 10 -t 1M "$TARGET" -q
# Burst
echo "[*] Burst load (100 users)"
siege -c 100 -t 30S "$TARGET" -q
# Recovery
echo "[*] Normal load recovery"
siege -c 10 -t 1M "$TARGET" -q
#!/bin/bash
# Long-duration steady load
TARGET="http://example.com"
CONCURRENT=25
DURATION="1H"
echo "[*] Running endurance test for $DURATION with $CONCURRENT users"
siege -c $CONCURRENT -t $DURATION "$TARGET" -v
echo "[*] Test completed - check results below"
#!/bin/bash
# Test API with various endpoints
cat > api_urls.txt << 'EOF'
http://api.example.com/v1/users
http://api.example.com/v1/users/1
http://api.example.com/v1/posts
http://api.example.com/v1/posts/1
http://api.example.com/v1/comments
EOF
# Test API with authentication
AUTH_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
siege -f api_urls.txt \
-c 30 \
-t 10M \
-H "Authorization: Bearer $AUTH_TOKEN" \
-H "Content-Type: application/json" \
-v
# Run with verbose output
siege -c 10 http://example.com -v
# Verbose + quiet progress
siege -c 10 http://example.com -v -q
# Enable CSV logging
siege -c 10 -t 5M http://example.com -m -R ~/.siegerc
# CSV file location
cat ~/.siege.csv
# Parse CSV results
awk -F, '{print $1, $2, $3}' ~/.siege.csv | head -20
# Analyze response times (column 1)
awk -F, 'NR>1 {sum+=$1; count++} END {print "Avg:", sum/count}' ~/.siege.csv
# Summary report after test
siege -c 10 -r 100 http://example.com
# Full metrics report
siege -c 10 -t 5M http://example.com -m -R ~/.siegerc
# Custom report script
#!/bin/bash
REPORT=$(siege -c 10 -t 5M http://example.com 2>&1)
echo "$REPORT"
# Extract key metrics
THROUGHPUT=$(echo "$REPORT" | grep "Transactions:" | awk '{print $2}')
RESPONSE=$(echo "$REPORT" | grep "Response time:" | awk '{print $3}')
FAILED=$(echo "$REPORT" | grep "Failed:" | awk '{print $2}')
echo "Results:"
echo " Throughput: $THROUGHPUT trans/sec"
echo " Response time: $RESPONSE sec"
echo " Failed: $FAILED"
# Test with focus on response times
siege -c 20 -t 10M http://example.com -m
# CSV parsing for response time stats
awk -F, 'NR>1 {
times[NR]=$1
sum+=$1
max=($1>max)?$1:max
min=($1<min||min==0)?$1:min
}
END {
print "Response Time Analysis:"
print " Average: " sum/NR " ms"
print " Max: " max " ms"
print " Min: " min " ms"
print " Total: " NR " requests"
}' ~/.siege.csv
#!/bin/bash
# Measure requests per second
echo "[*] Testing throughput..."
START=$(date +%s)
siege -c 20 -r 1000 http://example.com -q
END=$(date +%s)
DURATION=$((END - START))
REQUESTS=$((20 * 1000))
RPS=$((REQUESTS / DURATION))
echo "Results:"
echo " Total Requests: $REQUESTS"
echo " Duration: ${DURATION}s"
echo " RPS: $RPS"
# Test and track failures
siege -c 10 -t 5M http://example.com -m -R ~/.siegerc
# Analyze failures from CSV
awk -F, 'NR>1 {
success++
if ($3 != "200" && $3 != "0") {
failed++
print "Failed: HTTP " $3 " at " $2
}
}
END {
total = success + failed
pct = (failed / total) * 100
print "\nFailure Rate: " pct "% (" failed "/" total ")"
}' ~/.siege.csv
#!/bin/bash
# Simulate realistic user behavior
cat > realistic_urls.txt << 'EOF'
http://example.com/ # Homepage (80% traffic)
http://example.com/products # Products (15% traffic)
http://example.com/api/search # Search (3% traffic)
http://example.com/checkout # Checkout (2% traffic)
EOF
# Hour-long test with realistic pattern
echo "[*] Simulating realistic traffic pattern..."
siege -f realistic_urls.txt \
-c 50 \
-t 60M \
-d 200 \
-i \
-v
#!/bin/bash
# Sudden traffic spike
TARGET="http://example.com"
test_load() {
local users=$1
local duration=$2
echo "[*] Load: $users users, Duration: $duration"
siege -c $users -t $duration "$TARGET" -q
}
# Baseline
test_load 10 1M
# Spike 1
test_load 100 10S
# Recovery
test_load 10 1M
# Spike 2
test_load 150 15S
# Return to normal
test_load 10 1M
# HTTPS endpoint
siege -c 20 https://secure.example.com
# With specific TLS version
siege -c 20 https://example.com
# Ignore SSL warnings (self-signed)
export SIERRA_IGNORE_CERT=1
siege -c 20 https://selfsigned.example.com
# TLS verification disabled
curl -k https://example.com
siege -c 20 https://example.com
#!/bin/bash
# Test multiple endpoints
ENDPOINTS=(
"http://example.com"
"http://example.com/api"
"http://example.com/dashboard"
)
for endpoint in "${ENDPOINTS[@]}"; do
echo "[*] Testing: $endpoint"
siege -c 10 -t 2M "$endpoint" -q
echo "---"
done
#!/bin/bash
# Compare two versions
BEFORE="http://example.com:8080"
AFTER="http://example.com:8081"
for url in "$BEFORE" "$AFTER"; do
echo "[*] Testing: $url"
OUTPUT=$(siege -c 20 -r 100 "$url" 2>&1)
TRANS=$(echo "$OUTPUT" | grep "Transactions:" | awk '{print $2}')
RESP=$(echo "$OUTPUT" | grep "Response time:" | awk '{print $3}')
echo " Transactions/sec: $TRANS"
echo " Response time: $RESP"
echo ""
done
#!/bin/bash
# Alert on high response times
THRESHOLD=5.0 # seconds
TARGET="http://example.com"
OUTPUT=$(siege -c 20 -r 100 "$TARGET" 2>&1)
RESPONSE=$(echo "$OUTPUT" | grep "Response time:" | awk '{print $3}')
if (( $(echo "$RESPONSE > $THRESHOLD" | bc -l) )); then
echo "ALERT: Response time $RESPONSE exceeds threshold $THRESHOLD"
# Send alert
mail -s "Performance Alert" admin@example.com <<< "Response time critical"
else
echo "OK: Response time $RESPONSE is acceptable"
fi
# Test connectivity first
ping example.com
curl http://example.com
# Verbose debug output
siege -c 5 http://example.com -v
# Check network
netstat -an | grep ESTABLISHED | wc -l
# Increase file descriptor limit
ulimit -n 65536
# Check server status
curl -I http://example.com
# Reduce concurrent users
siege -c 5 http://example.com
# Add delay between requests
siege -c 10 -d 500 http://example.com
# Check server logs
tail -f /var/log/apache2/access.log
tail -f /var/log/nginx/access.log
# Monitor resource usage
watch -n 1 'ps aux | grep siege'
# Reduce test intensity
siege -c 10 -r 50 http://example.com
# Run in background
siege -c 20 -t 10M http://example.com &
# Check available resources
free -h
- Always get written authorization before load testing
- Test against non-production systems first
- Gradually increase load to identify breaking points
- Monitor server resources during testing
- Document baseline performance metrics
- Schedule tests during off-peak hours if testing production
- Maintain detailed test results for analysis
# Optimize test parameters
CONCURRENT=50
DURATION="10M"
REQUESTS=1000
# Calculate expected load
# Requests per second = (Concurrent * Requests per user) / Duration
siege -c $CONCURRENT -r $((REQUESTS/CONCURRENT)) -t $DURATION http://example.com
| Task | Command |
|---|
| Basic test | siege http://example.com |
| 10 concurrent users | siege -c 10 http://example.com |
| 5 minute duration | siege -t 5M http://example.com |
| URL list | siege -f urls.txt -c 20 |
| With auth | siege -c 10 -H "Authorization: Bearer token" http://example.com |
| Custom delay | siege -c 10 -d 500 http://example.com |
| Verbose output | siege -v -c 10 http://example.com |
| CSV logging | siege -m http://example.com |