Comprehensive load testing suite for Stellar PolyMarket platform using Taurus framework.
This stress test suite validates platform performance under peak load conditions, identifying bottlenecks before they affect production users.
- Load: 500 concurrent users
- Duration: 60s ramp-up + 2m sustained load
- Target: Each user places 1 bet
- Success Criteria: Error rate < 1%, p95 latency < 2s
- Load: 50 concurrent market resolutions
- Duration: 10s ramp-up + 1m sustained load
- Target: Create, propose, and resolve markets
- Success Criteria: p95 latency < 5s, error rate < 1%
- Load: 1000 concurrent connections
- Duration: 30s ramp-up + 3m sustained
- Target: Maintain stable connections with polling
- Success Criteria: Connection success rate > 99%
- Python 3.8+
- Node.js 16+
- 4GB+ RAM available
- Backend server running on port 4000
- Install Python dependencies:
pip install -r requirements.txt- Verify Taurus installation:
bzt --version- Start the backend server:
cd backend
npm install
npm start- Verify backend is running:
curl http://localhost:4000/health# Run all stress tests
python3 run-stress-test.py# Run with default configuration
bzt stress-test.yml
# Run with custom report name
bzt stress-test.yml -o modules.blazemeter.report-name=my-test
# Run specific scenario only
bzt stress-test.yml -o execution[0].scenario=concurrent-bets# Test only concurrent bets
bzt stress-test.yml -o execution=[{concurrency:500,ramp-up:60s,hold-for:2m,scenario:concurrent-bets}]
# Test only market resolution
bzt stress-test.yml -o execution=[{concurrency:50,ramp-up:10s,hold-for:1m,scenario:market-resolution}]
# Test only WebSocket connections
bzt stress-test.yml -o execution=[{concurrency:1000,ramp-up:30s,hold-for:3m,scenario:websocket-connections}]- Definition: Requests per second (RPS) the system can handle
- Target: Maintain stable RPS throughout test duration
- Red Flag: Declining RPS indicates saturation
- Definition: 95% of requests complete within this time
- Target: < 2000ms for all endpoints
- Target (Resolution): < 5000ms for market resolution
- Red Flag: p95 > 2s indicates performance degradation
- Definition: Percentage of failed requests (4xx, 5xx)
- Target: < 1% across all scenarios
- Red Flag: > 1% indicates system instability
- Definition: Maximum simultaneous active users
- Target: 500 for bets, 1000 for WebSocket
- Red Flag: Connection failures or timeouts
After running tests, check stress-test-results/[timestamp]/:
kpi.jtl: Raw performance data (CSV format)error.jtl: Error logs and stack tracesbzt.log: Taurus execution log- HTML reports: Visual dashboards (if configured)
Cumulative stats:
Label Samples Avg Min Max p50 p90 p95 p99 Errors Throughput
place-bet 500 145ms 89ms 2341ms 132ms 198ms 287ms 1234ms 0.2% 8.3/s
resolve-market 50 892ms 234ms 4567ms 765ms 1234ms 2345ms 3456ms 0.0% 0.8/s
What to look for:
Avg: Average response time (lower is better)p95: 95th percentile (must be < 2000ms)Errors: Error percentage (must be < 1%)Throughput: Requests/second (higher is better)
The stress test runs automatically on PRs to main branch:
# .github/workflows/stress-test.yml
name: Stress Test
on:
pull_request:
branches: [main]
jobs:
stress-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: pip install -r requirements.txt
- name: Start backend
run: |
cd backend
npm install
npm start &
sleep 10
- name: Run stress tests
run: python3 run-stress-test.py
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: stress-test-results
path: stress-test-results/Tests automatically fail if:
- Average response time > 2000ms for 10+ seconds
- p95 latency > 2000ms
- Error rate > 1% for 10+ seconds
- Market resolution p95 > 5000ms
Symptom: Increasing latency, connection timeout errors
Fix:
// backend/src/db.js
const pool = new Pool({
max: 50, // Increase from default 10
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 5000,
});Symptom: Slow query performance under load
Fix:
-- Add indexes on frequently queried columns
CREATE INDEX idx_markets_resolved ON markets(resolved);
CREATE INDEX idx_bets_market_id ON bets(market_id);
CREATE INDEX idx_bets_wallet ON bets(wallet_address);Symptom: Low throughput despite low CPU usage
Fix:
// Use async/await properly, avoid blocking operations
// Bad: Synchronous file operations
// Good: Async database queries with connection poolingSymptom: Increasing memory usage, eventual crashes
Fix:
// Ensure proper cleanup of event listeners
// Use connection pooling instead of creating new connections
// Implement request timeoutsSymptom: High CPU/memory usage, system slowdown
Fix:
- Scale horizontally: Add more server instances
- Scale vertically: Increase CPU/RAM allocation
- Implement caching layer (Redis)
- Use CDN for static assets
Symptom: 429 errors, throttled requests
Fix:
// Implement proper rate limiting with Redis
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 100, // 100 requests per minute
standardHeaders: true,
});# Check if port 4000 is already in use
lsof -i :4000
# Kill existing process
kill -9 <PID>
# Restart backend
cd backend && npm start# Install with pip
pip install bzt
# Or use pipx for isolated installation
pipx install bzt
# Verify installation
bzt --version- Check backend logs for errors
- Verify database is running and accessible
- Ensure sufficient system resources
- Review
stress-test-results/*/error.jtlfor details
- Increase backend server resources
- Optimize database queries
- Add database indexes
- Implement caching
- Use connection pooling
- Concurrent Bets: 8-10 RPS, p95 < 500ms
- Market Resolution: 0.8-1.0 RPS, p95 < 3000ms
- WebSocket: 1000 concurrent connections, 99.9% success
- CPU: 4 cores @ 2.5GHz
- RAM: 8GB
- Disk: SSD
- Network: 100Mbps
Edit stress-test.yml to adjust:
concurrency: Number of concurrent usersramp-up: Time to reach peak loadhold-for: Duration at peak loaditerations: Number of times to repeat scenario
# Set custom backend URL
export BACKEND_URL=http://localhost:4000
# Set custom test duration
export TEST_DURATION=5m
# Run tests
bzt stress-test.yml- Run tests in isolated environment: Avoid running on production
- Monitor system resources: Use
htop,iostatduring tests - Baseline before changes: Run tests before and after code changes
- Gradual load increase: Use ramp-up to simulate realistic traffic
- Test regularly: Include in CI/CD pipeline
- Document results: Track performance trends over time
- Tests use synthetic data only
- No real user credentials or wallets
- Isolated test environment recommended
- Rate limiting should be disabled for stress tests
- Clean up test data after completion
For issues or questions:
- Check
bzt.login results directory - Review backend logs
- Consult Taurus documentation: https://gettaurus.org/docs/
- Open an issue in the repository
Same as main project license.