VPS Load Testing Guide: How to Benchmark Your Server with Siege and wrk

Before putting your VPS into production, you need to know how it behaves under load. Load testing answers critical questions: How many concurrent users can your server handle? At what point does response time degrade? Which component bottlenecks first — CPU, RAM, disk I/O, or network? This comprehensive guide walks through practical load testing using Siege and wrk to benchmark your VPS, interpret results, identify bottlenecks, and build a continuous performance testing pipeline.

Why Load Test Your VPS?

VPS performance varies significantly between providers due to shared hypervisor resources, CPU throttling policies, and I/O limits. Load testing helps you:

  • Establish baseline performance metrics for your VPS
  • Identify CPU, memory, disk, or network bottlenecks under realistic traffic
  • Validate that your provider delivers the advertised resources
  • Determine scaling thresholds for capacity planning
  • Compare providers when choosing a VPS hosting plan

To get the most from your load testing, check VPS performance features on our site to understand what specs to look for when selecting a provider.

Installing the Tools

Install Siege

Siege is a mature HTTP load testing tool that supports concurrent users, random delays, and multi-URL testing:

sudo apt update
sudo apt install -y siege

Install wrk

wrk is a modern HTTP benchmarking tool that uses a multithreaded event-loop architecture for high-throughput tests. Build from source:

sudo apt install -y build-essential libssl-dev git
git clone https://github.com/wg/wrk.git /tmp/wrk
cd /tmp/wrk
make
sudo cp wrk /usr/local/bin/
rm -rf /tmp/wrk

Verify both tools are installed:

siege --version
wrk --version

Running Your First Load Test with Siege

Siege operates by simulating concurrent users hitting your server over a specified duration. Start with a basic test:

siege -c 50 -t 60s https://your-vps-domain.com/

Parameters explained:

  • -c 50 — 50 concurrent users
  • -t 60s — Run for 60 seconds
  • The URL is the endpoint you want to test

Siege outputs a summary report at the end:

Transactions:                4500 hits
Availability:              100.00 %
Elapsed time:               59.23 secs
Data transferred:           12.50 MB
Response time:                0.65 secs
Transaction rate:           75.97 trans/sec
Throughput:                  0.21 MB/sec
Concurrency:                 49.23
Successful transactions:    4500
Failed transactions:           0
Longest transaction:         2.34
Shortest transaction:        0.01

Key metrics to watch:

  • Availability — Should be 100% for a healthy server. Drops indicate requests timing out or being rejected.
  • Response time — Average time per request. Under 1 second is good; over 2 seconds under moderate load indicates a bottleneck.
  • Transaction rate — Requests per second. Compare this against your expected traffic.
  • Failed transactions — Any failures indicate the server cannot keep up with the load.

Advanced Siege Testing with Multi-URL Workloads

For more realistic testing, use Siege URL files to simulate multi-page navigation with random think times:

# Create a URL file with weighted paths
cat > /tmp/urls.txt << EOF
https://your-vps-domain.com/ URL = 5.0
https://your-vps-domain.com/about URL = 1.0
https://your-vps-domain.com/api/status URL = 3.0
https://your-vps-domain.com/login URL = 1.0
EOF

# Run with random delays and 100 concurrent users
siege -c 100 -t 120s -f /tmp/urls.txt -d 5

The -d 5 flag adds a random delay of up to 5 seconds between requests. The weight values after URL = control how often each endpoint is hit — a weight of 5.0 means that endpoint gets hit five times more often than one with weight 1.0.

Running Benchmarks with wrk

wrk excels at high-throughput testing with precise latency measurements:

# Basic benchmark: 12 threads, 400 connections, 30 seconds
wrk -t12 -c400 -d30s https://your-vps-domain.com/

Sample output:

Running 30s test @ https://your-vps-domain.com/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    45.67ms   38.21ms   1.24s    84.23%
    Req/Sec   723.45    152.32     1.42k    70.12%
  259842 requests in 30.09s, 385.27MB read
  Socket errors: connect 0, read 0, write 0, timeout 12
Requests/sec:   8635.63
Transfer/sec:     12.80MB

wrk latency distribution is its most valuable output. The Avg and Stdev tell you the central tendency, but the Max reveals worst-case behavior. A high maximum with low average suggests occasional contention — investigate those timeouts.

Advanced wrk with Lua Scripting

wrk supports Lua scripting for custom request patterns, authentication, and dynamic payloads. Create post.lua for testing API endpoints:

-- post.lua - wrk script for POST request benchmarking
wrk.method = "POST"
wrk.body   = '{"email": "[email protected]", "password": "test123"}'
wrk.headers["Content-Type"] = "application/json"
wrk.headers["Authorization"] = "Bearer test-token-here"

