# How to Configure Redis or KV for Open Agents Skills Metadata Caching

> Configure Redis or KV for Open Agents skills metadata caching using REDIS_URL or KV_URL environment variables. Enhance performance with a two-layer cache system.

- Repository: [Vercel Labs/open-agents](https://github.com/vercel-labs/open-agents)
- Tags: how-to-guide
- Published: 2026-04-16

---

**You can configure Redis or KV for Open Agents skills metadata caching by setting either `REDIS_URL` or `KV_URL` environment variables, which automatically enables a two-layer cache system combining in-memory storage with persistent Redis storage.**

The **vercel-labs/open-agents** repository implements a robust caching strategy for skill metadata that falls back to in-memory storage when Redis is unavailable. When you configure Redis or KV for Open Agents skills metadata caching, the system uses the `ioredis` client to persist skill arrays across server restarts and horizontal scaling events.

## How Redis and KV Caching Works in Open Agents

Open Agents uses a two-layer caching architecture defined in **[`apps/web/lib/skills-cache.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/skills-cache.ts)**. The primary layer is an in-memory `Map` object that provides microsecond-level access speeds. When you configure Redis or KV for Open Agents skills metadata caching by providing a connection URL, the system adds a secondary persistent layer via **[`apps/web/lib/redis.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/redis.ts)**.

The Redis integration activates automatically when `isRedisConfigured()` returns `true`, which occurs when either `REDIS_URL` or `KV_URL` environment variables are detected. The `createRedisClient(connectionName)` function then instantiates an `ioredis` client with connection pooling and automatic reconnection logic.

## Step 1: Set Environment Variables for Redis or KV

To enable Redis or KV for skills metadata caching, configure one of the following environment variables in your deployment environment:

| Variable | Purpose | Example Values |
|----------|---------|----------------|
| `REDIS_URL` | Primary Redis configuration (takes precedence) | `redis://user:pass@host:6379/0`, `rediss://host:6380`, `localhost:6379`, `/tmp/redis.sock?db=1` |
| `KV_URL` | Alternative variable for Upstash KV or legacy deployments | `rediss://:mySecret@my-redis.upstash.io:6379` |

The URL parser in **[`apps/web/lib/redis.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/redis.ts)** handles multiple formats including plain host:port combinations, Unix socket paths, and full URIs with authentication credentials. If you provide both variables, `REDIS_URL` takes precedence and `KV_URL` is ignored.

## Step 2: Verify Redis Configuration in Code

After setting environment variables, verify that Open Agents detects your Redis configuration using the helper functions in **[`apps/web/lib/redis.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/redis.ts)**:

```typescript
import { isRedisConfigured, createRedisClient, warnRedisDisabled } from "@/apps/web/lib/redis";

if (!isRedisConfigured()) {
  warnRedisDisabled("skills-cache");
  console.log("Running with in-memory cache only");
} else {
  const client = createRedisClient("verification-test");
  console.log("Redis client created successfully");
  
  // Test connectivity
  await client.ping();
}

```

The `isRedisConfigured()` function checks for the presence of `REDIS_URL` or `KV_URL` at line 23 of **[`redis.ts`](https://github.com/vercel-labs/open-agents/blob/main/redis.ts)**. When configuration is detected, `createRedisClient()` builds an `ioredis` options object that handles TLS, authentication, and database selection automatically.

## Step 3: Configure Skills Cache TTL and Behavior

The skills cache in **[`apps/web/lib/skills-cache.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/skills-cache.ts)** uses a default **4-hour TTL** (14,400 seconds) defined by `SKILLS_CACHE_TTL_SECONDS`. You can customize this behavior when creating cache instances:

```typescript
import { createSkillsCache } from "@/apps/web/lib/skills-cache";

// Create a cache with 30-minute TTL instead of default 4 hours
const shortLivedCache = createSkillsCache({ 
  ttlSeconds: 30 * 60 
});

// Use the custom cache
await shortLivedCache.set("session-123", sandboxState, skillList);
const skills = await shortLivedCache.get("session-123", sandboxState);

```

The cache key format uses the prefix `skills:v1` generated by `getSkillsCacheKey()`. When Redis is configured, the `set()` method stores JSON-encoded skill arrays using Redis's `SET ... EX` command with your specified TTL.

## Using the Skills Cache in Your Application

Integrate the skills cache into your application logic using the singleton exports from **[`apps/web/lib/skills-cache.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/skills-cache.ts)**:

```typescript
import { getCachedSkills, setCachedSkills } from "@/apps/web/lib/skills-cache";

async function loadSkillsForSession(sessionId: string, sandboxState: unknown) {
  // Attempt to retrieve from cache (memory or Redis)
  const cachedSkills = await getCachedSkills(sessionId, sandboxState);
  
  if (cachedSkills) {
    console.log("Cache hit: returning cached skill metadata");
    return cachedSkills;
  }
  
  // Cache miss: fetch from source
  console.log("Cache miss: computing fresh skill metadata");
  const freshSkills = await computeAvailableSkills(sandboxState);
  
  // Store for future requests
  await setCachedSkills(sessionId, sandboxState, freshSkills);
  return freshSkills;
}

```

The `getCachedSkills()` and `setCachedSkills()` functions use a shared singleton instance (`sharedSkillsCache`) created at the module level. This ensures consistent cache state across your application while maintaining the two-layer fallback behavior.

## Testing and Debugging Your Redis Configuration

Verify your Redis configuration using the test suite provided in the repository:

```bash

# Run Redis configuration tests

bun test apps/web/lib/redis.test.ts

# Run skills cache integration tests

bun test apps/web/lib/skills-cache.test.ts

```

For debugging connection issues, use this diagnostic snippet:

```typescript
import { createRedisClient, isRedisConfigured } from "@/apps/web/lib/redis";

if (isRedisConfigured()) {
  const client = createRedisClient("debug");
  
  client.on("connect", () => console.log("Redis connected"));
  client.on("error", (err) => console.error("Redis error:", err));
  client.on("reconnecting", () => console.log("Redis reconnecting"));
  
  // Test the connection
  await client.ping();
} else {
  console.log("Redis not configured - check REDIS_URL or KV_URL env vars");
}

```

The tests verify URL parsing for various formats (plain ports, Unix sockets, TLS URLs) and confirm the fallback behavior when Redis is unavailable.

## Summary

- **Environment Variables**: Set `REDIS_URL` or `KV_URL` to activate Redis caching; `REDIS_URL` takes precedence if both are present.
- **Architecture**: Open Agents uses a two-layer cache system in **[`apps/web/lib/skills-cache.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/skills-cache.ts)** with an in-memory `Map` and optional Redis persistence via **[`apps/web/lib/redis.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/redis.ts)**.
- **Configuration**: The Redis client supports multiple URL formats including `redis://`, `rediss://`, Unix sockets, and plain host:port combinations with automatic TLS handling.
- **TTL Control**: Default cache expiration is 4 hours (14,400 seconds), customizable via `createSkillsCache({ ttlSeconds: ... })`.
- **Integration**: Use `getCachedSkills()` and `setCachedSkills()` for standard operations, or `createSkillsCache()` for custom cache instances.

## Frequently Asked Questions

### What is the difference between using REDIS_URL and KV_URL in Open Agents?

`REDIS_URL` and `KV_URL` serve identical functions in Open Agents, but `REDIS_URL` takes precedence if both environment variables are set. The codebase uses `KV_URL` primarily for backwards compatibility with older deployments using Upstash KV, while `REDIS_URL` is the recommended variable for standard Redis or Redis-compatible services.

### How long does the skills metadata cache persist by default?

The default **time-to-live (TTL)** for skills metadata caching is **4 hours** (14,400 seconds), defined by the `SKILLS_CACHE_TTL_SECONDS` constant in **[`apps/web/lib/skills-cache.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/skills-cache.ts)**. You can override this default when creating a custom cache instance using `createSkillsCache({ ttlSeconds: 1800 })` for 30 minutes, or any other duration appropriate for your use case.

### Can Open Agents connect to Redis via Unix socket instead of TCP?

Yes, Open Agents supports Unix socket connections for Redis. You can specify a Unix socket path in your `REDIS_URL` or `KV_URL` environment variable, such as `/tmp/redis.sock?db=1`. The connection parser in **[`apps/web/lib/redis.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/redis.ts)** automatically detects Unix socket paths and configures the `ioredis` client appropriately, including support for database selection via query parameters.

### What happens if Redis is unavailable or misconfigured?

If Redis is unavailable or not configured, Open Agents automatically falls back to an **in-memory-only cache** using a JavaScript `Map` object. The `isRedisConfigured()` function in **[`apps/web/lib/redis.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/redis.ts)** checks for the presence of `REDIS_URL` or `KV_URL`; if neither is set, the system logs a warning via `warnRedisDisabled()` and continues operating with the in-memory cache layer from **[`apps/web/lib/skills-cache.ts`](https://github.com/vercel-labs/open-agents/blob/main/apps/web/lib/skills-cache.ts)**. This ensures your application remains functional even without Redis, though cache data will not persist across server restarts.