Batch Processing
Process multiple prompts with configurable concurrency, ordered results, cancellation, and predictable error handling.
Use model.batch() to process multiple prompts with a single method call. Configure concurrency, handle individual failures, and cancel batch work with an AbortSignal. Results preserve the original input order, regardless of completion order.
Initialize the client
Configure the Gemini Web session credentials before running batch requests. The SDK does not read environment variables automatically.
import 'dotenv/config'import { GeminiWeb } from '@orcushq/gemini' const cookies = process.env.GEMINI_COOKIESconst xsrfToken = process.env.GEMINI_XSRF_TOKEN if (!cookies?.trim() || !xsrfToken?.trim()) { throw new Error( 'GEMINI_COOKIES and GEMINI_XSRF_TOKEN are required', )} const model = new GeminiWeb({ model: 'gemini-3.6-flash', cookies, xsrfToken,})GEMINI_COOKIES="your_complete_cookie_header"GEMINI_XSRF_TOKEN="your_at_value"Basic usage
Pass an array of prompts to model.batch(). The method returns a response for each input.
const responses = await model.batch([ 'Explain HTTP in one sentence.', 'Explain TCP in one sentence.', 'Explain DNS in one sentence.',]) for (const response of responses) { console.log(response.content)}Each result is a GeminiResponse. Access content for the generated text and other response fields when needed. An empty input array returns an empty array.
Concurrency
Use concurrency to control the maximum number of requests running simultaneously. The default is 4. The effective concurrency cannot exceed the number of inputs.
const responses = await model.batch( [ 'Summarize document A.', 'Summarize document B.', 'Summarize document C.', 'Summarize document D.', ], { concurrency: 2, },) console.log(responses.map((response) => response.content))concurrency must be a positive integer. Values such as 0, negative numbers, decimals, NaN, and Infinity are rejected with GeminiConfigurationError.
Result ordering
Results preserve input order even when requests finish at different times. You can associate responses[i] with the input at index i.
const prompts = [ 'Reply with exactly BATCH_ORDER_ALPHA_741.', 'Reply with exactly BATCH_ORDER_BRAVO_852.', 'Reply with exactly BATCH_ORDER_CHARLIE_963.', 'Reply with exactly BATCH_ORDER_DELTA_174.',] const responses = await model.batch(prompts, { concurrency: 2,}) for (let i = 0; i < responses.length; i++) { console.log(i, responses[i].content)}Empty input
Calling batch() with an empty array returns an empty array without generating responses.
const responses = await model.batch([]) console.log(responses) // []Options
concurrency: Maximum number of simultaneous requests. Defaults to4.continueOnError: Defaults tofalse. When enabled, processing continues after individual failures and throwsBatchAggregateErrorif any request fails.signal: An optionalAbortSignalfor requesting cancellation of batch work.- Invocation options: Supported
GeminiInvokeOptions, including options such asmodel,timeoutMs, andretry, apply to each input in the batch.
Invocation options are shared across the inputs in one batch call; they are not configured separately for each input.
Error handling
By default, batch() uses fail-fast behavior: if a request fails, the batch rejects with an error. Requests already in progress may still finish; rejection does not guarantee that all in-flight requests have been cancelled.
try { const responses = await model.batch([ 'Explain HTTP briefly.', 'Explain TCP briefly.', 'Explain DNS briefly.', ]) console.log(responses)} catch (error) { console.error('Batch failed:', error)}Continue after individual failures
Set continueOnError: true to process remaining inputs after individual failures. When requests fail, the method throws BatchAggregateError after processing finishes. The error exposes errors and, when available, results for inspecting failures and successful values.
try { const responses = await model.batch( [ 'Explain HTTP briefly.', 'Explain TCP briefly.', 'Explain DNS briefly.', ], { concurrency: 2, continueOnError: true, }, ) console.log(responses)} catch (error) { if ( error instanceof Error && error.name === 'BatchAggregateError' ) { const aggregate = error as Error & { errors?: readonly unknown[] results?: readonly unknown[] } console.error('Failed requests:', aggregate.errors) console.log('Available results:', aggregate.results) } else { throw error }}BatchAggregateError.results preserves input positions. Failed positions may contain undefined. The errors collection follows failure encounter order, which may differ from input order.
Handling aggregate errors
`BatchAggregateError` extends the standard `Error` class and is not part of the Gemini-specific error taxonomy. Detect it by its `name` (`error.name === "BatchAggregateError"`) rather than using a value import. Do not assume `isGeminiError(error)` recognizes it.
Collect individual outcomes with batchSettled()
Use batchSettled() when you need the outcome for every input without rejecting the overall operation merely because an individual request fails. Each returned entry contains the input index and either a successful value or a failure reason. Authentication and configuration checks can still reject the method before an outcome array is returned.
const outcomes = await model.batchSettled( [ 'Reply with the word ALPHA only.', 'Reply with the word BRAVO only.', 'Reply with the word CHARLIE only.', ], { concurrency: 2, },) for (const outcome of outcomes) { if (outcome.status === 'fulfilled') { console.log( 'Success at index:', outcome.index, outcome.value.content, ) } else { console.error( 'Failure at index:', outcome.index, outcome.reason, ) }}batchSettled() returns outcomes in input order. Fulfilled entries contain value; rejected entries contain reason. This lets your application handle successful and failed requests independently.
Cancellation
Pass an AbortSignal to request cancellation. An already-aborted signal prevents the batch from completing successfully. The tested pre-aborted case rejected with AbortError.
const controller = new AbortController() controller.abort() try { const responses = await model.batch( [ 'Explain HTTP briefly.', 'Explain DNS briefly.', ], { concurrency: 2, signal: controller.signal, }, ) console.log(responses)} catch (error) { console.error('Batch stopped:', error)}Cancellation behavior
The pre-aborted signal test confirms rejection before successful completion. Cancellation of requests already in progress requires separate verification; do not assume every active operation stops immediately.
Structured-output batch
Combine batch processing with withStructuredOutput() to validate each response against a Zod schema. Each successful result contains the parsed value and response details.
import { z } from 'zod' const Person = z.object({ name: z.string(), age: z.number(),}) const structured = model.withStructuredOutput(Person) const results = await structured.batch( [ 'Return a JSON person object with name "Alice" and age 30.', 'Return a JSON person object with name "Bob" and age 25.', ], { concurrency: 2, },) for (const result of results) { console.log(result.value) console.log(result.raw) console.log(result.metadata)}result.value contains the parsed, schema-validated object. Each result also exposes raw, response, and metadata. The tested structured batch returned valid objects for both inputs.
Timeouts and retries
Invocation-level timeout and retry behavior is delegated to the invocation and transport layers. A request timeout applies to an individual invocation; batch() does not provide a separate overall timeout for the entire batch. Configure concurrency appropriately and handle upstream, timeout, and rate-limit errors.
Important notes
- Batching is a client-side convenience API, not a provider-native bulk endpoint.
- Each input is processed as an independent invocation.
- Higher concurrency does not guarantee higher throughput; provider limits and session capacity still apply.
- Results are collected in memory and returned after processing.
- Already-running requests may finish after a fail-fast rejection.
- Use
batchSettled()when you need per-input outcomes without an aggregate rejection for individual request failures.