Core concepts
Private Chat combines three key mechanisms to create truly ephemeral chat rooms:- Time-limited rooms - Every room expires after exactly 10 minutes
- Real-time messaging - WebSocket-powered instant message delivery
- Token-based access - Secure room access via HTTP-only cookies
Room lifecycle
Room creation
When a user clicks CREATE ROOM, the server generates a unique room ID using The room TTL (Time To Live) is set to 600 seconds (10 minutes).
nanoid and stores minimal metadata in Redis:src/app/api/[[...slugs]]/route.ts:13
Room access
Users access rooms via URL:
/room/[roomId]On first visit, the client receives an authentication token stored as an HTTP-only cookie. This token is added to the room’s connected array in Redis.Authentication tokens are validated on every API request via the
AuthMiddleware in src/app/api/[[…slugs]]/auth.ts:11Message exchange
Messages are stored temporarily in Redis and broadcast to all connected clients via Upstash Realtime:Each message gets the same TTL as the room, ensuring synchronized expiration.
src/app/api/[[...slugs]]/route.ts:74
Automatic expiration
Redis automatically deletes all room data after 10 minutes:
- Room metadata (
meta:{roomId}) - Message history (
messages:{roomId}) - Any associated keys
src/app/room/[roomId]/page.tsx:68
Real-time messaging architecture
Private Chat uses Upstash Realtime for WebSocket communication:Server-side setup
Define the event schema with Zod validation:src/lib/realtime.ts:5
Client-side subscription
Clients subscribe to room channels and listen for events:src/app/room/[roomId]/page.tsx:107
Message flow
Data storage model
All data is stored in Redis with automatic expiration:Room metadata
Message history
Message structure
src/types/message.ts:3
Authentication flow
Private Chat uses cookie-based authentication without user accounts:Generate username
When a user first visits, a random username is generated client-side and stored in localStorage:
src/lib/username.ts:1
Token assignment
When joining a room, the server issues an auth token stored as an HTTP-only cookie named
x-auth-token.Tokens expire when the room is destroyed. No permanent authentication state is maintained.
Self-destruction mechanism
Rooms self-destruct through two paths:Automatic expiration (10 minutes)
- Redis TTL expires automatically
- All keys (
meta:*,messages:*) are deleted - Clients poll
/api/room/ttlto track remaining time - When TTL reaches 0, clients redirect to lobby
Manual destruction
- User clicks DESTROY NOW button
- API emits
chat.destroyevent via Realtime - API deletes all room keys from Redis
- All connected clients receive event and redirect
src/app/room/[roomId]/page.tsx:163
Scalability considerations
Serverless-ready
Built on Next.js with serverless-compatible architecture. No persistent connections on server.
Redis offloading
Upstash Redis handles data storage and expiration. No application-level cleanup needed.
WebSocket infrastructure
Upstash Realtime manages WebSocket connections. No manual scaling required.
Stateless API
API routes are completely stateless. Easy horizontal scaling.
Security features
- HTTP-only cookies - Auth tokens inaccessible to JavaScript
- Token validation - Every request checks room membership
- No permanent storage - Data automatically expires
- Rate limiting - Message text limited to 1000 characters, sender name to 100
- Input validation - Zod schemas validate all API inputs
Next steps
Deploy to production
Launch your instance on Vercel
API reference
Explore REST endpoints in detail
Redis data model
Deep dive into data storage patterns
WebSocket implementation
Learn about Upstash Realtime integration