Skip to main content
Version: 3.0

Batch Processing

When your workflow needs to process many items concurrently — embedding hundreds of document chunks, calling an API for each row in a dataset, or transforming files in bulk — you need to control how many operations run at the same time. promiseAllWithLimit gives you a concurrency limiter that integrates with the Operaide framework.

promiseAllWithLimit​

Processes an array of items in parallel while capping the number of concurrent operations.

import { promiseAllWithLimit } from '@operaide/aktor';

const results = await promiseAllWithLimit(
async (chunk, index) => {
return await embedChunk(chunk);
},
{
name: 'embeddings',
items: documentChunks,
limit: 30,
}
);

Parameters​

ParameterTypeDefaultDescription
fn(item: T, index: number) => Promise<R>requiredFunction to execute for each item
namestringrequiredQueue identifier
itemsT[]requiredArray of items to process
limitnumberrequiredMaximum concurrent executions
localbooleanfalseUse a local pool instead of the global queue

Results are returned in the original item order, regardless of which operations finish first.

Global vs. Local Mode​

Global Queue (default)​

All calls with the same name share a single concurrency pool. This is the right choice when you need to respect an external rate limit — for example, an API that allows 30 concurrent requests regardless of how many Reaktors are running.

// Both calls share one pool of 30 slots
const batch1 = promiseAllWithLimit(embedChunk, {
name: 'embeddings',
items: chunksFromDoc1,
limit: 30,
});

const batch2 = promiseAllWithLimit(embedChunk, {
name: 'embeddings',
items: chunksFromDoc2,
limit: 30,
});

await Promise.all([batch1, batch2]);
// Total concurrency across both: max 30

Local Pool​

Each call gets its own independent concurrency limit. Use this when the limit is about managing local resource usage rather than a shared external constraint.

const results = await promiseAllWithLimit(
async (file) => processFile(file),
{
name: 'file-processing',
items: files,
limit: 10,
local: true, // Independent pool for this call
}
);

Usage in AktorFunctions​

promiseAllWithLimit is a plain async function, not an Aktor. Use it inside createAktorFunction to add concurrency control to your Aktor logic:

import { createAktorFunction, promiseAllWithLimit } from '@operaide/aktor';

const aktorEmbedAllChunks = createAktorFunction('aktorEmbedAllChunks',
async ({ chunks }: { chunks: string[] }) => {
if (chunks.length === 0) return [];

const embeddings = await promiseAllWithLimit(
async (chunk) => {
const response = await fetch('/api/embed', {
method: 'POST',
body: JSON.stringify({ text: chunk }),
});
return response.json();
},
{
name: 'embedding-api',
items: chunks,
limit: 20,
}
);

return embeddings;
}
);