SharedArray is an array-like object that shares underlying memory between VUs. The constructor function executes only once, and its result is saved in memory once. When a script requests an element, k6 gives a copy of that element.
import { SharedArray } from 'k6/data';const data = new SharedArray('some name', function () { // All heavy work (opening and processing big files) should be done here. // This happens only once and the result is shared between all VUs. const f = JSON.parse(open('./somefile.json')); return f; // must be an array});export default function () { const element = data[Math.floor(Math.random() * data.length)]; // do something with element}
import { SharedArray } from 'k6/data';const users = new SharedArray('users', function () { return JSON.parse(open('./users.json'));});export default function () { const user = users[Math.floor(Math.random() * users.length)]; // use user data}
Methods like .filter() and .map() create regular arrays when called on a SharedArray, removing memory benefits.Don’t:
const data = new SharedArray('users', function () { return JSON.parse(open('./users.json'));});export default function () { // This creates a new regular array, losing SharedArray benefits const filtered = data.filter(user => user.active);}
Do:
// Using filter inside the constructor is fine - it only runs onceconst activeUsers = new SharedArray('active users', function () { const allUsers = JSON.parse(open('./users.json')); return allUsers.filter(user => user.active);});export default function () { const user = activeUsers[Math.floor(Math.random() * activeUsers.length)];}
Avoid marshalling the entire SharedArray
Serializing a SharedArray (e.g., with JSON.stringify()) converts it to a regular array.Don’t:
export default function () { // Marshalling the entire SharedArray defeats its purpose const serialized = JSON.stringify(data);}
Do:
export default function () { // Marshal only the element you need const user = data[Math.floor(Math.random() * data.length)]; const serialized = JSON.stringify(user);}
Avoid returning SharedArray from setup()
Returning a SharedArray from setup() causes it to be marshalled, removing memory benefits.Don’t:
const data = new SharedArray('users', function () { return JSON.parse(open('./users.json'));});export function setup() { return { users: data }; // This marshalls the SharedArray}
Do:
// Keep SharedArray in init contextconst users = new SharedArray('users', function () { return JSON.parse(open('./users.json'));});export default function () { // Access SharedArray directly const user = users[Math.floor(Math.random() * users.length)];}
Open files inside SharedArray callback
Opening files outside the SharedArray callback causes each VU to hold its own copy.Don’t:
const usersRaw = open('./users.json');const usersJSON = JSON.parse(usersRaw);const usersShared = new SharedArray('users', function () { return usersJSON; });
Do:
const users = new SharedArray('users', function () { // Do all work inside - opens file only once return JSON.parse(open('./users.json'));});
Internally, SharedArray keeps data marshaled as JSON and unmarshals elements only when requested. This operation is typically unnoticeable relative to other operations, but for small data sets, SharedArray might perform worse.Memory savings:
100-1000 elements: Minimal benefit
10,000+ elements: Significant memory and CPU savings
100,000+ elements: Dramatic improvement (8-9GB → 238-275MB in tests)
SharedArray is most beneficial for large datasets. For small datasets (< 1000 items), the overhead might outweigh the benefits.