Reliability
Configure timeouts, retries with exponential backoff, rate-limit handling, and cancellation for authenticated Gemini requests and streams.
The Gemini package maps HTTP outcomes onto a typed error taxonomy and retries the failures worth retrying. Configure session cookies and an XSRF token from the same signed-in Gemini Web session. Reliability options can be configured on the client, with per-call overrides where supported.
Initialize the client
import 'dotenv/config'import { GeminiWeb, GeminiRateLimitError, DEFAULT_RETRY_POLICY,} 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 clientConfig = { model: 'gemini-3.6-flash', cookies, xsrfToken,} const model = new GeminiWeb(clientConfig)Timeouts
const timeoutModel = new GeminiWeb({ ...clientConfig, timeoutMs: 60_000,}) // Override the timeout for one invocation.await timeoutModel.invoke( 'Explain distributed systems.', { timeoutMs: 30_000 },) // Disable the request timeout.await timeoutModel.invoke( 'Explain distributed systems.', { timeoutMs: 0 },)- The default timeout is
180_000milliseconds (3 minutes). 0disables the timeout.- A timeout raises
GeminiTimeoutError, which carriestimeoutMs. - Timeout failures are retryable by default, subject to the configured retry policy.
Retries
const retryingModel = new GeminiWeb({ ...clientConfig, retry: { attempts: 5, delayMs: 1_000, backoffFactor: 2, maxDelayMs: 20_000, },}) const noRetriesModel = new GeminiWeb({ ...clientConfig, retry: false,})attemptscounts the first attempt, so3means at most three attempts.delayMsis the base delay between attempts.backoffFactormultiplies the delay after each failure.maxDelayMscaps a single delay.retry: falsedisables retries.- Rate-limit and timeout failures may be retried. Authentication, configuration, and protocol failures are generally not retryable.
console.log(DEFAULT_RETRY_POLICY)// {// attempts: 3,// delayMs: 2000,// backoffFactor: 2,// maxDelayMs: 30000// }Rate limits
HTTP 429 responses raise GeminiRateLimitError. When the upstream response provides a retry hint, retryAfterMs contains the suggested delay. Use that value instead of guessing a wait time.
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)) try { await model.invoke('Explain rate limiting.')} catch (error) { if (error instanceof GeminiRateLimitError) { const delayMs = error.retryAfterMs ?? 1_000 console.log('Rate limited. Waiting:', delayMs, 'ms') await sleep(delayMs) } else { throw error }}Provider-managed limits
Requests go directly to Gemini Web. Applicable quotas and rate limits depend on the provider and the authenticated session. Retries can help with transient failures, but they do not increase provider limits or resolve sustained overuse.
Cancellation
Pass an AbortSignal to request cancellation. You can configure a signal on the client or provide one for an individual invocation.
const controller = new AbortController() const cancellableModel = new GeminiWeb({ ...clientConfig, signal: controller.signal,}) const timer = setTimeout( () => controller.abort(), 5_000,) try { await cancellableModel.invoke( 'Explain how distributed systems work.', )} catch (error) { console.error('Request stopped:', error)} finally { clearTimeout(timer)} // A separate signal for an individual invocation.const callController = new AbortController() await model.invoke( 'Explain request cancellation.', { signal: callController.signal },)A client-level signal and a per-call signal can both be configured. Handle cancellation errors in your application and verify the specific error type for the operation being cancelled.
Streaming timeouts
A stream can remain open while Gemini generates output. The request timeout may cover the time to response headers rather than the entire stream body, depending on the transport implementation. Use an AbortSignal when your application needs to cancel a running stream.
Test retry timing without waiting
The transport exposes a sleep seam that can be used in tests to verify retry delay schedules without waiting for real delays. See [Custom fetch and tests](/docs/gemini/custom-fetch).