Realtime
Quickstart
Upstash Realtime is the easiest way to add realtime features to any Next.js project.

Why Upstash Realtime?
- 𧨠Clean APIs & first-class TypeScript support
- β‘ Extremely fast, zero dependencies, 2.6kB gzipped
- π» Deploy anywhere: Vercel, Netlify, etc.
- π 100% type-safe with zod 4 or zod mini
- β±οΈ Built-in message histories
- π Automatic connection management w/ delivery guarantee
- π Built-in middleware and authentication helpers
- πΆ 100% HTTP-based: Redis streams & SSE
Quickstart
1. Installation
npm
npm install @upstash/realtime @upstash/redis zodyarn
yarn add @upstash/realtime @upstash/redis zodpnpm
pnpm add @upstash/realtime @upstash/redis zodbun
bun install @upstash/realtime @upstash/redis zod2. Configure Upstash Redis
Upstash Realtime is powered by Redis Streams. Grab your credentials from the Upstash Console.

Add them to your environment variables:
.env
UPSTASH_REDIS_REST_URL=https://striking-osprey-20681.upstash.ioUPSTASH_REDIS_REST_TOKEN=AVDJAAIjcDEyZ...And lastly, create a Redis instance:
lib/redis.ts
import { Redis } from "@upstash/redis"export const redis = new Redis({ url: process.env.UPSTASH_REDIS_REST_URL, token: process.env.UPSTASH_REDIS_REST_TOKEN,})3. Define Event Schema
Define the structure of realtime events in your app:
lib/realtime.ts
import { Realtime, InferRealtimeEvents } from "@upstash/realtime"import { redis } from "./redis"import z from "zod/v4"const schema = { notification: { alert: z.string(), },}export const realtime = new Realtime({ schema, redis })export type RealtimeEvents = InferRealtimeEvents<typeof realtime>4. Create Realtime Route Handler
Create a route handler at api/realtime/route.ts:
app/api/realtime/route.ts
import { handle } from "@upstash/realtime"import { realtime } from "@/lib/realtime"export const GET = handle({ realtime })5. Add the Provider
Wrap your application in RealtimeProvider:
app/providers.tsx
"use client"import { RealtimeProvider } from "@upstash/realtime/client"export function Providers({ children }: { children: React.ReactNode }) { return <RealtimeProvider>{children}</RealtimeProvider>}app/layout.tsx
import { Providers } from "./providers"export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html> <body> <Providers>{children}</Providers> </body> </html> )}6. Create Typed Client Hook
Create a typed useRealtime hook for your client components:
lib/realtime-client.ts
"use client"import { createRealtime } from "@upstash/realtime/client"import type { RealtimeEvents } from "./realtime"export const { useRealtime } = createRealtime<RealtimeEvents>()7. Emit Events
From any server component, server action, or API route:
app/api/notify/route.ts
import { realtime } from "@/lib/realtime"export const POST = async () => { await realtime.emit("notification.alert", "hello world!") return new Response("OK")}8. Subscribe to Events
In any client component:
app/components/notifications.tsx
"use client"import { useRealtime } from "@/lib/realtime-client"export default function Notifications() { useRealtime({ events: ["notification.alert"], onData({ event, data, channel }) { console.log(`Received ${event}:`, data) }, }) return <p>Listening for events...</p>}That's it! Your app is now listening for realtime events with full type safety. π
9. Realtime Dashboard
For debugging or monitoring purposes, you can use Realtime Dashboard in console.
