AJMAS is a production-grade HTTP/HTTPS load testing tool written in Go, designed for massive concurrency, reproducible tests, and fine-grained performance analysis. It's built with Kubernetes-native deployment in mind.
- Massive concurrency: simulates thousands of concurrent users using Go's goroutines
- Flexible config: YAML and JSON configuration support
- Fluent DSL API: programmatic scenario building for advanced users
- Real-time Console UI: lightweight, terminal-based monitoring inspired by
htop - Comprehensive metrics: RPS, latency percentiles (p50, p90, p95, p99), error rates, status code distribution
- Multiple Export Formats: JSON, CSV, and Prometheus metrics endpoint
- Kubernetes-Ready: pre-built manifests for Deployment and Job execution
- Low overhead: optimized HTTP transport with connection pooling and keep-alive
- SLO Thresholds: Define pass/fail criteria (latency, error rate, RPS) for CI/CD pipelines
go install github.com/assu-2000/ajmas/cmd/loadtester@latestgit clone https://github.com/assu-2000/ajmas.git
cd ajmas
go build -o loadtester ./cmd/loadtesterdocker build -t ajmas-loadtester .
docker run -v $(pwd)/config.json:/app/config/config.json ajmas-loadtester# config.json
target:
base_url: https://api.example.com
load:
users: 100
spawn_rate: 10
duration: 5m
tasks:
- name: get_users
method: GET
path: /users
weight: 2
- name: create_user
method: POST
path: /users
weight: 1
headers:
Content-Type: application/json
body:
content: '{"name": "assu"}'
wait_time:
min: 200ms
max: 1s./loadtester -config config.json| Flag | Description |
|---|---|
-config |
path to configuration file (required) |
-target |
override target base URL |
-users |
override number of virtual users |
-duration |
override test duration |
-spawn-rate |
override users spawn rate per second |
-output-json |
export results to JSON file |
-output-csv |
export results to CSV file |
-prometheus |
start Prometheus metrics server (e.g: :9090) |
-no-ui |
disable real-time console UI |
-version |
show version information |
target:
base_url: https://api.example.com # base URL for all requestsload:
users: 1000 # number of concurrent virtual users
spawn_rate: 50 # users spawned per second during ramp-up
duration: 10m # total test duration (supports s, m, h)tasks:
- name: task_name # unique task identifier
method: GET # HTTP method (GET, POST, PUT, DELETE, etc.)
path: /api/endpoint # request path (supports {{.variable}} templates)
weight: 1 # task selection weight (higher = more frequent)
headers: # request headers (optional)
Content-Type: application/json
body: # request body (optional)
content: '{"key": "value"}'
template: file.json # or load from template filewait_time:
min: 200ms # minimum wait between tasks
max: 1s # maximum wait between tasksDefine pass/fail criteria for CI/CD integration. The tool exits with code 1 if any threshold is breached.
thresholds:
p50_latency: 100ms # Maximum p50 latency
p90_latency: 200ms # Maximum p90 latency
p95_latency: 300ms # Maximum p95 latency
p99_latency: 500ms # Maximum p99 latency
error_rate: 1.0 # Maximum error rate (percent)
min_rps: 100 # Minimum requests per secondAll fields are optional — only configured thresholds are evaluated.
CI/CD Example:
./loadtester -config config.yaml -no-ui -output-json results.json
# Exit code 0 = all thresholds passed
# Exit code 1 = one or more thresholds breachedFor advanced users, AJMAS provides a fluent Go API:
package main
import (
"context"
"time"
"github.com/assu-2000/ajmas/pkg/dsl"
"github.com/assu-2000/ajmas/internal/config"
)
func main() {
scenario := dsl.Scenario().
Target("https://api.example.com").
Users(1000).
RampUp(30 * time.Second).
Duration(5 * time.Minute).
Wait(200*time.Millisecond, time.Second).
Get("list_products", 2, "/products").
Post("create_order", 3, "/orders",
`{"product_id": "123"}`,
map[string]string{"Content-Type": "application/json"}).
Thresholds(config.ThresholdConfig{
P99Latency: 500 * time.Millisecond,
ErrorRate: 1.0,
MinRPS: 100,
})
ctx := context.Background()
snapshot, _ := scenario.Run(ctx)
fmt.Printf("RPS: %.2f, P99: %v\n", snapshot.RPS, snapshot.Latency.P99)
}USERS: 1000 │ RPS: 842.5 │ ERR: 0.12%
LAT(ms): p50=120 p90=250 p95=310 p99=480
MEM: 420.5MB │ NET: 12.34MB/s │ REQS: 42150
When running with -prometheus :9090, the following metrics are exposed at /metrics:
| Metric | Type | Description |
|---|---|---|
loadtest_requests_total |
Counter | Total number of requests |
loadtest_requests_success_total |
Counter | successful requests |
loadtest_requests_error_total |
Counter | failed requests |
loadtest_bytes_total |
Counter | total bytes transferred |
loadtest_active_users |
Gauge | current active virtual users |
loadtest_rps |
Gauge | current requests per second |
loadtest_error_rate |
Gauge | current error rate percentage |
loadtest_latency_ms |
Summary | request latency percentiles |
kubectl apply -f k8s/deployment.yamlkubectl apply -f k8s/job.yamlapiVersion: v1
kind: ConfigMap
metadata:
name: loadtest-config
data:
config.yaml: |
target:
base_url: http://target-service:8080
load:
users: 100
duration: 5m
tasks:
- name: test
method: GET
path: /api
weight: 1┌─────────────────────────────────────────────────────────┐
│ CLI / Main │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌───────────┐ │
│ │ Config │ │ Engine │ │ Metrics │ │ Export │ │
│ │ Parser │ │ │ │Collector│ │ (JSON/CSV)│ │
│ └─────────┘ └─────────┘ └─────────┘ └───────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Virtual Users (Goroutines) │ │
│ │ [VU1] [VU2] [VU3] ... [VU1000] │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ HTTP Transport (Optimized) │ │
│ │ • Connection Pooling • Keep-Alive | │
│ │ • HTTP/2 Support • Configurable Limits │ │
│ └─────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
-
Increase File Descriptors: for high concurrency, increase ulimit
ulimit -n 65535 -
Use Keep-Alive: enabled by default, reduces connection overhead
-
Optimize Spawn Rate: match spawn rate to target server capacity
-
Monitor Resources: use
-prometheusflag to export metrics for monitoring
En tout cas, please feel free to submit a P.R