Operating
Load Testing
Learn to perform load testing on your Blnk server using k6.
Use load testing to ensure that your Blnk deployment can handle expected traffic and maintain performance under various conditions. This is a critical step in setting up your Blnk server.
Blnk includes a comprehensive load testing suite built with k6, a modern load testing tool. This guide walks you through finding, configuring, and running load tests to validate your Blnk server’s performance across different scenarios.
Before you start
Make sure you have:
- Cloned the Blnk repository to your local machine
- Docker and Docker Compose installed, for running the Blnk server
- k6 installed on your machine. Visit k6.io for installation instructions
- Your Blnk server running and accessible
Getting started
You can find the load test files in the tests/loadtest directory of the Blnk repository. Navigate to this directory to access all available test scripts:
cd tests/loadtest
Main test script
The primary load test script (script.js) supports seven configurable load-testing scenarios, each controlled via environment variables.
Each scenario targets a specific aspect of your Blnk server’s transaction performance, allowing you to test different load patterns and system behaviors.
Every request is posted with inflight: true and skip_queue: false unless you override INFLIGHT or SKIP_QUEUE.
- Baseline: Steady, constant load to measure normal performance.
- Ramp: Gradually increasing load to find when your server struggles.
- Contention: Tests when one balance gets most of the traffic.
- Hot source: One balance funding many destinations (
A → N). - Hot destination: Many balances funding one destination (
N → A). - Soak: Long-duration test (2 hours) to find memory leaks and stability issues.
- Spike: Sudden traffic surge to test recovery behavior.
Use the SCENARIO environment variable to select which scenario to run. Each scenario has specific configuration options:
Runs a steady, constant load to measure your server’s normal performance. Use this to see how fast your server responds under normal conditions.
k6 run --env URL=http://localhost:5001/transactions --env SCENARIO=baseline --env VUS=100 --env DURATION=5m script.jsVUSinteger
Number of virtual users to run concurrently
DURATIONstring
Test duration (e.g., “5m”, ”30s”, “1h”)
Slowly increases traffic over time to find when your server starts to struggle. Starts with 100 users and gradually increases to 1000 users across three stages.
k6 run --env URL=http://localhost:5001/transactions --env SCENARIO=ramp \
--env START_VUS=100 \
--env VUS1=300 --env STAGE1=5m \
--env VUS2=600 --env STAGE2=5m \
--env VUS3=1000 --env STAGE3=5m \
script.jsSTART_VUSinteger
Initial number of virtual users at the start of the test
VUS1integer
Target number of virtual users for the first ramp stage
STAGE1string
Duration of the first ramp stage
VUS2integer
Target number of virtual users for the second ramp stage
STAGE2string
Duration of the second ramp stage
VUS3integer
Target number of virtual users for the third ramp stage
STAGE3string
Duration of the third ramp stage
Tests what happens when one balance gets most of the traffic while others get less. This simulates real-world scenarios where some accounts are much busier than others.
k6 run --env URL=http://localhost:5001/transactions --env SCENARIO=contention \
--env HOT_DEST=@hot-balance-0001 \
--env HOT_RPS=308 \
--env RANDOM_RPS=132 \
--env DURATION=5m \
--env VUS=200 \
--env MAX_VUS=800 \
script.jsHOT_DESTstring
The balance identifier that receives concentrated traffic (70% of requests)
HOT_RPSinteger
Requests per second targeting the hot balance
RANDOM_RPSinteger
Requests per second targeting random balances
DURATIONstring
Test duration (e.g., “5m”, ”30s”, “1h”)
VUSinteger
Number of pre-allocated virtual users
MAX_VUSinteger
Maximum number of virtual users that can be allocated
Tests one balance funding many others (A → N), such as a payout or treasury account. Every transaction draws from the same source and credits a new destination.
k6 run --env URL=http://localhost:5001/transactions --env SCENARIO=hot_source \
--env HOT_SOURCE=@hot-source-0001 \
--env RATE=300 \
--env DURATION=5m \
--env VUS=200 \
--env MAX_VUS=800 \
--env SOURCE_BUCKETS=1 \
script.jsHOT_SOURCEstring
The balance identifier that funds every transaction
RATEinteger
Requests per second targeting the hot source
DURATIONstring
Test duration (e.g., “5m”, ”30s”, “1h”)
VUSinteger
Number of pre-allocated virtual users
MAX_VUSinteger
Maximum number of virtual users that can be allocated
SOURCE_BUCKETSinteger
Number of shards to split the hot source across. Values above 1 spread traffic over @hot-source-0001-bucket-1 through -bucket-N
Tests many balances funding one (N → A), such as a collections or settlement account. Every transaction debits a new source and credits the same destination.
k6 run --env URL=http://localhost:5001/transactions --env SCENARIO=hot_destination \
--env HOT_DEST=@hot-balance-0001 \
--env RATE=300 \
--env DURATION=5m \
--env VUS=200 \
--env MAX_VUS=800 \
--env DESTINATION_BUCKETS=1 \
script.jsHOT_DESTstring
The balance identifier that receives every transaction
RATEinteger
Requests per second targeting the hot destination
DURATIONstring
Test duration (e.g., “5m”, ”30s”, “1h”)
VUSinteger
Number of pre-allocated virtual users
MAX_VUSinteger
Maximum number of virtual users that can be allocated
DESTINATION_BUCKETSinteger
Number of shards to split the hot destination across. Values above 1 spread traffic over @hot-balance-0001-bucket-1 through -bucket-N
Runs a steady load for a long time (default: 2 hours) to check if your server has memory leaks or other problems that only show up after running for a while.
k6 run --env URL=http://localhost:5001/transactions --env SCENARIO=soak --env VUS=200 --env DURATION=2h script.jsVUSinteger
Number of virtual users to run concurrently
DURATIONstring
Test duration (e.g., “5m”, ”30s”, “1h”, “2h”)
Simulates a sudden traffic spike to see if your server can handle the surge and recover afterward.
k6 run --env URL=http://localhost:5001/transactions --env SCENARIO=spike \
--env BASE_RPS=200 \
--env SPIKE_RPS=600 \
--env WARM=2m \
--env PEAK=1m \
--env COOL=3m \
--env PRE_VUS=300 \
--env MAX_VUS=1200 \
script.jsBASE_RPSinteger
Baseline requests per second during warm-up and recovery phases
SPIKE_RPSinteger
Peak requests per second during spike phase
WARMstring
Duration of warm-up phase before spike
PEAKstring
Duration of spike phase
COOLstring
Duration of recovery phase after spike
PRE_VUSinteger
Number of pre-allocated virtual users
MAX_VUSinteger
Maximum number of virtual users that can be allocated during the spike
Understanding test results
k6 provides comprehensive metrics for each test run. Key metrics to monitor include:
- http_req_duration: Request latency (p50, p95, p99 percentiles)
- http_req_failed: Error rate (should be < 0.1%)
- http_reqs: Total requests processed
- vus: Virtual users active during the test
Performance thresholds
The main test script (script.js) includes built-in performance thresholds that automatically fail tests if exceeded:
- Error rate: Less than 0.1% (
http_req_failed < 0.001) - P95 latency: Less than 300ms
- P99 latency: Less than 600ms
Exporting results
The main test script automatically exports results to summary.json. Run any scenario:
k6 run --env SCENARIO=baseline script.jsResults are automatically saved to summary.json in the current directory.
Analyze results with TPM tool
The test suite includes a utility script to convert k6 JSON output into transactions per minute (TPM) CSV format.
First, export k6 results as JSON:
k6 run --out json=results.json --env SCENARIO=baseline script.jsThen convert to CSV:
python3 tools/k6_json_to_tpm.py results.json tpm_results.csvinput.jsonstring
Path to k6 JSON output file (use --out json=output.json when running k6)
output.csvstring
Path to output CSV file
The generated CSV includes: minute timestamp, requests, transactions per minute (tpm), success ratio, p50/p95/p99 latency, and apdex score.
Troubleshooting
Connection refused errors
If you see connection errors, verify:
- Your Blnk server is running and accessible.
- The URL matches your server’s address and port.
- Firewall rules allow connections to the Blnk server.
High error rates
If error rates exceed thresholds:
- Check Blnk server logs for errors.
- Verify database connection pool settings.
- Review server resource usage (CPU, memory).
- Consider reducing virtual users or request rate.