Siege is useful when a Debian server needs repeatable HTTP load checks before a change reaches real users. You can install Siege on Debian from the default APT repository for the safest maintenance path, or compile the current upstream release when you specifically need the newer JoeDog source build.
Yes, Siege runs on Linux as a command-line tool. On Debian, it can test local services, staging sites, API endpoints, and web stacks such as Apache on Debian or Nginx on Debian, as long as you test only systems you own or have permission to stress.
Install Siege on Debian
Choose a Siege Installation Method
Use the APT package unless you have a clear reason to build from source. The Debian package receives normal system updates and avoids a compiler toolchain, while the source method installs outside Debian’s package database and needs manual lifecycle handling.
| Method | Source | Update Behavior | Best For | Trade-offs |
|---|---|---|---|---|
| APT package | Debian package archive | Updates through normal APT upgrades | Most Debian systems | Debian 13 ships a newer package than Debian 12 or 11 |
| Source build | JoeDog source downloads | Manual rebuild or source-update helper | Users who need the current upstream release or custom prefix | Requires build dependencies and manual cleanup |
Use one method for normal shell use. If both APT and source builds are installed, Debian usually finds
/usr/local/bin/siegebefore/usr/bin/siege, so verify the active binary withcommand -v siege.
Debian 13 (Trixie) currently provides Siege 4.1.6 from the default repository. Debian 12 (Bookworm) and Debian 11 (Bullseye) provide Siege 4.0.7. The core options used in this article, including concurrent users, timed tests, URL files, custom headers, logging, and JSON output, are available across those releases.
Install Siege with APT
Refresh package metadata, then install the Debian package:
sudo apt update
sudo apt install siege
These commands use sudo for package management tasks that need root privileges. If your account cannot run sudo yet, configure a privileged account first with the Debian sudoers setup guide.
Verify the APT Installation
Check the installed binary and version:
command -v siege
siege --version
On Debian 13, the version output starts with:
SIEGE 4.1.6
On Debian 12 and Debian 11, the version output starts with:
SIEGE 4.0.7
The first run also creates a user configuration template under ~/.siege when it does not already exist.
Compile Siege from Source
Build from source only when the Debian package is too old for your workflow. This method downloads the current upstream siege-latest.tar.gz tarball, compiles it locally, and installs it under /usr/local by default.
Install the compiler, OpenSSL headers, zlib headers, and the downloader first:
sudo apt update
sudo apt install build-essential libssl-dev zlib1g-dev wget
Create a reusable source-build helper after the dependencies are installed. The helper downloads the current upstream tarball, compares it with the source-built binary under the selected prefix, skips rebuilds when the source install is already current, and can be rerun later for updates. It runs as your normal user and uses sudo only for the final system-wide install step.
mkdir -p ~/.local/bin
export PATH="$HOME/.local/bin:$PATH"
nano ~/.local/bin/update-siege-source
#!/usr/bin/env bash
set -euo pipefail
usage() {
printf 'Usage: %s [system|--local] [--force]\n' "$0"
}
die() {
printf 'Error: %s\n' "$*" >&2
exit 1
}
require_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
die "Missing required command: $1. Install dependencies with: sudo apt install build-essential libssl-dev zlib1g-dev wget"
fi
}
version_from_binary() {
binary=$1
if [ ! -x "$binary" ]; then
printf 'none\n'
return
fi
version_output=$("$binary" --version 2>&1 || true)
version=$(printf '%s\n' "$version_output" | sed -n 's/^SIEGE //p' | sed -n '1p')
if [ -n "$version" ]; then
printf '%s\n' "$version"
else
printf 'unknown\n'
fi
}
mode=system
force=no
for arg in "$@"; do
case "$arg" in
system)
mode=system
;;
--local | local)
mode=local
;;
--force)
force=yes
;;
-h | --help)
usage
exit 0
;;
*)
usage >&2
exit 2
;;
esac
done
if [ "$EUID" -eq 0 ]; then
die 'Run this helper as your normal user, not with sudo.'
fi
# Resolve the install prefix and privilege boundary.
case "$mode" in
system)
prefix=/usr/local
install_cmd=(sudo make install)
require_cmd sudo
;;
local)
prefix=$HOME/.local
install_cmd=(make install)
;;
esac
for cmd in wget tar make gcc nproc sed find mktemp; do
require_cmd "$cmd"
done
build_dir=$(mktemp -d "${TMPDIR:-/tmp}/siege-build.XXXXXX")
trap 'rm -rf "$build_dir"' EXIT
# Download and inspect the current source archive.
archive=$build_dir/siege-latest.tar.gz
wget -q -O "$archive" https://download.joedog.org/siege/siege-latest.tar.gz
tar -xzf "$archive" -C "$build_dir"
src_dir=$(find "$build_dir" -mindepth 1 -maxdepth 1 -type d -name 'siege-*' -print -quit)
[ -n "$src_dir" ] || die 'Could not find the extracted Siege source directory.'
configure_script=$src_dir/configure
[ -f "$configure_script" ] || die 'The extracted source tree does not contain a configure script.'
latest_version=$(sed -n "s/^PACKAGE_VERSION='\\([^']*\\)'.*/\\1/p" "$configure_script")
[ -n "$latest_version" ] || die 'Could not detect the Siege source version.'
installed_bin=$prefix/bin/siege
current_version=$(version_from_binary "$installed_bin")
printf 'Install mode: %s\n' "$mode"
printf 'Install prefix: %s\n' "$prefix"
printf 'Current source version: %s\n' "$current_version"
printf 'Latest source version: %s\n' "$latest_version"
# Skip rebuilds when the selected prefix already has the latest source build.
if [ "$current_version" = "$latest_version" ] && [ "$force" = no ]; then
printf 'Siege source build is already current.\n'
exit 0
fi
# Build and install from the temporary workspace.
cd "$src_dir"
./configure --prefix="$prefix"
make -j"$(nproc)"
"${install_cmd[@]}"
installed_version=$(version_from_binary "$installed_bin")
[ "$installed_version" = "$latest_version" ] || die "Installed version check failed: expected $latest_version, got $installed_version"
printf 'SIEGE %s\n' "$installed_version"
printf 'Installed binary: %s\n' "$installed_bin"
Make the helper executable and confirm your shell can find it. Review the chmod command guide if executable permission bits are unfamiliar.
chmod +x ~/.local/bin/update-siege-source
command -v update-siege-source
Run one install mode. The default mode installs Siege under /usr/local, which makes the source-built binary available system-wide:
update-siege-source
Use the local mode when you want the source build under your home directory instead:
update-siege-source --local
The helper uses wget to download the upstream archive and tar to extract it in a temporary workspace. See the wget command examples for downloader options and the gz and tgz extraction guide for the archive format.
A successful user-local run begins with the version comparison and ends with the installed binary path after the normal configure and make output:
Install mode: local Install prefix: /home/username/.local Current source version: none Latest source version: 4.1.7 SIEGE 4.1.7 Installed binary: /home/username/.local/bin/siege
A no-op run exits before rebuilding when the installed source version already matches the latest tarball:
Install mode: local Install prefix: /home/username/.local Current source version: 4.1.7 Latest source version: 4.1.7 Siege source build is already current.
The user-local mode installs under ~/.local. Add ~/.local/bin to your shell profile only if that directory is not already active in new terminal sessions.
Verify the source build and confirm which binary your shell resolves:
command -v siege
siege --version
A current upstream build reports the upstream version from the JoeDog tarball, such as SIEGE 4.1.7. The source install also places helper files such as bombardment, siege.config, siege2csv.pl, siegerc, and urls.txt under the selected prefix.
Debian 12 and Debian 13 can show OpenSSL deprecation warnings while compiling Siege 4.1.7. Those warnings do not stop a successful build. Missing headers, configure failures, or make errors need fixing before installing.
Configure Siege on Debian
Siege stores per-user settings in ~/.siege/siege.conf. Display the active configuration with:
siege -C
The output shows the active version, HTTP protocol mode, default concurrency, timeout, delay, log path, and resource file. Debian package builds normally show /var/log/siege.log as the default log path, while source builds use the log path compiled for the selected prefix.
Edit the user configuration only when you want new defaults for every Siege run:
nano ~/.siege/siege.conf
| Setting | Purpose | When to Change It |
|---|---|---|
concurrent | Default number of simulated users | Increase it for larger tests after checking client and server limits |
delay | Random delay between requests | Use it for more realistic user pacing instead of pure benchmark traffic |
timeout | Socket timeout in seconds | Raise it for slow internal applications or long-running endpoints |
logging | Persistent test-result logging | Enable it when you need historical comparison across repeated tests |
Use Siege for Load Testing
Run Siege only against systems you own or are explicitly authorized to test. High-concurrency benchmark traffic against third-party services can violate terms of service and can look like abusive traffic.
Replace the example hostnames with a local service, staging site, or production endpoint approved for testing. Reserved example.test hostnames are placeholders, not runnable public targets.
Run a Fixed Request Count Test
The -c option sets concurrent users, and -r sets repetitions per user. This example sends 50 total requests with 10 concurrent users:
siege -c 10 -r 5 https://app.example.test/
Run a Timed Siege Test
Use -t for timed tests. Siege accepts S for seconds, M for minutes, and H for hours:
siege -c 25 -t 1M https://app.example.test/
Use Benchmark Mode Carefully
Benchmark mode disables the normal delay between requests and pushes harder against the target server:
siege -b -c 50 -t 30S https://app.example.test/
Start with modest concurrency, watch server metrics, and increase load gradually. Benchmark mode is useful for controlled capacity checks, but it is a poor default for shared production systems.
Test Multiple URLs from a File
Create a URL list when the test should cover several pages or endpoints:
nano ~/urls.txt
https://app.example.test/ https://app.example.test/about https://app.example.test/contact https://app.example.test/api/status
Run Siege with -f to read that file:
siege -c 20 -t 2M -f ~/urls.txt
Add -i when you want internet simulation mode, which randomizes URL selection and adds more natural pacing:
siege -i -c 20 -t 5M -f ~/urls.txt
Send Custom Headers
Use -H for headers required by an API, staging environment, or authenticated test endpoint:
siege -c 10 -t 30S \
-H "Authorization: Bearer replace-with-test-token" \
-H "Content-Type: application/json" \
https://api.example.test/endpoint
Write JSON or Log Output
Use JSON output when another script needs the final statistics:
siege -q -j -c 10 -r 5 https://app.example.test/
Use --log when you want a reusable result file:
siege --log="$HOME/siege-results.log" -c 25 -t 1M https://app.example.test/
Read Siege Result Metrics
Siege prints a final statistics block after each run. Focus on trends between comparable tests rather than treating one result as a universal performance score.
| Metric | Meaning | How to Use It |
|---|---|---|
| Transactions | Completed HTTP requests | Compare it only with the same test duration and concurrency |
| Availability | Percentage of successful requests | Investigate any drop below 100% during controlled tests |
| Response time | Average request completion time | Compare before and after application, cache, or server changes |
| Transaction rate | Requests completed per second | Use it as a throughput trend, not a cross-site benchmark |
| Concurrency | Average simultaneous active connections | Low values can mean the target responds too quickly to keep users active or the client cannot generate enough load |
| Failed transactions | HTTP failures, connection failures, or timeouts | Use the first failures as a troubleshooting trigger before increasing load |
Update or Remove Siege on Debian
Update APT-Installed Siege
APT-installed Siege updates with normal package upgrades. To target only the Siege package after refreshing metadata, run:
sudo apt update
sudo apt install --only-upgrade siege
Update Source-Built Siege
Source builds are not tracked by APT. Rerun the helper from the source-build section when you want to check for a newer upstream tarball. Use the same mode you used for the original source install.
For a system-wide source install, run:
update-siege-source
For a user-local source install, run:
update-siege-source --local
Do not run source-build updates from cron by default. Source builds can expose compiler warnings, dependency changes, and upstream failures that should be reviewed before a newer binary replaces the current one.
Remove APT-Installed Siege
Remove the Debian package with APT:
sudo apt remove --purge siege
Remove Source-Built Siege
For a system-wide source install under /usr/local, remove the binaries, default config files, and man pages created by the source install. The upstream uninstall target can leave default URL and man page files behind, so direct cleanup is more predictable.
sudo rm -f /usr/local/bin/siege /usr/local/bin/bombardment /usr/local/bin/siege.config /usr/local/bin/siege2csv.pl
sudo rm -f /usr/local/etc/siegerc /usr/local/etc/urls.txt
sudo rm -f /usr/local/share/man/man1/siege.1 /usr/local/share/man/man1/bombardment.1 /usr/local/share/man/man1/siege.config.1 /usr/local/share/man/man1/siege2csv.1
For a user-local source install, remove the same files from ~/.local:
rm -f "$HOME/.local/bin/siege" "$HOME/.local/bin/bombardment" "$HOME/.local/bin/siege.config" "$HOME/.local/bin/siege2csv.pl"
rm -f "$HOME/.local/etc/siegerc" "$HOME/.local/etc/urls.txt"
rm -f "$HOME/.local/share/man/man1/siege.1" "$HOME/.local/share/man/man1/bombardment.1" "$HOME/.local/share/man/man1/siege.config.1" "$HOME/.local/share/man/man1/siege2csv.1"
Then clear the shell command cache and verify what remains on PATH:
hash -r
command -v siege
If command -v siege still prints a path, another Siege install remains. That may be the Debian package, another source prefix, or a manually copied binary.
Remove User Configuration
The next command permanently deletes your Siege user configuration, URL lists, and local settings under
~/.siege. Back up anything you want to keep first.
rm -rf ~/.siege
Remove the update helper if you created it, then clear the shell command cache:
rm -f ~/.local/bin/update-siege-source
hash -r
Troubleshoot Siege on Debian
Connection Refused or Timeout Errors
First, make a low-impact header request with Siege itself:
siege -g https://app.example.test/
If the target is unreachable, fix DNS, firewall, listener, or TLS routing before increasing load. If the header request works but normal tests fail, the application, reverse proxy, or security layer may be rate-limiting the Siege user agent. For deeper HTTP diagnostics, use curl command checks against the same endpoint.
Too Many Open Files
High concurrency can exceed the current shell’s file descriptor limit. Check the current soft limit first:
ulimit -n
Raise it temporarily for the current shell when your hard limit allows it:
ulimit -n 65535
If that command fails, your user or service session has a lower hard limit. Increase limits through your login manager, systemd unit, or /etc/security/limits.conf path that matches how the test process starts.
Missing Source Build Configuration
A source install should create siegerc and urls.txt under the selected prefix. If a source-built binary reports that it cannot open /usr/local/etc/siegerc, verify the file exists:
ls -l /usr/local/etc/siegerc /usr/local/etc/urls.txt
If the files are missing, return to the source directory and rerun the install step for the prefix you configured:
sudo make install
SSL Certificate Failures
Expired, self-signed, or untrusted certificates can cause HTTPS tests to fail before the application receives load. For realistic production-style results, fix the certificate chain or install the internal CA certificate on the client instead of bypassing TLS checks.
Conclusion
Siege is installed on Debian with either APT-managed updates or a verified source-build path. Start with small authorized tests, confirm the active binary when methods overlap, and keep source-built installs documented so updates and cleanup remain predictable.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>