Skip to content

perf-migrator

import { Aside } from ‘@astrojs/starlight/components’;

perf-migrator converts performance test scripts between JMeter, k6, and Gatling — all 6 directions. Built in Rust for speed and correctness. 87% success rate on 115 real-world scripts with zero lint errors on output.

TierDirectionsPrice
Single DirectionOne direction (e.g., JMeter → k6)£79 one-time
BidirectionalAll 6 directions£149 one-time

Platforms: Linux x86_64, Windows x86_64

Terminal window
# Linux
chmod +x perf-migrator
sudo mv perf-migrator /usr/local/bin/
perf-migrator --version
# Windows: add perf-migrator.exe to PATH
Terminal window
export PERF_MIGRATOR_LICENSE=your-license-key
# or pass on each invocation:
perf-migrator --license your-key jmx2k6 test.jmx -o test.js

The fastest way to convert:

Terminal window
perf-migrator jmx2k6 test.jmx -o test.js
perf-migrator jmx2gatling test.jmx -o src/test/scala/Test.scala
perf-migrator k62jmx script.js -o test.jmx
perf-migrator k62gatling script.js -o src/test/scala/Test.scala
perf-migrator gatling2jmx Simulation.scala -o test.jmx
perf-migrator gatling2k6 Simulation.scala -o test.js

For explicit format specification:

Terminal window
perf-migrator convert \
--from jmeter \
--to k6 \
input.jmx \
-o output.js

Formats: jmeter, k6, gatling

FlagDescription
-o, --output <file>Output file path (required)
--report <file>Write JSON conversion report
--html-report <file>Write HTML conversion report
--no-reportSuppress all report output
--progressShow element-level conversion progress
--verboseDebug output
--no-secrets-scanSkip secrets detection in source script
--batchBatch mode: convert all matching files in a directory
--license <key>License key (or use PERF_MIGRATOR_LICENSE env var)

By default, a JSON report is printed to stdout summarising the conversion:

{
"status": "partial",
"successRate": 0.91,
"elements": {
"converted": 43,
"skipped": 4,
"failed": 0
},
"skippedElements": [
{"type": "BSFSampler", "reason": "BSF scripting not supported in target"},
{"type": "JDBCSampler", "reason": "Database samplers require manual wiring"}
]
}

Status values: success (100% converted), partial (some elements skipped), failed (conversion aborted).

HTML report (--html-report): visual breakdown with per-element details.

FeatureJMeter→k6JMeter→Gatlingk6→JMeterk6→GatlingGatling→JMeterGatling→k6
HTTP requestsFullFullFullFullFullFull
Request headersFullFullFullFullFullFull
Response assertionsFullFullFullFullFullFull
Regex extractorsFullFullFullPartialFullFull
JSON extractorsFullFullFullFullFullFull
CSV data feedFullFullFullFullFullFull
Think timesFullFullFullFullFullFull
Load profileFullPartialFullFullFullFull
Groups/transactionsFullFullFullFullFullFull
Conditional logicPartialPartialPartialPartialPartialPartial
Auth (Basic/Bearer)FullFullFullFullFullFull
gRPCPartialPartial

perf-migrator scans source scripts for hardcoded secrets (API keys, passwords, Bearer tokens) before conversion. Detected secrets are reported with line numbers.

WARNING: Potential secret detected in test.jmx:
line 45: Authorization header contains what appears to be a Bearer token
→ Replace with a variable before committing to version control

Disable with --no-secrets-scan if you’ve already handled secrets.

Convert all scripts in a directory:

Terminal window
perf-migrator jmx2k6 tests/jmeter/ --batch -o tests/k6/

Output files are named <input-name>.converted.js.

Output scripts pass perf-lint with zero errors. For additional validation:

Terminal window
perf-migrator jmx2k6 test.jmx -o test.js && perf-lint check test.js

With perf-ecosystem.yml configured (integrations.migrator_validate: true), perf-migrator auto-lints output and includes lint results in the conversion report.

JMeter’s CSV Data Set Config becomes a k6 SharedArray:

// Generated output
import { SharedArray } from 'k6/data';
const users = new SharedArray('users', function() {
return JSON.parse(open('./users.csv'));
});
// Generated from JMeter thread group: 50 users, ramp 60s, duration 300s
export const options = {
stages: [
{ duration: '60s', target: 50 },
{ duration: '300s', target: 50 },
{ duration: '30s', target: 0 },
],
};