---
title: Redis
description: The recommended production store. Live streams are pushed, not polled.
---

```ts server/orders.ts
import { createServer } from 'experimental-a2/server'
import { redis } from 'experimental-a2/store-redis'
import { orders } from '@/contracts'

export const ordersServer = createServer({
  contract: orders,
  store: redis({ url: process.env.REDIS_URL }),
  handlers: {
    /* ... */
  },
})
```

```package-install
npm i ioredis
```

Works on a single Redis instance and on non-cluster providers such as Upstash,
which is durable by default (use its TCP `rediss://` URL). There's nothing to
set up: A2 creates its keys as it writes.

## Options

| Option | |
| --- | --- |
| `url` | creates an `ioredis` client |
| `client` | your own `ioredis` client instead |
| `keyPrefix` | isolates several apps on one Redis. Default `'a2'` |
| `clock`, `ids` | test seams for timestamps and generated event ids |

## How it works

- Each session is a Redis Stream.
- Every write publishes a wake-up, so live streams are push-driven, and
  connections scale with your processes, not with your viewers.
- A wake-up is disposable: a safety re-read recovers a lost one within ten
  seconds.

## Cost per command

On providers that bill per command, such as Upstash, appending an event with a
handler and running it takes 24 commands, and an idle live stream takes 6 a
minute.
