Skip to content

Tool Migration

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

This guide covers migrating performance test scripts between JMeter, k6, and Gatling using perf-migrator.

Common reasons to switch tools:

  • JMeter → k6: Reducing infrastructure overhead (k6 uses less memory per VU), moving to code-first scripts, better CI/CD integration
  • JMeter → Gatling: Scala type safety, better distributed testing, Akka-based scaling
  • k6 → JMeter: Need protocol support not available in k6 (LDAP, FTP, JMS), GUI-based team
  • k6/Gatling → JMeter: Legacy infrastructure requires JMX format, existing JMeter infrastructure
  • Any → Any: Standardising a mixed-tool organisation on a single tool

Audit your existing script first:

Terminal window
perf-lint check existing-test.jmx --format json > pre-migration-lint.json

Fix lint errors before migrating. Clean input produces cleaner output.

Install perf-migrator and activate your license:

Terminal window
export PERF_MIGRATOR_LICENSE=your-license-key
Terminal window
perf-migrator jmx2k6 load-test.jmx -o load-test.js
Terminal window
perf-migrator jmx2gatling load-test.jmx -o src/test/scala/LoadTest.scala
Terminal window
perf-migrator k62jmx script.js -o load-test.jmx
Terminal window
perf-migrator k62gatling script.js -o src/test/scala/LoadTest.scala
Terminal window
perf-migrator gatling2jmx MySimulation.scala -o load-test.jmx
Terminal window
perf-migrator gatling2k6 MySimulation.scala -o script.js

Always check the report, especially for complex scripts:

Terminal window
perf-migrator jmx2k6 load-test.jmx -o load-test.js --html-report migration-report.html

Open migration-report.html in a browser. Look for:

  • skipped elements: parts that weren’t converted — you’ll need to add these manually
  • partial status: elements that were converted but may need review (e.g., regex patterns, complex conditional logic)
  • Secrets warnings: hardcoded credentials detected in the source

JSON report:

Terminal window
perf-migrator jmx2k6 load-test.jmx -o load-test.js --report migration-report.json
cat migration-report.json | jq '.skippedElements'

The output is automatically lint-clean, but verify:

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

With perf-ecosystem.yml (integrations.migrator_validate: true), this runs automatically.

JMeter inline Groovy/BeanShell code cannot be automatically converted. The report will flag these. Equivalent k6 pattern:

// JMeter had: BeanShell Sampler with Groovy script
// k6 equivalent:
export default function() {
// Replace inline logic with standard k6 code
const timestamp = new Date().getTime();
const signature = generateSignature(timestamp); // implement in JS
}

Converted correctly, but the CSV file path in the output is relative. Ensure the file is accessible:

// Generated output — verify this path is correct
import { SharedArray } from 'k6/data';
const users = new SharedArray('users', function() {
return papaparse.parse(open('./data/users.csv'), { header: true }).data;
});

Thread Groups with ramp-up are converted to stages:

// Generated from JMeter Thread Group: 100 VUs, ramp 60s, duration 300s
export const options = {
stages: [
{ duration: '60s', target: 100 },
{ duration: '300s', target: 100 },
{ duration: '30s', target: 0 },
],
};

Review the values match your intent.

IfController and WhileController are partially converted. Complex conditions may need manual review:

// Generated from IfController: "${loginRequired}" == "true"
if (__ENV.loginRequired === 'true') {
// ... login requests
}

Migrate all JMX files in a directory:

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

Output naming: test-name.converted.js

  1. Run a smoke test with 1-2 VUs and 30 seconds:

    Terminal window
    docker run --rm \
    -v $(pwd)/tests:/tests \
    ghcr.io/markslilley/perf-k6:latest \
    k6 run /tests/load-test.js -e VUS=2 -e DURATION=30s
  2. Compare results with the original tool against the same endpoint.

  3. Upload both to perf-results-db and use perf-compare to verify equivalence:

    Terminal window
    npx @martkos-it/perf-compare \
    --url http://localhost:4000 \
    --project your-project-uuid \
    --method simple \
    --threshold 0.15 # allow 15% variance during migration validation
  • Pre-migration lint of source script — all errors fixed
  • Migrator run with --html-report — report reviewed
  • Skipped elements documented and manually added
  • Output script linted — zero errors
  • Smoke test passes (2 VUs, 30s)
  • Comparison run vs original results within acceptable variance
  • CSV/data files accessible at expected paths
  • Environment variables updated for new tool’s conventions
  • CI pipeline updated to use new tool