Artillery Cheat Sheet
Overview
Artillery is a modern, powerful, and developer-friendly load testing toolkit built on Node.js. It enables teams to test the performance and reliability of backend services, APIs, WebSocket servers, and more using declarative YAML-based test scripts. Artillery supports complex user scenarios with multiple phases, custom logic, and plugin extensibility.
Artillery integrates seamlessly into CI/CD pipelines and provides detailed performance reports with latency percentiles, throughput metrics, and error tracking. It supports HTTP, WebSocket, Socket.io, and gRPC protocols out of the box, and can be extended with custom engines for other protocols.
Installation
# Install globally via npm
npm install -g artillery
# Verify installation
artillery version
# Install with npx (no global install)
npx artillery --version
# Install Artillery Pro (cloud features)
npm install -g artillery-pro
# Install specific plugins
npm install -g artillery-plugin-expect
npm install -g artillery-plugin-metrics-by-endpoint
Core Commands
| Command | Description |
|---|---|
artillery run test.yml | Run a test script |
artillery quick --count 100 -n 50 URL | Quick test without a script |
artillery report report.json | Generate HTML report from JSON |
artillery run --output report.json test.yml | Run and save results to JSON |
artillery run --target https://api.example.com test.yml | Override target URL |
artillery run --environment staging test.yml | Use a named environment |
artillery run --dotenv .env.test test.yml | Load environment variables |
Test Script Structure
# test.yml
config:
target: "https://api.example.com"
phases:
- duration: 60
arrivalRate: 5
name: "Warm up"
- duration: 120
arrivalRate: 50
name: "Ramp up"
- duration: 300
arrivalRate: 100
name: "Sustained load"
defaults:
headers:
Content-Type: "application/json"
Authorization: "Bearer {{ $processEnvironment.API_TOKEN }}"
scenarios:
- name: "Browse and purchase"
flow:
- get:
url: "/products"
capture:
- json: "$.products[0].id"
as: "productId"
- think: 2
- get:
url: "/products/{{ productId }}"
- post:
url: "/cart"
json:
productId: "{{ productId }}"
quantity: 1
Phases Configuration
config:
phases:
# Constant arrival rate
- duration: 60
arrivalRate: 10
# Ramp up linearly
- duration: 120
arrivalRate: 10
rampTo: 100
# Pause between phases
- pause: 10
# Fixed number of virtual users
- duration: 60
arrivalCount: 500
Capturing and Reusing Data
scenarios:
- flow:
- post:
url: "/auth/login"
json:
username: "testuser"
password: "testpass"
capture:
- json: "$.token"
as: "authToken"
- header: "x-request-id"
as: "requestId"
- get:
url: "/profile"
headers:
Authorization: "Bearer {{ authToken }}"
Using CSV Data Files
config:
payload:
path: "users.csv"
fields:
- "username"
- "password"
order: random
skipHeader: true
scenarios:
- flow:
- post:
url: "/login"
json:
username: "{{ username }}"
password: "{{ password }}"
Assertions with Expect Plugin
config:
plugins:
expect: {}
scenarios:
- flow:
- get:
url: "/api/health"
expect:
- statusCode: 200
- contentType: json
- hasProperty: "status"
- equals:
- "{{ status }}"
- "healthy"
- post:
url: "/api/users"
json:
name: "Test User"
expect:
- statusCode: 201
- hasHeader: "location"
Environment Configuration
config:
target: "https://api.example.com"
environments:
staging:
target: "https://staging-api.example.com"
phases:
- duration: 60
arrivalRate: 10
production:
target: "https://api.example.com"
phases:
- duration: 30
arrivalRate: 2
# Run against a specific environment
artillery run --environment staging test.yml
Advanced Usage
Custom JavaScript Functions
config:
processor: "./helpers.js"
scenarios:
- flow:
- function: "generateRandomUser"
- post:
url: "/users"
json:
name: "{{ name }}"
email: "{{ email }}"
// helpers.js
module.exports = {
generateRandomUser: function (userContext, events, done) {
const id = Math.floor(Math.random() * 10000);
userContext.vars.name = `User_${id}`;
userContext.vars.email = `user${id}@test.com`;
return done();
},
};
WebSocket Testing
config:
target: "wss://ws.example.com"
engines:
ws: {}
scenarios:
- engine: ws
flow:
- send: '{"type": "subscribe", "channel": "updates"}'
- think: 5
- send: '{"type": "ping"}'
Metrics by Endpoint Plugin
config:
plugins:
metrics-by-endpoint:
useOnlyRequestNames: true
scenarios:
- flow:
- get:
url: "/api/users"
name: "Get Users"
- get:
url: "/api/orders"
name: "Get Orders"
CI/CD Integration
# Run with threshold checks (exit code 1 on failure)
artillery run --ensure 'p99 < 500' --ensure 'http.response_time.p95 < 200' test.yml
# Generate JSON report for CI artifacts
artillery run --output results.json test.yml
artillery report --output results.html results.json
# Run in quiet mode
artillery run --quiet test.yml
Troubleshooting
| Issue | Solution |
|---|---|
| High CPU usage on test machine | Use distributed testing with --platform or reduce arrivalRate |
| Connection refused errors | Check target URL, firewall rules, and server capacity |
ECONNRESET errors | Server may be dropping connections under load; check server logs |
| Variables not interpolating | Ensure capture is in a prior step and variable names match exactly |
| CSV data not loading | Check file path is relative to the test script location |
| Plugin not found | Install the plugin globally: npm install -g artillery-plugin-<name> |
| Out of memory during long tests | Increase Node memory: NODE_OPTIONS='--max-old-space-size=4096' artillery run test.yml |
| Slow report generation | Use --output to save JSON, then generate HTML separately |