Siege is an HTTP load testing and benchmarking utility that simulates multiple users accessing your web server simultaneously. Whether you need to stress-test a new deployment, measure response times under load, or identify performance bottlenecks before going live, Siege provides the metrics you need. This tool works with any HTTP server, including Apache and Nginx installations. By the end of this guide, you will have Siege installed and configured on Debian, with practical examples for testing web applications.
Choose Your Siege Installation Method
Debian offers Siege through its default repositories, while source compilation provides access to the latest features. The following table compares both approaches to help you choose:
| Method | Channel | Version | Updates | Best For |
|---|---|---|---|---|
| APT Package Manager | Debian Repos | Distribution default | Automatic via apt upgrade | Most users who prefer stability and easy maintenance |
| Source Compilation | JoeDog Downloads | Latest stable | Manual recompilation required | Users who need the newest features or custom build options |
For most users, the APT method is recommended because it integrates with your system’s package management, receives security updates automatically, and requires no compilation. Choose source compilation only if you specifically need features unavailable in the repository version.
This guide covers Debian 13 (Trixie), Debian 12 (Bookworm), and Debian 11 (Bullseye). The APT package version varies by release: Debian 13 includes Siege 4.1.6, while Debian 11 and 12 provide version 4.0.7. Commands work identically across all supported releases unless noted otherwise.
Install Siege on Debian via APT
Step 1: Update Package Lists
Before installing any software, refresh your package lists to ensure you receive the latest available version from Debian’s repositories:
sudo apt update
Step 2: Install Siege
Since Siege is available in Debian’s default repositories, installation requires just a single command:
sudo apt install siege
APT automatically resolves dependencies and configures Siege for immediate use. Once installation completes, Siege creates a default configuration file in your home directory.
Step 3: Verify the Installation
Next, confirm that Siege installed correctly by checking the version:
siege --version
Expected output on Debian 13:
SIEGE 4.1.6 Copyright (C) 2023 by Jeffrey Fulmer, et al. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
On Debian 11 and 12, the version displays as 4.0.7 with a 2018 copyright year. However, both versions function identically for most testing scenarios.
Install Siege on Debian via Source Compilation
Alternatively, compiling Siege from source provides access to the latest version (currently 4.1.7) and allows custom build options. This method requires installing development tools and libraries first.
Step 1: Install Build Dependencies
First, install the required development packages for compiling Siege:
sudo apt update
sudo apt install build-essential libssl-dev zlib1g-dev wget
These packages provide the C compiler (build-essential), SSL/TLS support (libssl-dev), compression handling (zlib1g-dev), and file downloading (wget).
Step 2: Download the Source Archive
Next, download the latest Siege source code from the official JoeDog server:
cd ~
wget https://download.joedog.org/siege/siege-latest.tar.gz
The siege-latest.tar.gz file always points to the most recent stable release. At the time of writing, this is version 4.1.7.
Step 3: Extract and Enter the Source Directory
Then, extract the downloaded archive and navigate into the source directory:
tar -xzf siege-latest.tar.gz
cd siege-*/
The wildcard pattern siege-*/ matches any version directory, so this command works regardless of the specific version you downloaded.
Step 4: Configure the Build
Now, run the configure script to detect your system’s capabilities and prepare the build environment:
./configure
The configure script detects your compiler and libraries automatically. After processing completes, you should see a success message:
checking for OpenSSL version... >= 0.9.8 (appropriate flag set) checking for ZLIB version... checking for inline... inline configure: creating ./config.status config.status: creating Makefile config.status: creating src/Makefile config.status: creating include/config.h config.status: executing depfiles commands -------------------------------------------------------- Configuration is complete Run the following commands to complete the installation: make make install For complete documentation: http://www.joedog.org --------------------------------------------------------
This output confirms the build system detected OpenSSL and zlib. If configuration fails, verify that libssl-dev and zlib1g-dev are installed.
Step 5: Compile and Install
Finally, compile the source code and install Siege. You have two options depending on your access level:
System-wide Installation (requires sudo)
To install Siege for all users on the system:
make
sudo make install
This installs Siege to /usr/local/bin/, making it available to all users on the system.
User-local Installation (no sudo required)
If you do not have root access or prefer to keep Siege in your home directory, configure with a local prefix instead. First, go back and reconfigure:
./configure --prefix=$HOME/.local
Then compile and install without sudo:
make
make install
This installs Siege to ~/.local/bin/. To use it, ensure this directory is in your PATH by adding the following to your ~/.bashrc or ~/.profile:
export PATH="$HOME/.local/bin:$PATH"
After adding this line, reload your shell configuration:
source ~/.bashrc
Step 6: Verify the Source Installation
After installation completes, confirm the source-compiled version is accessible:
siege --version
Expected output:
SIEGE 4.1.7 Copyright (C) 2024 by Jeffrey Fulmer, et al. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Configure Siege
Siege stores its configuration in ~/.siege/siege.conf, which it creates automatically on first run. To view the current configuration, run:
siege -C
This command displays all active settings. For APT installations, you should see output similar to:
CURRENT SIEGE CONFIGURATION Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/4.1.6 Edit the resource file to change the settings. ---------------------------------------------- version: 4.1.6 verbose: true color: true quiet: false protocol: HTTP/1.1 concurrent users: 25 time to run: n/a socket timeout: 30 delay: 0.000 sec logging: false log file: /var/log/siege.log resource file: /home/username/.siege/siege.conf
Source-compiled installations show a log path of /usr/local/var/log/siege.log instead. Both installation methods store user settings in ~/.siege/siege.conf.
Common Configuration Options
To customize Siege’s behavior, edit the configuration file:
nano ~/.siege/siege.conf
The following are key settings to consider:
concurrent
- Default number of simulated users
- Default: 25
- Increase for higher load tests, but monitor your client machine’s resources
delay
- Random delay (in seconds) between each user’s requests
- Default: 0 (no delay)
- Set to 1-5 for more realistic user simulation
timeout
- Socket connection timeout in seconds
- Default: 30
- Increase if testing slow applications
logging
- Enable persistent logging of test results
- Default: false
- Set to true for tracking performance over time
Use Siege for Load Testing
Siege provides several testing modes for different scenarios. The following examples demonstrate common use cases, along with expected output.
Basic Load Test
To start, the simplest test sends requests from the default 25 concurrent users until you stop it with Ctrl+C:
siege https://example.com
When you press Ctrl+C, the test stops and displays the results:
Lifting the server siege... Transactions: 1250 hits Availability: 100.00 % Elapsed time: 10.25 secs Data transferred: 1.45 MB Response time: 0.20 secs Transaction rate: 121.95 trans/sec Throughput: 0.14 MB/sec Concurrency: 24.39 Successful transactions: 1250 Failed transactions: 0 Longest transaction: 0.85 Shortest transaction: 0.08
Timed Test with Specific User Count
For more controlled testing, you can specify the number of concurrent users with -c and the test duration with -t:
siege -c 50 -t 1M https://example.com
In this example, the command simulates 50 concurrent users for 1 minute. Note that the time modifier accepts S (seconds), M (minutes), or H (hours).
Benchmark Mode
When you need maximum throughput, benchmark mode removes all delays between requests, thereby generating maximum load on the target server:
siege -b -c 100 -t 30S https://example.com
Here, the -b flag enables benchmark mode. You can use this to find your server’s maximum capacity; however, be aware it can overwhelm production systems.
Only run benchmark tests against servers you own or have explicit permission to test. Aggressive load testing against third-party servers may violate terms of service and could be interpreted as a denial-of-service attack.
Test Multiple URLs
In practice, real-world traffic hits multiple pages. First, create a file containing URLs to test:
nano ~/urls.txt
Then, add your target URLs, one per line:
https://example.com/ https://example.com/about https://example.com/contact https://example.com/products
Next, run Siege with the -f flag to read URLs from the file:
siege -c 25 -t 2M -f ~/urls.txt
During testing, Siege randomly selects URLs from the file, simulating realistic user navigation patterns.
Internet Simulation Mode
The -i flag enables internet simulation, which randomly selects URLs and adds variable delays to mimic real user behavior:
siege -c 25 -t 5M -i -f ~/urls.txt
As a result, this mode provides more realistic load patterns compared to pure benchmark testing.
Add Custom Headers
Test authenticated endpoints or API requests by adding custom headers with -H:
siege -c 10 -t 30S -H "Authorization: Bearer your-token-here" https://api.example.com/endpoint
Additionally, you can specify multiple headers by using -H multiple times:
siege -c 10 -t 30S \
-H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
https://api.example.com/endpoint
JSON Output for Automation
If you need scripting and monitoring integration, you can use --json-output to get machine-readable results:
siege -c 25 -t 30S --json-output -q https://example.com
In this case, the -q (quiet) flag suppresses per-request output, leaving only the final JSON statistics:
{"transactions": 850, "availability": 100.00, "elapsed_time": 30.05, "data_transferred": 0.98, "response_time": 0.18, "transaction_rate": 28.29, "throughput": 0.03, "concurrency": 5.02, "successful_transactions": 850, "failed_transactions": 0, "longest_transaction": 0.92, "shortest_transaction": 0.07}
Enable Logging
To save test results for historical analysis, use the --log flag:
siege --log=~/siege-results.log -c 50 -t 1M https://example.com
Each test appends a summary line to the log file, allowing you to track performance changes over time.
Realistic Delay Between Requests
Real users don’t click continuously. The -d flag adds a random delay (up to the specified seconds) between each simulated user’s requests:
siege -c 50 -t 5M -d 3 https://example.com
As a result, this introduces 0-3 seconds of delay between requests, better simulating how actual visitors interact with your site.
Interpret Siege Results
Understanding Siege’s output is essential for identifying bottlenecks and measuring improvements. Here is what each metric means:
Transactions
- Total number of completed HTTP requests
- Higher is generally better, but context matters
Availability
- Percentage of successful requests
- Should be 100% under normal conditions; values below 99% indicate problems
Response time
- Average time to complete each request
- Lower is better; under 0.5 seconds is generally acceptable for web pages
Transaction rate
- Requests completed per second
- Your server’s throughput capacity
Concurrency
- Average number of simultaneous connections during the test
- Should be close to your
-cvalue; significantly lower indicates connection bottlenecks
Failed transactions
- Requests that received errors or timeouts
- Any value above 0 warrants investigation
Update Siege
Update APT-Installed Siege
If you installed Siege via APT, updates arrive through normal system upgrades:
sudo apt update
sudo apt install --only-upgrade siege
This command uses the --only-upgrade flag, which updates Siege only if a newer version is available, without installing it fresh if previously removed.
Update Source-Compiled Siege
For source installations, you can either run the commands manually or use an automated script. Here are both options:
Option 1: Manual Update
To update manually, download the latest source and recompile:
cd ~
wget https://download.joedog.org/siege/siege-latest.tar.gz
tar -xzf siege-latest.tar.gz
cd siege-*/
./configure
make
sudo make install
Option 2: Automated Update Script
Alternatively, create a reusable update script that checks versions, downloads, compiles, and cleans up automatically. First, create the script file:
nano ~/update-siege.sh
Then, paste the following content:
#!/bin/bash
# Siege Source Update Script
# Downloads, compiles, and installs the latest Siege version
# Usage: ./update-siege.sh [--local]
# --local: Install to ~/.local (no sudo required)
set -e
# Parse arguments
LOCAL_INSTALL=false
if [ "$1" = "--local" ]; then
LOCAL_INSTALL=true
fi
BUILD_DIR="${HOME}/siege-build"
DOWNLOAD_URL="https://download.joedog.org/siege/siege-latest.tar.gz"
echo "=== Siege Source Update Script ==="
if [ "$LOCAL_INSTALL" = true ]; then
echo "Mode: User-local installation (no sudo required)"
INSTALL_PREFIX="$HOME/.local"
else
echo "Mode: System-wide installation (requires sudo)"
INSTALL_PREFIX="/usr/local"
fi
# Check for required tools
echo -e "\nChecking prerequisites..."
for cmd in wget tar make gcc; do
if ! command -v "$cmd" &> /dev/null; then
echo "Error: $cmd is not installed."
echo "Install dependencies: sudo apt install build-essential libssl-dev zlib1g-dev wget"
exit 1
fi
done
echo "All prerequisites found."
# Check current version
if command -v siege &> /dev/null; then
CURRENT_VERSION=$(siege --version 2>&1 | head -1 | awk '{print $2}')
echo "Current Siege version: ${CURRENT_VERSION}"
else
echo "Siege is not currently installed."
CURRENT_VERSION="none"
fi
# Create build directory and download
echo -e "\nCreating build directory..."
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
echo -e "\nDownloading latest Siege source..."
rm -f siege-latest.tar.gz
wget -q --show-progress "$DOWNLOAD_URL"
echo -e "\nExtracting archive..."
rm -rf siege-*/
tar -xzf siege-latest.tar.gz
# Check version and compile
cd siege-*/
NEW_VERSION=$(grep "PACKAGE_VERSION=" configure | cut -d'=' -f2 | tr -d "'")
echo "Latest available version: ${NEW_VERSION}"
if [ "$CURRENT_VERSION" = "$NEW_VERSION" ]; then
echo -e "\nSiege is already up to date (version ${NEW_VERSION})."
exit 0
fi
echo -e "\nConfiguring build..."
./configure --prefix="$INSTALL_PREFIX" --quiet
echo -e "\nCompiling..."
make -j$(nproc) --quiet
echo -e "\nInstalling..."
if [ "$LOCAL_INSTALL" = true ]; then
make install --quiet
else
sudo make install --quiet
fi
# Verify and cleanup
echo -e "\nVerifying installation..."
INSTALLED_VERSION=$(siege --version 2>&1 | head -1 | awk '{print $2}')
echo "Successfully installed Siege ${INSTALLED_VERSION}"
echo -e "\nCleaning up..."
cd "$HOME"
rm -rf "$BUILD_DIR"
echo -e "\n=== Update complete ==="
After saving the file, make it executable:
chmod +x ~/update-siege.sh
Now you can run the script with or without the --local flag:
# System-wide update (requires sudo)
~/update-siege.sh
# User-local update (no sudo required)
~/update-siege.sh --local
Expected output when updating from version 4.1.6 to 4.1.7:
=== Siege Source Update Script === Checking prerequisites... All prerequisites found. Current Siege version: 4.1.6 Creating build directory... Downloading latest Siege source... siege-latest.tar.gz 100%[==================>] 530.71K 2.50MB/s in 0.2s Extracting archive... Latest available version: 4.1.7 Configuring build... Compiling... Installing (requires sudo)... Verifying installation... Successfully installed Siege 4.1.7 Cleaning up... === Update complete ===
Do not run this script via cron or automated schedulers. Source compilation should always be performed interactively so you can address any dependency issues or compilation errors that may arise.
Fortunately, your configuration file remains intact during updates since it resides in your home directory.
Troubleshoot Common Issues
Connection Refused or Timeout Errors
If Siege reports connection failures, verify the target server is accessible:
curl -I https://example.com
If curl works but Siege fails, the target server may be rate-limiting or blocking load testing tools based on the User-Agent string. In that case, try using a custom user agent:
siege -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" https://example.com
Too Many Open Files
High concurrency tests may hit your system’s file descriptor limit:
[error] socket: unable to connect sock.c:282: Too many open files
First, check your current limit:
ulimit -n
Then, temporarily increase the limit for your session:
ulimit -n 65535
For permanent changes, edit /etc/security/limits.conf and add lines for your user.
SSL Certificate Errors
Self-signed or expired certificates cause SSL handshake failures. Siege validates certificates by default. If you encounter SSL errors, first verify the target URL works in curl:
curl -v https://example.com 2>&1 | grep -i ssl
For testing environments with self-signed certificates, either ensure your system trusts the certificate or use HTTP for local testing instead. Note that the APT-installed Siege version (4.0.7) on Debian 11/12 has more limited SSL options than newer source-compiled versions.
Production load tests should always use valid certificates to accurately simulate real user connections. Testing against self-signed certificates gives inaccurate results since SSL handshake overhead differs from production environments.
Low Concurrency Despite High User Count
If reported concurrency is much lower than your -c value, the server is responding faster than Siege can generate requests. This is actually a positive result, indicating your server handles load efficiently. To generate more load, increase the concurrent user count or use benchmark mode (-b).
Remove Siege
Remove APT-Installed Siege
To uninstall the APT-installed version, run the following commands:
sudo apt remove --purge siege
sudo apt autoremove
The autoremove command then cleans up any orphaned dependencies that were installed alongside Siege.
Remove Source-Compiled Siege
If you compiled Siege from source, delete the installed binaries and man pages manually:
sudo rm /usr/local/bin/siege
sudo rm /usr/local/bin/bombardment
sudo rm /usr/local/bin/siege2csv.pl
sudo rm /usr/local/bin/siege.config
sudo rm /usr/local/etc/siegerc
sudo rm /usr/local/etc/urls.txt
sudo rm -rf /usr/local/share/man/man1/siege*
Remove User Configuration
The following command permanently deletes your Siege configuration and any custom URL files in the
.siegedirectory. If you have customizations you want to preserve, back them up first.
To delete the user configuration directory:
rm -rf ~/.siege
Clean Up Source Files
Finally, delete the downloaded source archive and extracted directory:
rm -rf ~/siege-latest.tar.gz ~/siege-*/
Verify Removal
To confirm that Siege is no longer installed:
which siege
If removal succeeded, this command produces no output. Conversely, any path displayed indicates files remain.
Conclusion
You now have Siege installed and configured for HTTP load testing on Debian. Throughout this guide, the examples covered range from basic availability checks to realistic multi-URL simulations with custom headers. By using these techniques, you can validate server capacity, identify bottlenecks, and measure the impact of performance optimizations before deploying to production.