# Deadlines and cancellation

Bound the complete call and each attempt, and stop the chain when callers cancel.

Canonical: https://searchsdk.dev/docs/reliability/timeouts
Markdown: https://searchsdk.dev/docs/reliability/timeouts.md

<a id="budgets"></a>

## Two budgets, one deadline

> **TypeScript reference**
> The API names, code and policy behavior in this article describe the TypeScript SDK. See [your language guide](https://searchsdk.dev/docs/sdks) for its supported surface and limits.

`timeoutMs` bounds the complete normalized call, including attempts and JSON parsing. `attemptTimeoutMs` bounds each attempt without extending the total deadline. Both default to the configured total budget; with defaults, a full-budget timeout leaves no time for fallback.

**Configuration**

```typescript
const policy = {
  timeoutMs: 10_000,
  attemptTimeoutMs: 4_000,
};
// Pass these fields alongside provider and optional fallback to createSearch().
```

<a id="cancellation"></a>

## Cancel with AbortSignal

**cancel.ts · fixture**

```typescript
import { createSearch, SearchError } from '@belweave/search-sdk';
import { createMockProvider } from '@belweave/search-sdk/testing';

const controller = new AbortController();
const client = createSearch({ provider: createMockProvider({ delayMs: 500 }) });
const pending = client.web.search(
  { query: 'SQLite concurrency' },
  { signal: controller.signal },
);

controller.abort();
try {
  await pending;
} catch (error) {
  if (error instanceof SearchError) console.log(error.code); // aborted
  else throw error;
}
```

Cancellation aborts the current attempt and prevents later providers from starting. A pre-aborted signal fails before provider dispatch. The SDK cleans up its own timers and listeners.

<a id="transport-limits"></a>

## Understand resource limits

> **Promise settlement and upstream work**
> The SDK can settle even when a transport ignores its signal. That underlying I/O may continue. Use signal-aware transports to cancel resources; a local deadline does not guarantee that upstream work or billing stops.

JavaScript timers require the event loop to yield. When provider work eventually settles, elapsed deadlines take precedence over a late success or failure.
