# How OAuth KV Garbage Collection Detects Oversized Keyspaces and Handles the 'done: false' Warning

> Learn how Open-SEO's OAuth KV garbage collector identifies oversized keyspaces and clarifies the 'done: false' warning indicating incomplete namespace scans.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: internals
- Published: 2026-09-12

---

**Open-SEO's OAuth KV garbage collector detects oversized keyspaces by checking the `done` flag returned from batched Cloudflare KV list operations, where `done: false` indicates the batch size was insufficient to scan the entire namespace in a single pass.**

The `every-app/open-seo` repository stores OAuth grants and tokens in a Cloudflare KV namespace (`OAUTH_KV`). Because KV entries persist until their TTL expires, orphaned records from expired client registrations can accumulate indefinitely. A daily scheduled task runs a **KV garbage collector** that sweeps the keyspace and purges dead records before they consume excessive storage.

## How the OAuth KV Garbage Collector Works

The garbage collection process operates through a scheduled cron job defined in [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts). When the `MCP_OAUTH_PURGE_CRON` trigger fires, the system invokes `openSeoOAuthProvider.purgeExpiredData()` to initiate a batched scan of the KV namespace.

The underlying provider uses Cloudflare's KV `list` API to iterate over keys in chunks. By default, the system processes **200 keys per batch** (`batchSize: 200`). After each batch completes, the provider returns a result object containing metadata about the iteration state.

```typescript
// src/server.ts – scheduled handler
if (controller.cron === MCP_OAUTH_PURGE_CRON) {
  const result = await openSeoOAuthProvider.purgeExpiredData(env as OpenSeoOAuthEnv);
  console.log("[mcp-oauth] purged expired OAuth data", result);
  if (!result.done) {
    console.warn("[mcp-oauth] purge did not cover the full keyspace");
  }
}

```

## Detecting Oversized Keyspaces with the `done` Flag

The provider's `purgeExpiredData` method walks the KV namespace sequentially. When the number of live keys **exceeds** the configured batch capacity, the iteration halts before reaching the end of the keyspace. The method returns an object with a `done` property indicating whether the scan visited every key.

- **`done: true`**: The sweep traversed the entire keyspace and deleted all expired entries.
- **`done: false`**: The keyspace contains more records than the current batch size can process in one invocation.

The scheduled handler in [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) explicitly checks this flag to detect when the OAuth KV store has grown beyond the batch limit.

## What the 'done: false' Warning Means

When the console logs `"[mcp-oauth] purge did not cover the full keyspace"`, this **does not indicate an error**. Instead, it signals an **incomplete sweep** due to keyspace size constraints.

The garbage collector employs an idempotent scanning strategy. The next scheduled run (typically the following day) resumes from the previous cursor position, eventually cleaning the entire namespace once the record count drops below the batch threshold. Until then, the warning alerts operators that the KV store accumulates more OAuth records than the current configuration can handle in a single pass.

## Configuring Batch Sizes and Scheduling

You can adjust the throughput by modifying the `batchSize` parameter passed to the OAuth provider. The configuration resides in [`src/server/mcp/oauth-provider.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-provider.ts).

```typescript
// src/server/mcp/oauth-provider.ts – expose purge method
purgeExpiredData(env: OpenSeoOAuthEnv) {
  // Batch size large enough for most workloads; adjust if keyspace grows.
  return getProvider().purgeExpiredData(env, { batchSize: 200 });
}

```

If your deployment consistently triggers the `done: false` warning, increase the `batchSize` value or reduce the cron interval to run multiple times daily. Monitor your Cloudflare KV usage metrics to determine optimal settings for your workload volume.

## Summary

- Open-SEO uses a daily cron job in [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) to trigger OAuth KV garbage collection via `purgeExpiredData()`.
- The provider scans the KV namespace in batches of 200 keys by default.
- The `done` flag returned from the scan indicates whether the iteration completed the full keyspace.
- **`done: false`** specifically signals that the keyspace exceeded the batch capacity, requiring multiple passes to fully clean.
- Operators should increase `batchSize` or scheduling frequency if the warning appears consistently.

## Frequently Asked Questions

### Why does Open-SEO need a garbage collector for OAuth KV data?

Cloudflare KV only expires entries based on their TTL values. Orphaned grants and tokens from expired or deleted OAuth client registrations lack active TTL management and persist indefinitely. The garbage collector proactively removes these dead records to prevent unbounded storage growth in the `OAUTH_KV` namespace.

### Is `done: false` an error that requires immediate intervention?

No. `done: false` is an informational signal, not a failure state. The system designed the garbage collector to operate across multiple scheduled runs when necessary. However, consistent warnings indicate the keyspace outgrew your configured batch size, suggesting you should increase the `batchSize` parameter in [`src/server/mcp/oauth-provider.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-provider.ts) or schedule more frequent cleanup runs.

### How can I increase the batch size for OAuth KV garbage collection?

Modify the `batchSize` option in the `purgeExpiredData` method within [`src/server/mcp/oauth-provider.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/oauth-provider.ts). The default value is 200. Increasing this number allows each scheduled invocation to process more keys, reducing the likelihood of incomplete sweeps. Ensure your Cloudflare Worker execution limits can accommodate larger batch operations without timing out.