# How to Configure OmniRoute's Background Token Health Check Scheduler

> Configure OmniRoute's token health check scheduler using environment variables to control stagger delay, jitter, batch size, and provider filtering. Optimize your token health monitoring.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-08-14

---

**You can configure OmniRoute's token health check scheduler through environment variables that control stagger delay, jitter, batch size, provider filtering, and enable/disable toggles, with the job registered in [`src/lib/jobs/tokenHealthCheckJob.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/jobs/tokenHealthCheckJob.ts) and core logic implemented in [`src/lib/tokenHealthCheck.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheck.ts).**

OmniRoute's **token health check scheduler** is a background job that periodically validates OAuth tokens, API keys, and Copilot sub-tokens to ensure connections remain healthy. This lightweight sweep runs every 60 seconds by default, updating connection state and handling refreshes automatically. This guide covers all configuration options available in the OmniRoute codebase, including environment variables and their implementation details.

## How the Token Health Check Scheduler Works

The scheduler operates as a **registered job** in OmniRoute's job registry. When the server boots, [`src/lib/jobs/tokenHealthCheckJob.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/jobs/tokenHealthCheckJob.ts) creates a repeating timer that triggers the health check sweep.

The core sweep logic resides in [[`src/lib/tokenHealthCheck.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheck.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/tokenHealthCheck.ts). This file:

- Reads all environment variables to tune behavior
- Iterates over provider connections (OAuth, API-key, Cursor, Copilot)
- Applies **stagger delays** and **jitter** to spread load
- Handles token refreshes, network errors, and terminal failures
- Updates connection metadata like `rateLimitedUntil` and `testStatus`

Specialized handlers for Cursor and Copilot tokens live in separate files: [[`src/lib/tokenHealthCheckCursor.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheckCursor.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/tokenHealthCheckCursor.ts) and [[`src/lib/tokenHealthCheckCopilot.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheckCopilot.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/tokenHealthCheckCopilot.ts).

## Environment Variables for Scheduler Configuration

All configuration is **environment-variable driven** as documented in [[`docs/ENVIRONMENT.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/ENVIRONMENT.md)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/docs/ENVIRONMENT.md). The scheduler reads these at startup.

| Variable | Default | Purpose |
|----------|---------|---------|
| `HEALTHCHECK_STAGGER_MS` | `3000` | Milliseconds between the start of each provider's health check |
| `HEALTHCHECK_JITTER_MIN_MS` | `500` | Minimum random jitter added to stagger delays |
| `HEALTHCHECK_JITTER_MAX_MS` | `5000` | Maximum random jitter added to stagger delays |
| `HEALTHCHECK_BATCH_SIZE` | *unset* | Limits connections processed per tick (CPU/IO throttling) |
| `OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK` | *unset* | Disables the entire scheduler when set to any truthy value |
| `OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS` | *empty* | Comma-separated provider IDs to exclude (e.g., `openai,anthropic`) |
| `OMNIROUTE_HIDE_HEALTHCHECK_LOGS` | *unset* | Silences verbose scheduler logging |

The **sweep interval** is hardcoded in [`src/lib/tokenHealthCheck.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheck.ts):

```typescript
const TICK_MS = 60 * 1000; // 60 seconds between full sweeps

```

## Job Registration and Scheduling

The scheduler is registered in [[`src/lib/jobs/tokenHealthCheckJob.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/jobs/tokenHealthCheckJob.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/jobs/tokenHealthCheckJob.ts):

```typescript
import { scheduleJob } from "@/open-sse/jobs";
import { startTokenHealthCheck } from "@/lib/tokenHealthCheck";

export const TOKEN_HEALTH_CHECK_INTERVAL_MS = 60_000;

scheduleJob({
  name: "tokenHealthCheck",
  intervalMs: TOKEN_HEALTH_CHECK_INTERVAL_MS,
  handler: startTokenHealthCheck,
});

```

This creates a `setInterval` timer that calls `startTokenHealthCheck()` every 60 seconds. The job starts automatically unless `OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK` is set.

## Step-by-Step Configuration

### 1. Create or Edit Environment File

Add scheduler variables to your `.env` file or export them in your shell:

```bash

# .env - Token health check scheduler configuration

HEALTHCHECK_STAGGER_MS=5000
HEALTHCHECK_JITTER_MIN_MS=1000
HEALTHCHECK_JITTER_MAX_MS=8000
HEALTHCHECK_BATCH_SIZE=50
OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS=openai,anthropic

# OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK=1  # uncomment to disable

```

### 2. Restart OmniRoute

Environment variables are read once at startup. Restart the server to apply changes:

```bash
npm run start

# or

yarn start

```

### 3. Verify Configuration

Check scheduler status through OmniRoute's monitoring. The MCP tool `observability_snapshot` or the internal health endpoint (exposed via MCP) shows whether health checks are active and any disabled flags.

## Code Examples

### Reading Configuration in [`tokenHealthCheck.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tokenHealthCheck.ts)

```typescript
// src/lib/tokenHealthCheck.ts
const TICK_MS = 60 * 1000;

const staggerMs = parseInt(process.env.HEALTHCHECK_STAGGER_MS ?? "3000", 10);
const jitterMin = parseInt(process.env.HEALTHCHECK_JITTER_MIN_MS ?? "500", 10);
const jitterMax = parseInt(process.env.HEALTHCHECK_JITTER_MAX_MS ?? "5000", 10);
const batchSize = process.env.HEALTHCHECK_BATCH_SIZE 
  ? parseInt(process.env.HEALTHCHECK_BATCH_SIZE, 10) 
  : undefined;

const skipProviders = new Set(
  (process.env.OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS ?? "")
    .split(",")
    .map(s => s.trim())
    .filter(Boolean)
);

export async function startTokenHealthCheck(): Promise<void> {
  if (isEnvFlagEnabled("OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK")) {
    log("Token health check disabled by env flag.");
    return;
  }

  const connections = getAllProviderConnections()
    .filter(c => !skipProviders.has(c.providerId));

  // Apply stagger + jitter per connection
  for (let i = 0; i < connections.length; i++) {
    const conn = connections[i];
    const jitter = randomInt(jitterMin, jitterMax);
    const delay = staggerMs + (jitter * i);
    
    setTimeout(() => refreshConnection(conn), delay);
    
    // Respect batch size if configured
    if (batchSize && i > 0 && i % batchSize === 0) {
      await sleep(TICK_MS / 2); // Yield between batches
    }
  }
}

```

### Running with Custom Configuration

```bash

# Command-line override example

HEALTHCHECK_STAGGER_MS=4000 \
HEALTHCHECK_JITTER_MIN_MS=1000 \
HEALTHCHECK_JITTER_MAX_MS=6000 \
HEALTHCHECK_BATCH_SIZE=100 \
OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS=cursor,copilot \
npm run start

```

## Provider-Specific Health Check Modules

| File | Purpose |
|------|---------|
| [[`src/lib/tokenHealthCheck.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheck.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/tokenHealthCheck.ts) | Core sweep logic, environment variable parsing, and generic token refresh |
| [[`src/lib/tokenHealthCheckCursor.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheckCursor.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/tokenHealthCheckCursor.ts) | Cursor IDE token refresh handling |
| [[`src/lib/tokenHealthCheckCopilot.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheckCopilot.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/tokenHealthCheckCopilot.ts) | GitHub Copilot sub-token management |
| [[`docs/ENVIRONMENT.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/ENVIRONMENT.md)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/docs/ENVIRONMENT.md) | Complete environment variable reference |

## Summary

- **Enable/disable**: Set `OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK` to disable the scheduler entirely
- **Control timing**: Adjust `HEALTHCHECK_STAGGER_MS` and jitter variables to spread load across your infrastructure
- **Limit scope**: Use `OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS` to exclude specific providers from validation
- **Throttle processing**: Set `HEALTHCHECK_BATCH_SIZE` to cap connections processed per sweep tick
- **Reduce noise**: Enable `OMNIROUTE_HIDE_HEALTHCHECK_LOGS` to suppress verbose scheduler output
- **Restart required**: All environment variables are read at startup; changes require a server restart

## Frequently Asked Questions

### How do I completely disable the token health check scheduler?

Set the environment variable `OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK` to any truthy value (e.g., `1`, `true`). The scheduler checks this flag in [[`src/lib/tokenHealthCheck.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheck.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/tokenHealthCheck.ts) at the start of each sweep and exits immediately if enabled.

### Can I change how often the health check runs?

The 60-second interval is hardcoded as `TICK_MS` in [[`src/lib/tokenHealthCheck.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/tokenHealthCheck.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/tokenHealthCheck.ts). To modify this, you must edit the source code and rebuild. Use `HEALTHCHECK_STAGGER_MS` and jitter variables to control the *spread* of work within each sweep without changing the interval itself.

### What happens if a token fails the health check?

The scheduler updates the connection's `testStatus` field and sets `rateLimitedUntil` for rate-limited or terminal failures. Failed tokens are not automatically removed; subsequent API requests through OmniRoute will skip unhealthy credentials based on this state. Retry logic with exponential backoff is applied to transient network errors.

### Why would I use `HEALTHCHECK_BATCH_SIZE`?

Large deployments with hundreds of provider connections can experience CPU or I/O spikes during sweeps. Setting `HEALTHCHECK_BATCH_SIZE` caps the number of connections processed before yielding, spreading the workload across multiple ticks and preventing event loop starvation.