# Custom Timeouts (/sdks/nodejs/how-to/connection/custom-timeouts)



## Overview [#overview]

Every client operation has an implicit deadline — how long to wait for the initial connection, how long before a dead socket is detected, how long a single call blocks before giving up. The defaults are reasonable for a healthy local network, but they're wrong for high-latency links, connections through load balancers or NAT gateways, or servers that occasionally run slow under load. Tuning timeouts explicitly is how you trade fast-fail behavior against tolerance for transient slowness.

`connectionTimeoutSeconds` bounds how long `KubeMQClient.create()` waits for the initial handshake, while the `retry` policy governs backoff on later reconnection attempts; a per-call `{ timeout }` option overrides that default for a single `sendEvent` without touching client-wide config; and an `AbortSignal` gives cooperative cancellation independent of any timeout, surfaced as `CancellationError` rather than `KubeMQTimeoutError`. &#x2A;*Gotchas:** a per-call timeout shorter than the server's real processing time causes spurious failures, not faster detection of a genuinely broken handler; a `retry` policy with a high `maxRetries` and no cap on elapsed time can keep retrying against a server that's down for good; and conflating `KubeMQTimeoutError` (deadline expired) with `CancellationError` (you cancelled it) leads to the wrong retry decision.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Node.js SDK installed (`npm install kubemq-js`)

## Code [#code]

```typescript title="custom-timeouts.ts"
/**
 * Example: Custom Timeout Configuration
 *
 * Demonstrates configuring custom timeouts at the client level and
 * per-operation level. Also shows how to use AbortSignal for explicit
 * cancellation control.
 *
 * Prerequisites:
 *   - KubeMQ server running on localhost:50000
 *
 * Run: npx tsx examples/configuration/custom-timeouts.ts
 */
import {
  KubeMQClient,
  createEventMessage,
  CancellationError,
  KubeMQTimeoutError,
} from 'kubemq-js';

async function main(): Promise<void> {
  // Client-level timeout configuration.
  const client = await KubeMQClient.create({
    address: 'localhost:50000',
    clientId: 'js-configuration-custom-timeouts-client',
    connectionTimeoutSeconds: 15,
    retry: {
      maxRetries: 5,
      initialBackoffMs: 1000,
      maxBackoffMs: 30_000,
      multiplier: 2.0,
      jitter: 'full',
    },
  });

  try {
    // Per-operation timeout override.
    await client.sendEvent(
      createEventMessage({ channel: 'js-configuration.custom-timeouts', body: 'p99=42ms' }),
      { timeout: 2000 },
    );
    console.log('Published with 2-second timeout');

    // AbortSignal-based cancellation.
    const controller = new AbortController();
    setTimeout(() => {
      controller.abort();
    }, 3000);

    try {
      await client.sendEvent(
        createEventMessage({ channel: 'js-configuration.custom-timeouts', body: 'p99=38ms' }),
        { signal: controller.signal },
      );
      console.log('Published before cancellation');
    } catch (err) {
      if (err instanceof CancellationError) {
        console.log('Operation was cancelled by AbortSignal');
      } else if (err instanceof KubeMQTimeoutError) {
        console.log('Operation timed out');
      }
    }
  } finally {
    await client.close();
  }
}

main().catch(console.error);

```

## How It Works [#how-it-works]

* `connectionTimeoutSeconds` caps how long `KubeMQClient.create()` waits for the initial handshake; the `retry` policy controls exponential backoff for subsequent reconnections.
* Every send/receive/subscribe method accepts a second `OperationOptions` argument — passing `{ timeout: 2000 }` overrides the client-level default for that single call only.
* The `AbortController` / `AbortSignal` pattern (Web API, available in Node.js 15+) lets caller code cancel in-flight operations cooperatively; the SDK translates a signal abort into a `CancellationError`.
* `KubeMQTimeoutError` is thrown when the per-operation deadline expires; `CancellationError` is thrown when an `AbortSignal` fires — both expose `isRetryable: true` by default.

## Related [#related]

* [Node.js SDK Reference](/sdks/nodejs/reference)
* [Connect](/sdks/nodejs/tutorials/connect)
* [Close](/sdks/nodejs/how-to/connection/close)