Run with:

wrk -t4 -c100 -d30s -s post.lua https://your-vps-domain.com/api/login

You can also use Lua to generate dynamic request data using request() and response() callback functions, enabling session-based testing with cookies and tokens.

Interpreting Results and Identifying Bottlenecks

During and after your load test, monitor the VPS with htop, iostat -x 2, vmstat 2, and netstat -i simultaneously to identify which resource is saturated:

SymptomLikely BottleneckSolution
CPU at 100%, low request rateCPU-bound (application logic)Optimize code, add more vCPUs, enable caching
High swap usage, RAM near limitMemory-boundIncrease RAM, optimize memory usage, reduce worker count
Disk iowait > 30%, high await timeDisk I/O boundUpgrade to NVMe, tune I/O scheduler, offload to cache
Network retransmits > 0.5%Network congestionCheck bandwidth limits, upgrade network tier
Connection timeouts, socket errorsConnection limit (ulimit or nginx)Increase ulimit, tune nginx worker_connections
All resources low but throughput stallsApplication lock contention or DB query bottleneckProfile with strace/perf, optimize slow queries

Parsing Load Test Results Programmatically

For CI/CD pipelines, parse wrk output as JSON:

wrk -t4 -c100 -d30s --latency https://your-vps-domain.com/ 2>&1 | \
  awk '/Requests\/sec:/ {print "rps:", $2}'

Or pipe to a Python script for structured output:

|
#!/usr/bin/env python3
# Parse wrk output and assert performance thresholds
import sys, re

output = sys.stdin.read()
rps = float(re.search(r'Requests/sec:\s+([\d.]+)', output).group(1))
avg_lat = float(re.search(r'Latency\s+([\d.]+)ms', output).group(1))
errors = int(re.search(r'timeout (\d+)', output).group(1)) if 'timeout' in output else 0

print(f"RPS: {rps:.0f}, Avg Latency: {avg_lat:.2f}ms, Timeouts: {errors}")
if rps < 5000 or avg_lat > 100:
    sys.exit(1)  # Fail CI pipeline

Establishing Baselines and Comparing Providers

Run the same load test suite after each configuration change or migration to track performance trends. A practical baseline test suite includes:

  • Light load: 10 concurrent users, 60 seconds (baseline responsiveness)
  • Medium load: 100 concurrent users, 120 seconds (typical production traffic)
  • Stress load: 500 concurrent users, 180 seconds (breaking point)
  • Soak test: 100 concurrent users, 30 minutes (memory leaks and degradation)

For a side-by-side comparison of VPS providers with consistent hardware specs, visit our comparison page.

Automating Load Tests with Shell Scripts

Create a reusable test script to run the complete suite programmatically:

#!/bin/bash
# loadtest.sh - Run complete load test suite
URL=$1
DATE=$(date +%Y%m%d_%H%M)
RESULTS_DIR="/tmp/loadtest_$DATE"

mkdir -p "$RESULTS_DIR"

echo "=== Light Load (10 concurrent, 60s) ==="
siege -c 10 -t 60s "$URL" > "$RESULTS_DIR/siege_light.txt" 2>&1
wrk -t2 -c10 -d60s "$URL" > "$RESULTS_DIR/wrk_light.txt" 2>&1

echo "=== Medium Load (100 concurrent, 120s) ==="
siege -c 100 -t 120s "$URL" > "$RESULTS_DIR/siege_medium.txt" 2>&1
wrk -t4 -c100 -d120s "$URL" > "$RESULTS_DIR/wrk_medium.txt" 2>&1

echo "=== Stress Load (500 concurrent, 180s) ==="
wrk -t12 -c500 -d180s "$URL" > "$RESULTS_DIR/wrk_stress.txt" 2>&1

echo "Results saved to $RESULTS_DIR"

Integrating Load Tests into CI/CD

For continuous performance testing, run load tests as part of your deployment pipeline. Store results in a time-series database (like Prometheus) and graph them in Grafana. When performance regressions exceed thresholds (e.g., RPS drops by 20%), the pipeline can automatically roll back the deployment. Cloudways managed VPS includes integrated performance monitoring to augment your load testing data.

Conclusion

Regular load testing with Siege and wrk gives you objective data about your VPS performance, helps you identify bottlenecks before they affect users, and provides leverage when evaluating providers. Establish baselines, test systematically, automate your test suite in CI/CD, and always correlate load test results with system metrics to pinpoint the actual bottleneck. For VPS providers with dedicated resources and performance guarantees, check our VPS provider comparison table.

Leave a Reply