---
title: "Redis"
description: "Use Redis for the MainSDK key-value store and cache - setup, main.yaml, connection secret, TTLs, tag invalidation, local testing and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/redis"
updated: "2026-10-28"
---

# Redis

> Use Redis for the MainSDK key-value store and cache - setup, main.yaml, connection secret, TTLs, tag invalidation, local testing and swapping.

Canonical: https://mainsdk.dev/docs/integrations/redis · Updated: 2026-10-28

Redis is a driver behind [`kv`](https://mainsdk.dev/docs/interfaces/kv), the interface for small values and cached results. Your app calls `kv.set()`, `cache.wrap()` and `cache.invalidate()`, and the values live in your Redis server with an expiry on every entry. Pick it when you already run Redis, self-hosted or on a managed service, or when you want the cache inside your own network.

> **Note:** `kv` has no spec yet. The calls and options on this page are provisional, taken from the catalog and the product requirements, and may change when the spec lands.

## Interfaces it serves

### Key-value store and cache (`kv`)

- Status: Building for 0.3 · ships as a beta API
- Driver: `redis` (Redis)
- Docs: https://mainsdk.dev/docs/interfaces/kv.md

```yaml
kv:
  driver: redis
```

Swap to another provider: `local`, `upstash`, `vercel-runtime-cache`, `cloudflare-kv`.

### Usage metering (`meter`)

- Status: Building for 0.3 · ships as a beta API
- Driver: `redis` (Redis (built-in RESP client))
- Docs: https://mainsdk.dev/docs/interfaces/meter.md

```yaml
meter:
  driver: redis
```

Swap to another provider: `db`, `local`, `stripe-meters`, `lago`.

### Rate limits and quotas (`limits`)

- Status: Building for 0.3 · ships as a beta API
- Driver: `redis` (Redis)
- Docs: https://mainsdk.dev/docs/interfaces/limits.md

```yaml
limits:
  driver: redis
```

Swap to another provider: `local`, `arcjet`.

### Runtime settings (`config`)

- Status: Building for 0.2 · ships as a stable API
- Driver: `redis` (Redis)
- Docs: https://mainsdk.dev/docs/interfaces/config.md

```yaml
config:
  driver: redis
```

Swap to another provider: `files`, `local`, `postgres`, `vercel-global-config`, `aws-appconfig`, `cloudflare-kv`.

## Before you start

1. **Get a Redis server.** Run it yourself or use a managed service, in the region where your app runs so cache reads stay fast.
2. **Turn on authentication and TLS.** Give the app its own user and password, and connect over TLS when the server is outside your private network.
3. **Copy the connection URL.** It carries the host, port and credentials, so store it in your secrets manager.

## Configure

```yaml title="main.yaml"
kv:
  driver: redis
  # url: secret:REDIS_URL   # suggested name; the connection key's name is [TBD] until the kv spec
```

There is no default TTL: you pass `ttl` on every write.

## Use it

```ts title="lib/prices.ts"
import { cache } from "mainsdk";

export async function pricesFor(market: string) {
  return cache.wrap(`prices:${market}`, () => loadPrices(market), {
    ttl: "5m",
    tags: ["prices"],
  });
}
```

After you publish new prices, drop every entry tagged `prices` with `cache.invalidate("prices")`.

## Local development and testing

- **No server:** tests and `mainsdk dev` don't need Redis. The local driver for `kv` is not named yet [TBD].
- **A local Redis:** run Redis on your machine or in a container to test against the real server.
- **Tests:** `createTestApp()` from `@mainsdk/testing` runs `kv` on its in-memory fake. Use `clock.advance()` to pass a TTL without waiting, and `chaos.on("kv", { outage: true })` to simulate Redis going down.

## What MainSDK adds on top

- Keys scoped per tenant, so one customer never reads another's cached data.
- No personal data in shared caches without a label.
- Every entry has a TTL; nothing lingers.
- Tag invalidation through `cache.invalidate(tag)`.

See [Key-value store and cache](https://mainsdk.dev/docs/interfaces/kv) for the full contract.

## Limits and notes

- `redis` is a planned `kv` driver for phase 1; `kv` has no spec yet.
- Keep the server in the same region as the app and its data. Cached values that hold personal data follow the same residency rules as the records they came from; see [Data and regions](https://mainsdk.dev/docs/concepts/data-and-regions).
- Use [`db`](https://mainsdk.dev/docs/interfaces/db), not `kv`, for data you must keep.

## Swap to or from it

```yaml title="main.yaml"
kv:
  driver: redis   # was upstash
```

Cached entries are not carried over; they refill as they expire. No migration is needed.

## FAQ

**Can I store a value that never expires?** No. Every entry has a TTL. Use `db` for data you keep.

**Can I use Redis for rate limits too?** `limits` lists built in, Upstash and Arcjet as drivers; plain Redis is not one of them yet.

## Next

- [Key-value store and cache](https://mainsdk.dev/docs/interfaces/kv)
- [Upstash](https://mainsdk.dev/docs/integrations/upstash), [Vercel](https://mainsdk.dev/docs/integrations/vercel) and [Cloudflare KV](https://mainsdk.dev/docs/integrations/cloudflare-kv)
- [Swap a driver](https://mainsdk.dev/docs/guides/swap-a-driver)
