06.06 — lib/redis.ts + Upstash#

Source file: lib/redis.ts

Code#

import { Redis } from "@upstash/redis";

const redis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL,
  token: process.env.UPSTASH_REDIS_REST_TOKEN,
});

export default redis;

Why @upstash/redis rather than ioredis#

Criterionioredis@upstash/redis
ProtocolTCP / RESPHTTP / REST
Edge runtime❌ No✅ Yes
ConnectionPersistentPer-request
Latency (warm)< 1ms50–100ms
Latency (cold)200ms+50–100ms
CostVariablePay-per-request
SetupSelf-hosted RedisUpstash dashboard (managed)

Edge doesn’t accept persistent TCP connections — each worker is ephemeral. Upstash REST it is.

Singleton#

const redis = new Redis({...});
export default redis;

Created once at module import (cold start), reused for every request the worker serves. With reasonable traffic the worker stays warm.

Env var consumption#

url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN,
UPSTASH_REDIS_REST_URL    = "https://us1-something-12345.upstash.io"
UPSTASH_REDIS_REST_TOKEN  = "AcdefGHi..."

The token is JWT-like, generated by Upstash and scoped to a specific Redis database.

vercel env add#

The README details:

vercel env add API_SECRET
vercel env add UPSTASH_REDIS_REST_URL
vercel env add UPSTASH_REDIS_REST_TOKEN
vercel deploy

Three vercel env adds, then vercel deploy. No local config needed.

API#

Redis methodEndpointUse
redis.set(key, value, { ex: ttl })/api/otpSET with TTL
redis.scan(cursor, { match, count })/api/otp-historyCursor-based SCAN
redis.mget(...keys)/api/otp-historyMGET (multi-get)

Error handling#

@upstash/redis throws on network or server errors. The code doesn’t catch them — they bubble up to Vercel’s handler as 500 Internal Server Error.

  • On Igoristan: the user sees an OTP error and retries.
  • On Ocarina: transient_errors catches and retries.

No explicit timeout#

const redis = new Redis({
  url: ...,
  token: ...,
});

No explicit timeout. @upstash/redis defaults to ~5s. The Edge runtime has its own hard limit (10s on Vercel) — so even if the client doesn’t time out, Vercel will.