I want to create a performance test using k6 to generate load up to 2000 QPS. Is the below script the right way to implement this? reading data from csv

import http from ‘k6/http’;
import { check, sleep } from ‘k6’;
import { Rate } from ‘k6/metrics’;
import { SharedArray } from ‘k6/data’;
import { Trend } from ‘k6/metrics’;

// ---------------- ERROR METRIC ----------------
export let errorRate = new Rate(‘error_rate’);
// ---------------- HELPER: Exponential think time ----------------
function exponentialSleep(mean) {
return -Math.log(1 - Math.random()) * mean;
}
// Optional: track response time per stage
export let responseTime = new Trend(‘response_time’, true);

// ---------------- LOAD TSV FILE ----------------
const csvData = new SharedArray(‘revgeo dataset’, function () {
const file = open(‘./rgc-a.csv’);
return file
.split(‘\n’)
.map((line) => line.trim())
.filter((line) => line.length > 0)
.map((line) => line.split(/\t+/));
});
// ---------------- HELPER: Stage tagging ----------------
function getStageTag() {
if (__ENV.SCENARIO_NAME === ‘baseload’) {
return ‘baseload’;
}

// Time elapsed since ramp start
const elapsed = (__ITER + 1); // seconds passed in this VU; simple approximation
const step = Math.floor(elapsed / RAMP_STEP_DURATION);
const stageIndex = Math.min(step, RAMP_TOTAL_STEPS - 1);
return `ramp${stageIndex}`;

}

// ---------------- BASELOAD PARAMETERS ----------------
export const BASELOAD_DURATION = 1200; // 20 minutes
export const BASELOAD_QPM_PER_THREAD = 600; // QPM per thread
export const BASELOAD_THREADS = 50;

// ---------------- RAMP-UP PARAMETERS ----------------
export const RAMP_MAX_THREADS = 1300; // Max threads (VU)
export const RAMP_QPM_PER_THREAD = 600;
export const RAMP_START_DELAY = 1320; // start after baseload
export const RAMP_STEP_DURATION = 120; // per ramp step (2min)
export const RAMP_THREADS_PER_STEP = 130; // threads added per step
export const RAMP_TOTAL_STEPS = 10;

// ---------------- CSV DISTRIBUTION ----------------
const rowsPerVU = Math.ceil(csvData.length / RAMP_MAX_THREADS);

// ---------------- STAGE TAGGING ----------------
export function tagWithCurrentStageIndex(stageIndex) {
return { stage: ramp${stageIndex} };
}
// ---------------- GLOBAL PERFID ----------------
// Generate a single perfId at script start
const PERF_ID = PT-3beba3cc869d4ba0ba172a02343ec7rg;
console.log(Global perfId: ${PERF_ID});

// ---------------- K6 OPTIONS ----------------
export const options = {
scenarios: {
baseload: {
executor: ‘constant-arrival-rate’,
rate: (BASELOAD_QPM_PER_THREAD / 60) * BASELOAD_THREADS,
timeUnit: ‘1s’,
duration: ${BASELOAD_DURATION}s,
preAllocatedVUs: BASELOAD_THREADS,
maxVUs: BASELOAD_THREADS * 2,
env: { SCENARIO_NAME: “baseload” }
},
rampup: {
executor: ‘ramping-arrival-rate’,
startRate: 0,
timeUnit: ‘1s’,
startTime: ${RAMP_START_DELAY}s,
stages: (() => {
const stages = ;
for (let i = 1; i <= RAMP_TOTAL_STEPS; i++) {
stages.push({
target: i * RAMP_THREADS_PER_STEP * (RAMP_QPM_PER_THREAD / 60),
duration: ${RAMP_STEP_DURATION}s,
});
}
return stages;
})(),
preAllocatedVUs: RAMP_THREADS_PER_STEP,
maxVUs:(RAMP_TOTAL_STEPS * RAMP_THREADS_PER_STEP * (RAMP_QPM_PER_THREAD / 60)) * 2, // make sure maxVUs is enough for final stage
env: { SCENARIO_NAME: “rampup” }
},
},
thresholds: {
‘error_rate’: [‘rate<0.1’],
‘http_req_failed’: [‘rate<0.01’],
‘http_req_duration’: [‘p(95)<500’],
},
};

// ---------------- HELPER: Get CSV row for this VU ----------------
function getRowForVU(vuIndex, iter) {
const start = (vuIndex - 1) * rowsPerVU;
const end = start + rowsPerVU;
const myRows = csvData.slice(start, end).length > 0 ? csvData.slice(start, end) : csvData;
return myRows[iter % myRows.length];
}

// ---------------- DEFAULT FUNCTION ----------------
export default function () {
const BASE_URL = ‘http://internal-ad844a08ac80c44b7ae55cfbdc90e43e-1071003513.eu-west-1.elb.amazonaws.com’;

// Get unique row per VU
const row = getRowForVU(__VU, __ITER);

if (!row || !row[0]) {
console.error(⚠️ Invalid or empty row for VU ${__VU}, iteration ${__ITER});
return;
}
const path = row[0].startsWith(‘/’) ? row[0] : ‘/’ + row[0];

// If the path already contains ?, append with &, otherwise with ?
const separator = path.includes(‘?’) ? ‘&’ : ‘?’;

const url = ${BASE_URL}${path}${separator}perfid=${PERF_ID};

// Optional: log the first request for sanity
if (__ITER < 3 && __VU === 1) {
console.log(Sample URL: ${url});
console.log(Row data: ${JSON.stringify(row)});
}

// Accurate stage tagging based on time
const stage = getStageTag();

// Send GET request
const res = http.get(url, { tags: { stage } });

// Validate response
const ok = check(res, {
‘status is 2xx or 3xx’: (r) => r.status <= 400,
});

// Update error rate
errorRate.add(!ok);
responseTime.add(res.timings.duration, tags);

sleep(exponentialSleep(1.5));
}

is this script fine??