π Protocol Agnostic - Currently supporting HTTP, HTTPS, HTTP/2. Other protocols are on the way.
π Scenario-Based - Create your flow in a JSON file. Without a line of code!
π Different Load Types - Test your system's limits across different load types.
π Parameterization - Use dynamic variables just like on Postman.
π Correlation - Extract variables from earlier phases and pass them on to the following ones.
π Test Data - Import test data from CSV and use it in the scenario.
ddosify
is available via Docker, Docker Extension, Homebrew Tap, and downloadable pre-compiled binaries from the releases page for macOS, Linux and Windows.
docker run -it --rm ddosify/ddosify
Run Ddosify open-source on Docker Desktop with Ddosify Docker extension. More: https://hub.docker.com/extensions/ddosify/ddosify-docker-extension
brew install ddosify/tap/ddosify
- For arm architectures change
ddosify_amd64
toddosify_arm64
orddosify_armv6
. - Superuser privilege is required.
# For Redhat based (Fedora, CentOS, RHEL, etc.)
rpm -i https://github.com/ddosify/ddosify/releases/latest/download/ddosify_amd64.rpm
# For Debian based (Ubuntu, Linux Mint, etc.)
wget https://github.com/ddosify/ddosify/releases/latest/download/ddosify_amd64.deb
dpkg -i ddosify_amd64.deb
# For Alpine
wget https://github.com/ddosify/ddosify/releases/latest/download/ddosify_amd64.apk
apk add --allow-untrusted ddosify_amd64.apk
# For Arch Linux
git clone https://aur.archlinux.org/ddosify.git
cd ddosify
makepkg -sri
# For FreeBSD
pkg install ddosify
Windows exe from the releases page
- Download *.zip file for your architecture. For example download ddosify version vx.x.x with amd64 architecture: ddosify_x.x.x.zip_windows_amd64
- Unzip
ddosify_x.x.x_windows_amd64.zip
- Open Powershell or CMD (Command Prompt) and change directory to unzipped folder:
ddosify_x.x.x_windows_amd64
- Run ddosify:
.\ddosify.exe -t http://target_site.com
- The script requires root or sudo privileges to move ddosify binary to
/usr/local/bin
. - The script attempts to detect your operating system (macOS or Linux) and architecture (arm64, x86, amd64) to download the appropriate binary from the releases page.
- By default, the script installs the latest version of
ddosify
. - If you have problems, check common issues
- Required packages:
curl
andsudo
curl -sSfL https://raw.githubusercontent.com/ddosify/ddosify/master/scripts/install.sh | sh
Minimum supported Go version is 1.18
go install -v go.ddosify.com/ddosify@latest
This section aims to show you how to use Ddosify without deep dive into its details easily.
-
ddosify -t http://target_site.com
The above command runs a load test with the default value that is 100 requests in 10 seconds.
-
ddosify -t http://target_site.com -n 1000 -d 20 -m PUT -T 7 -P http://proxy_server.com:80
Ddosify sends a total of 1000 PUT requests to https://target_site.com over proxy http://proxy_server.com:80 in 20 seconds with a timeout of 7 seconds per request.
-
ddosify -t http://target_site.com -o stdout-json | jq .avg_duration
Ddosify outputs the result in JSON format. Then
jq
(or any other command-line JSON processor) fetches theavg_duration
. The rest depends on your CI/CD flow logic. -
ddosify -config config_examples/config.json
Ddosify first sends HTTP/2 POST request to https://test_site1.com/endpoint_1 using basic auth credentials test_user:12345 over proxy http://proxy_host.com:proxy_port and with a timeout of 3 seconds. Once the response is received, HTTPS GET request will be sent to https://test_site1.com/endpoint_2 along with the payload included in config_examples/payload.txt file with a timeout of 2 seconds. This flow will be repeated 20 times in 5 seconds and response will be written to stdout.
-
ddosify -t http://target_site.com/{{_randomInt}} -d 10 -n 100 -h 'User-Agent: {{_randomUserAgent}}' -b '{"city": "{{_randomCity}}"}'
Ddosify sends a total of 100 GET requests to https://target_site.com/{{_randomInt}} in 10 seconds.
{{_randomInt}}
path generates random integers between 1 and 1000 in every request. Dynamic variables can be used in URL, headers, payload (body) and basic authentication. In this example, Ddosify generates a random user agent in the header and a random city in the body. The full list of the dynamic variables can be found in the docs. -
ddosify -config ddosify_config_correlation.json
Ddosify allows you to specify variables at the global level and use them throughout the scenario, as well as extract variables from previous steps and inject them to the next steps in each iteration individually. You can inject those variables in requests url, headers and payload(body). The example config can be found in correlation-config-example.
-
ddosify -config ddosify_data_csv.json
Ddosify allows you to load test data from a file, tag specific columns for later use. You can inject those variables in requests url, headers and payload(body). The example config can be found in test-data-example.
You can configure your load test by the CLI options or a config file. Config file supports more features than the CLI. For example, you can't create a scenario-based load test with CLI options.
ddosify [FLAG]
Flag | Description | Type | Default | Required? |
---|---|---|---|---|
-t |
Target website URL. Example: https://ddosify.com | string |
- | Yes |
-n |
Total iteration count | int |
100 |
No |
-d |
Test duration in seconds. | int |
10 |
No |
-m |
Request method. Available methods for HTTP(s) are GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS | string |
GET |
No |
-b |
The payload of the network packet. AKA body for the HTTP. | string |
- | No |
-a |
Basic authentication. Usage: -a username:password |
string |
- | No |
-h |
Headers of the request. You can provide multiple headers with multiple -h flag. Usage: -h 'Accept: text/html' |
string |
- | No |
-T |
Timeout of the request in seconds. | int |
5 |
No |
-P |
Proxy address as host:port. -P 'http://user:pass@proxy_host.com:port' |
string |
- | No |
-o |
Test result output destination. Supported outputs are [stdout, stdout-json] Other output types will be added. | string |
stdout |
No |
-l |
Type of the load test. Ddosify supports 3 load types. | string |
linear |
No |
--config |
Config File of the load test. | string |
- | No |
--version |
Prints version, git commit, built date (utc), go information and quit | - | - | No |
--cert_path |
A path to a certificate file (usually called 'cert.pem') | - | - | No |
--cert_key_path |
A path to a certificate key file (usually called 'key.pem') | - | - | No |
--debug |
Iterates the scenario once and prints curl-like verbose result. Note that this flag overrides json config. | bool |
false |
No |
ddosify -t http://target_site.com -l linear
Result:
Note: If the iteration count is too low for the given duration, the test might be finished earlier than you expect.
ddosify -t http://target_site.com -l incremental
Result:
ddosify -t http://target_site.com -l waved
Result:
Config file lets you use all capabilities of Ddosify.
The features you can use by config file;
- Scenario creation
- Custom load type creation
- Payload from a file
- Multipart/form-data payload
- Extra connection configuration, like keep-alive enable/disable logic
- HTTP2 support
Usage;
ddosify -config <json_config_path>
There is an example config file at config_examples/config.json. This file contains all of the parameters you can use. Details of each parameter;
-
iteration_count
optionalThis is the equivalent of the
-n
flag. The difference is that if you have multiple steps in your scenario, this value represents the iteration count of the steps. -
load_type
optionalThis is the equivalent of the
-l
flag. -
duration
optionalThis is the equivalent of the
-d
flag. -
manual_load
optionalIf you are looking for creating your own custom load type, you can use this feature. The example below says that Ddosify will run the scenario 5 times, 10 times, and 20 times, respectively along with the provided durations.
iteration_count
andduration
will be auto-filled by Ddosify according tomanual_load
configuration. In this example,iteration_count
will be 35 and theduration
will be 18 seconds. Alsomanual_load
overridesload_type
if you provide both of them. As a result, you don't need to provide these 3 parameters when usingmanual_load
."manual_load": [ {"duration": 5, "count": 5}, {"duration": 6, "count": 10}, {"duration": 7, "count": 20} ]
-
proxy
optionalThis is the equivalent of the
-P
flag. -
output
optionalThis is the equivalent of the
-o
flag. -
env
optional Scenario-scoped global variables. Note that dynamic variables changes every iteration."env": { "COMPANY_NAME" :"Ddosify", "randomCountry" : "{{_randomCountry}}" }
-
data
optional Config for loading test data from a csv file. Csv data used in below config."data":{ "info": { "path" : "config/config_testdata/test.csv", "delimiter": ";", "vars": { "0":{"tag":"name"}, "1":{"tag":"city"}, "2":{"tag":"team"}, "3":{"tag":"payload", "type":"json"}, "4":{"tag":"age", "type":"int"} }, "allow_quota" : true, "order": "sequential", "skip_first_line" : true, "skip_empty_line" : true } }
Field Description Type Default Required? path
Local path or remote url for your csv file string
- Yes delimiter
Delimiter for reading csv string
,
No vars
Tag columns using column index as key, use type
field if you want to cast a column to a specific type, default isstring
, can be one of the following:json
,int
,float
,bool
.map
- Yes allow_quota
If set to true, a quote may appear in an unquoted field and a non-doubled quote may appear in a quoted field bool
false
No order
Order of reading records from csv. Can be random
orsequential
string
random
No skip_first_line
Skips first line while reading records from csv. bool
false
No skip_empty_line
Skips empty lines while reading records from csv. bool
true
No -
steps
mandatoryThis parameter lets you create your scenario. Ddosify runs the provided steps, respectively. For the given example file step id: 2 will be executed immediately after the response of step id: 1 is received. The order of the execution is the same as the order of the steps in the config file.
Details of each parameter for a step;
-
id
mandatoryEach step must have a unique integer id.
-
url
mandatoryThis is the equivalent of the
-t
flag. -
Name of the step.
-
method
optionalThis is the equivalent of the
-m
flag. -
headers
optionalList of headers with key:value format.
-
payload
optionalThis is the equivalent of the
-b
flag. -
payload_file
optionalIf you need a long payload, we suggest using this parameter instead of
payload
. -
Use this for
multipart/form-data
Content-Type.Accepts list of
form-field
objects, structured as below;{ "name": [field-name], "value": [field-value|file-path|url], "type": <text|file>, // Default "text" "src": <local|remote> // Default "local" }
Example: Sending form name-value pairs;
"payload_multipart": [ { "name": "[field-name]", "value": "[field-value]" } ]
Example: Sending form name-value pairs and a local file;
"payload_multipart": [ { "name": "[field-name]", "value": "[field-value]", }, { "name": "[field-name]", "value": "./test.png", "type": "file" } ]
Example: Sending form name-value pairs and a local file and a remote file;
"payload_multipart": [ { "name": "[field-name]", "value": "[field-value]", }, { "name": "[field-name]", "value": "./test.png", "type": "file" }, { "name": "[field-name]", "value": "http://test.com/test.png", "type": "file", "src": "remote" } ]
Note: Ddosify adds
Content-Type: multipart/form-data; boundary=[generated-boundary-value]
header to the request when usingpayload_multipart
. -
timeout
optionalThis is the equivalent of the
-T
flag. -
capture_env
optionalConfig for extraction of variables to use them in next steps. Example: Capture NUM variable from steps response body;
"steps": [ { "id": 1, "url": "http://target.com/endpoint1", "capture_env": { "NUM" :{"from":"body","jsonPath":"num"}, } }, ]
-
Sleep duration(ms) before executing the next step. Can be an exact duration or a range.
Example: Sleep 1000ms after step-1;
"steps": [ { "id": 1, "url": "http://target.com/endpoint1", "sleep": "1000" }, { "id": 2, "url": "http://target.com/endpoint2", } ]
Example: Sleep between 300ms-500ms after step-1;
"steps": [ { "id": 1, "url": "http://target.com/endpoint1", "sleep": "300-500" }, { "id": 2, "url": "http://target.com/endpoint2", } ]
-
auth
optionalBasic authentication.
"auth": { "username": "test_user", "password": "12345" }
-
others
optionalThis parameter accepts dynamic key: value pairs to configure connection details of the protocol in use.
"others": { "keep-alive": true, // Default true "disable-compression": false, // Default true "h2": true, // Enables HTTP/2. Default false. "disable-redirect": true // Default false }
-
Just like the Postman, Ddosify supports parameterization (dynamic variables) on URL, headers, payload (body) and basic authentication. Actually, we support all the random methods Postman supports. If you use {{$randomVariable}}
on Postman you can use it as {{_randomVariable}}
on Ddosify. Just change $
to _
and you will be fine. To simulate a realistic load test on your system, Ddosify can send every request with dynamic variables.
The full list of dynamic variables can be found in the Ddosify Docs.
Ddosify sends 100 GET requests in 10 seconds with random string key
parameter. This approach can be also used in cache bypass.
ddosify -t http://target_site.com/?key={{_randomString}} -d 10 -n 100
Ddosify sends 100 GET requests in 10 seconds with random Transaction-Type
and Country
headers.
ddosify -t http://target_site.com -d 10 -n 100 -h 'Transaction-Type: {{_randomTransactionType}}' -h 'Country: {{_randomCountry}}'
Ddosify sends 100 GET requests in 10 seconds with random latitude
and longitude
values in body.
ddosify -t http://target_site.com -d 10 -n 100 -b '{"latitude": "{{_randomLatitude}}", "longitude": "{{_randomLongitude}}"}'
Ddosify sends 100 GET requests in 10 seconds with random username
and password
with basic authentication.
ddosify -t http://target_site.com -d 10 -n 100 -a '{{_randomUserName}}:{{_randomPassword}}'
Dynamic variables can be used on config file as well. Ddosify sends 100 GET requests in 10 seconds with random string key
parameter in URL and random User-Key
header.
ddosify -config ddosify_config_dynamic.json
{
"iteration_count": 100,
"load_type": "linear",
"duration": 10,
"steps": [
{
"id": 1,
"url": "https://test_site1.com/?key={{_randomString}}",
"method": "POST",
"headers": {
"User-Key": "{{_randomInt}}"
}
}
]
}
Ddosify enables you to capture variables from steps using jsonPath, xpath, or regular expressions. Later, in the subsequent steps, you can inject both the captured variables and the scenario-scoped global variables.
β οΈ Points to keep in mind
- You must specify 'header_key' when capturing from header.
- For jsonPath syntax, please take a look at gjson syntax doc.
- Regular expression are expected in 'Golang' style regex. For converting your existing regular expressions, you can use regex101.
You can use debug parameter to validate your config.
ddosify -config ddosify_config_correlation.json -debug
{
"steps": [
{
"capture_env": {
"NUM" :{"from":"body","jsonPath":"num"},
"NAME" :{"from":"body","jsonPath":"name"},
"SQUAD" :{"from":"body","jsonPath":"squad"},
"PLAYERS" :{"from":"body","jsonPath":"squad.players"},
"MESSI" : {"from":"body","jsonPath":"squad.players.0"},
}
}
]
}
{
"steps": [
{
"capture_env": {
"TITLE" :{"from":"body","xpath":"//item/title"},
}
}
]
}
{
"steps": [
{
"capture_env": {
"CONTENT_TYPE" :{"from":"header", "header_key":"Content-Type" ,"regexp":{"exp":"application\/(\\w)+","matchNo":0}} ,
"REGEX_MATCH_ENV" :{"from":"body","regexp":{"exp" : "[a-z]+_[0-9]+", "matchNo": 1}}
}
}
]
}
{
"steps": [
{
"capture_env": {
"TOKEN" :{"from":"header", "header_key":"Authorization"},
}
}
]
}
{
"env":{
"TARGET_URL" : "http://localhost:8084/hello",
"USER_KEY" : "ABC",
"COMPANY_NAME" : "Ddosify",
"RANDOM_COUNTRY" : "{{_randomCountry}}",
"NUMBERS" : [22,33,10,52]
},
}
On array-like captured variables or environment vars, the rand( ) function can be utilized.
// ddosify_config_correlation.json
{
"iteration_count": 100,
"load_type": "linear",
"duration": 10,
"steps": [
{
"id": 1,
"url": "{{TARGET_URL}}",
"method": "POST",
"headers": {
"User-Key": "{{USER_KEY}}",
"Rand-Selected-Num" : "{{rand(NUMBERS)}}"
},
"payload" : "{{COMPANY_NAME}}",
"capture_env": {
"NUM" :{"from":"body","jsonPath":"num"},
"NAME" :{"from":"body","jsonPath":"name"},
"SQUAD" :{"from":"body","jsonPath":"squad"},
"PLAYERS" :{"from":"body","jsonPath":"squad.players"},
"MESSI" : {"from":"body","jsonPath":"squad.players.0"},
"TOKEN" :{"from":"header", "header_key":"Authorization"},
"CONTENT_TYPE" :{"from":"header", "header_key":"Content-Type" ,"regexp":{"exp":"application\/(\\w)+","matchNo":0}}
}
},
{
"id": 2,
"url": "{{TARGET_URL}}",
"method": "POST",
"headers": {
"User-Key": "{{USER_KEY}}",
"Authorization": "{{TOKEN}}",
"Content-Type" : "{{CONTENT_TYPE}}"
},
"payload_file" : "payload.json",
"capture_env": {
"TITLE" :{"from":"body","xpath":"//item/title"},
"REGEX_MATCH_ENV" :{"from":"body","regexp":{"exp" : "[a-z]+_[0-9]+", "matchNo": 1}}
}
}
],
"env":{
"TARGET_URL" : "http://localhost:8084/hello",
"USER_KEY" : "ABC",
"COMPANY_NAME" : "Ddosify",
"RANDOM_COUNTRY" : "{{_randomCountry}}",
"NUMBERS" : [22,33,10,52]
},
}
// payload.json
{
"boolField" : "{{_randomBoolean}}",
"numField" : "{{NUM}}",
"strField" : "{{NAME}}",
"numArrayField" : ["{{NUM}}",34],
"strArrayField" : ["{{NAME}}","hello"],
"mixedArrayField" : ["{{NUM}}",34,"{{NAME}}","{{SQUAD}}"],
"{{NAME}}" : "messi",
"obj" :{
"numField" : "{{NUM}}",
"objectField" : "{{SQUAD}}",
"arrayField" : "{{PLAYERS}}"
}
}
Ddosify enables you to load test data from csv files. Later, in your scenario, you can inject variables that you tagged.
We are using this csv data in below config.
// config_data_csv.json
"data":{
"csv_test": {
"path" : "config/config_testdata/test.csv",
"delimiter": ";",
"vars": {
"0":{"tag":"name"},
"1":{"tag":"city"},
"2":{"tag":"team"},
"3":{"tag":"payload", "type":"json"},
"4":{"tag":"age", "type":"int"}
},
"allow_quota" : true,
"order": "random",
"skip_first_line" : true
}
}
You can refer to tagged variables in your request like below.
// payload.json
{
"name" : "{{data.csv_test.name}}",
"team" : "{{data.csv_test.team}}",
"city" : "{{data.csv_test.city}}",
"payload" : "{{data.csv_test.payload}}",
"age" : "{{data.csv_test.age}}"
}
"ddosify" canβt be opened because Apple cannot check it for malicious software.
- Open
/usr/local/bin
- Right click
ddosify
and select Open - Select Open
- Close the opened terminal
You can join our Discord Server for issues, feature requests, feedbacks or anything else.
This repository includes the single-node version of the Ddosify Loader. For distributed and Geo-targeted Load Testing you can use Ddosify Cloud
Ddosify is created for testing the performance of web applications. Users must be the owner of the target system. Using it for harmful purposes is extremely forbidden. Ddosify team & company is not responsible for itsβ usages and consequences.
Licensed under the AGPLv3: https://www.gnu.org/licenses/agpl-3.0.html