This guide helps you migrate from the legacy single-server configuration to the new multi-server architecture.
The multi-server feature allows you to generate and manage load test data for multiple NetSapiens target servers from a single installation. Key benefits include:
- Independent SEEDs: Each server has its own reproducible test data
- Isolated CSV files: Server-specific data organization prevents conflicts
- Port management: Automatic port offsets prevent conflicts when testing multiple servers
- Centralized management: Single codebase manages all target servers
Good news: Your existing single-server setup will continue to work without any changes! The system automatically detects whether you're using:
- Legacy mode: Single
.envfile withTARGET_SERVERandAPIKEY - Multi-server mode: New
servers.jsonconfiguration file
If you only need to test a single server, you don't need to change anything. Your existing setup will continue to work:
# Your existing workflow remains unchanged
node server.js
sipp/scripts/register_all.sh
sipp/scripts/inbound.sh US_EasternFollow these steps to enable multi-server support:
Copy the example configuration and customize it:
cp servers.json.example servers.jsonEdit servers.json with your server configurations:
{
"servers": [
{
"id": "prod1",
"hostname": "sas1.yourcompany.com",
"apikey": "nss_your_api_key_here",
"maxDomains": 50,
"peakCps": 10,
"registrationPct": 0.8,
"seed": 12345,
"description": "Production Server 1"
},
{
"id": "prod2",
"hostname": "sas2.yourcompany.com",
"apikey": "nss_another_api_key",
"maxDomains": 100,
"peakCps": 20,
"registrationPct": 0.9,
"seed": 67890,
"description": "Production Server 2"
}
]
}Important: Each server should have:
- Unique
id: Used for file organization and command-line arguments - Independent
seed: Ensures each server has distinct but reproducible test data - Server-specific settings:
maxDomains,peakCps,registrationPctcan differ per server
Field formats:
peakCps: Calls per second (supports decimals like 0.5 for low load)registrationPct: Fraction of devices to register, 0-1 range (e.g., 0.8 = 80%)maxDomains: Integer number of domains to generateseed: Integer seed for random data generation
The bash scripts use jq to parse servers.json:
Ubuntu/Debian:
sudo apt-get install jqmacOS:
brew install jqVerify installation:
jq --versionYou must explicitly specify which server to target:
# Generate data for prod1
node server.js --server prod1
# Generate data for prod2
node server.js --server prod2What happens:
- CSV files are created in
sipp/csv/servers/{server-id}/devices/andsipp/csv/servers/{server-id}/phonenumbers/ - Each server uses its own SEED for reproducible data
- Domains are independent across servers
Update your cron jobs or manual commands to specify the target server:
Registration:
# Legacy (still works)
sipp/scripts/register_all.sh
# Multi-server mode
sipp/scripts/register_all.sh --server prod1
sipp/scripts/register_all.sh --server prod2Inbound calling:
# Legacy (still works)
sipp/scripts/inbound.sh US_Eastern
# Multi-server mode
sipp/scripts/inbound.sh US_Eastern --server prod1
sipp/scripts/inbound.sh US_Pacific --server prod2sipp/csv/
├── devices/
│ ├── domain1.csv
│ └── domain2.csv
├── phonenumbers/
│ ├── US_Eastern.csv
│ └── US_Pacific.csv
├── random_caller_ids.csv
└── random_user_agents.csv
sipp/csv/
├── servers/
│ ├── prod1/
│ │ ├── devices/
│ │ │ ├── domain1.csv
│ │ │ └── domain2.csv
│ │ └── phonenumbers/
│ │ ├── US_Eastern.csv
│ │ └── US_Pacific.csv
│ └── prod2/
│ ├── devices/
│ └── phonenumbers/
├── random_caller_ids.csv (shared)
└── random_user_agents.csv (shared)
sipp/scripts/error_register.logsipp/scripts/register.logsipp/scripts/inbound_US_Eastern.log
sipp/scripts/error_register_prod1.logsipp/scripts/register_prod1.logsipp/scripts/inbound_prod1_US_Eastern.logsipp/scripts/error_register_prod2.logsipp/scripts/register_prod2.logsipp/scripts/inbound_prod2_US_Eastern.log
To prevent conflicts when running load tests against multiple servers simultaneously, the system automatically calculates port offsets:
- Legacy mode: Uses standard ports (6060, 8060, 20000, etc.)
- Multi-server mode: Adds server-specific offset based on server ID hash
Example for server prod1:
Base SIP port: 6060
Server offset: +2000 (calculated from hash of "prod1")
Actual SIP port: 8060
This allows multiple concurrent test runs without port conflicts.
# /etc/cron.d/netsapiens-loadgen
*/1 * * * * root cd /usr/local/NetSapiens/netsapiens-loadgenerator && sipp/scripts/register_all.sh
0,5,10... * * * * root cd /usr/local/NetSapiens/netsapiens-loadgenerator && sipp/scripts/inbound.sh "US_Eastern"Option A: Separate entries per server
# Prod1
*/1 * * * * root cd /usr/local/NetSapiens/netsapiens-loadgenerator && sipp/scripts/register_all.sh --server prod1
0,5,10... * * * * root cd /usr/local/NetSapiens/netsapiens-loadgenerator && sipp/scripts/inbound.sh "US_Eastern" --server prod1
# Prod2
*/1 * * * * root cd /usr/local/NetSapiens/netsapiens-loadgenerator && sipp/scripts/register_all.sh --server prod2
0,5,10... * * * * root cd /usr/local/NetSapiens/netsapiens-loadgenerator && sipp/scripts/inbound.sh "US_Eastern" --server prod2Option B: Wrapper script (create multi_server_wrapper.sh)
#!/bin/bash
SERVERS=$(jq -r '.servers[].id' servers.json)
for server in $SERVERS; do
echo "Running for server: $server"
sipp/scripts/register_all.sh --server "$server"
doneThen in cron:
*/1 * * * * root cd /usr/local/NetSapiens/netsapiens-loadgenerator && ./multi_server_wrapper.sh- Verify the server ID in
servers.jsonmatches the--serverargument - Check JSON syntax with
jq . servers.json
- Install jq:
sudo apt-get install jqorbrew install jq
- Run
node server.js --server <server-id>to generate data first - Verify the server ID matches your configuration
- Remove or rename
servers.json - System will automatically use
.envconfiguration
- Check if multiple instances are using the same server ID
- Verify port offset calculation in logs: "Port ranges - SIP: XXXX+"
- Ensure different server IDs to get different port offsets
If you need to revert to legacy mode:
-
Stop all load generation:
pkill -f sipp
-
Rename or remove servers.json:
mv servers.json servers.json.backup
-
Use legacy commands:
node server.js sipp/scripts/register_all.sh
-
Restore cron jobs to legacy format
The system will automatically detect the absence of servers.json and use .env configuration.
- Use descriptive server IDs:
prod1,staging,devinstead ofserver1,server2 - Keep independent SEEDs: Ensures reproducible but distinct data per server
- Document your configuration: Add meaningful
descriptionfields inservers.json - Test incrementally: Start with one server in multi-server mode before adding more
- Monitor logs separately: Use server-specific log files for easier debugging
- Version control: Commit
servers.json.examplebut notservers.json(contains API keys)
If you encounter issues during migration:
- Check the logs in
sipp/scripts/error_*.log - Verify
servers.jsonsyntax:jq . servers.json - Test data generation first:
node server.js --server <id> - Then test scripts:
sipp/scripts/register_all.sh --server <id> - Report issues at: https://github.com/anthropics/claude-code/issues