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:
| Symptom | Likely Bottleneck | Solution |
|---|---|---|
| CPU at 100%, low request rate | CPU-bound (application logic) | Optimize code, add more vCPUs, enable caching |
| High swap usage, RAM near limit | Memory-bound | Increase RAM, optimize memory usage, reduce worker count |
| Disk iowait > 30%, high await time | Disk I/O bound | Upgrade to NVMe, tune I/O scheduler, offload to cache |
| Network retransmits > 0.5% | Network congestion | Check bandwidth limits, upgrade network tier |
| Connection timeouts, socket errors | Connection limit (ulimit or nginx) | Increase ulimit, tune nginx worker_connections |
| All resources low but throughput stalls | Application lock contention or DB query bottleneck | Profile 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
You must be logged in to post a comment.