M

Master Upstash Suite

Battle-tested skill for upstash, qstash, expert, serverless. Includes structured workflows, validation checks, and reusable patterns for web development.

SkillClipticsweb developmentv1.0.0MIT
0 views0 copies

Upstash Suite

A serverless data platform skill for using Upstash Redis, Kafka, and QStash in serverless and edge environments, covering caching, message queues, rate limiting, and scheduled tasks.

When to Use

Choose Upstash Suite when:

  • Adding Redis caching to serverless functions (Vercel, Cloudflare Workers, AWS Lambda)
  • Implementing rate limiting, session storage, or leaderboards at the edge
  • Building event-driven architectures with managed Kafka
  • Scheduling tasks and webhooks with QStash

Consider alternatives when:

  • Running on traditional servers — use self-hosted Redis or Kafka
  • Needing complex SQL queries — use a relational database
  • Building real-time websocket features — use a dedicated real-time service

Quick Start

# Install Upstash packages npm install @upstash/redis @upstash/ratelimit @upstash/kafka @upstash/qstash
import { Redis } from '@upstash/redis'; const redis = Redis.fromEnv(); // Basic key-value operations await redis.set('user:123', JSON.stringify({ name: 'Jane', plan: 'pro' })); await redis.expire('user:123', 3600); // 1 hour TTL const user = await redis.get<string>('user:123'); console.log(JSON.parse(user!)); // Rate limiting import { Ratelimit } from '@upstash/ratelimit'; const ratelimit = new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(10, '60 s'), // 10 requests per minute analytics: true }); async function handleRequest(req: Request) { const ip = req.headers.get('x-forwarded-for') || '127.0.0.1'; const { success, limit, remaining, reset } = await ratelimit.limit(ip); if (!success) { return new Response('Too Many Requests', { status: 429, headers: { 'X-RateLimit-Limit': limit.toString(), 'X-RateLimit-Remaining': remaining.toString(), 'X-RateLimit-Reset': reset.toString() } }); } return new Response('OK'); } // Caching with automatic serialization class UpstashCache { constructor(private redis: Redis, private prefix: string = 'cache') {} async get<T>(key: string): Promise<T | null> { return this.redis.get<T>(`${this.prefix}:${key}`); } async set<T>(key: string, value: T, ttlSeconds: number = 300): Promise<void> { await this.redis.set(`${this.prefix}:${key}`, JSON.stringify(value), { ex: ttlSeconds }); } async getOrSet<T>(key: string, fetcher: () => Promise<T>, ttl: number = 300): Promise<T> { const cached = await this.get<T>(key); if (cached) return cached; const fresh = await fetcher(); await this.set(key, fresh, ttl); return fresh; } async invalidate(pattern: string): Promise<void> { const keys = await this.redis.keys(`${this.prefix}:${pattern}`); if (keys.length > 0) { await this.redis.del(...keys); } } }

Core Concepts

Upstash Product Suite

ProductPurposeProtocolPricing
RedisKV store, caching, rate limitingREST + RedisPer-request
KafkaEvent streaming, message queuesREST + KafkaPer-message
QStashScheduled tasks, webhooksRESTPer-message
VectorVector similarity searchRESTPer-query

QStash Scheduled Tasks

import { Client } from '@upstash/qstash'; const qstash = new Client({ token: process.env.QSTASH_TOKEN! }); // Schedule a one-time task await qstash.publishJSON({ url: 'https://myapp.com/api/process', body: { taskId: '123', action: 'send-email' }, delay: 300 // Run after 5 minutes }); // Create a recurring schedule (cron) await qstash.schedules.create({ destination: 'https://myapp.com/api/daily-report', cron: '0 9 * * *', // Every day at 9 AM body: JSON.stringify({ report: 'daily-summary' }) }); // Publish with retry and deduplication await qstash.publishJSON({ url: 'https://myapp.com/api/webhook', body: { event: 'order.completed', orderId: 'ORD-456' }, retries: 3, deduplicationId: 'order-ORD-456' });

Configuration

OptionDescriptionDefault
UPSTASH_REDIS_REST_URLRedis REST API endpointRequired
UPSTASH_REDIS_REST_TOKENRedis authentication tokenRequired
UPSTASH_KAFKA_REST_URLKafka REST endpointOptional
UPSTASH_KAFKA_REST_TOKENKafka authentication tokenOptional
QSTASH_TOKENQStash authentication tokenOptional
QSTASH_CURRENT_SIGNING_KEYQStash webhook verification keyOptional
rate_limit_windowDefault rate limit window"60 s"
cache_ttlDefault cache TTL in seconds300

Best Practices

  1. Use Redis.fromEnv() for configuration to keep credentials out of code and automatically use the UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN environment variables
  2. Implement cache-aside pattern with getOrSet that checks cache first and only calls the expensive operation on miss — this pattern handles cache population, TTL management, and race conditions in a single method
  3. Use QStash for serverless scheduled tasks instead of cron jobs because serverless functions cannot run cron schedules; QStash calls your endpoint on schedule with built-in retry and delivery guarantees
  4. Set appropriate TTLs on all cached data to prevent stale data from persisting; use short TTLs (60-300s) for frequently changing data and longer TTLs (1-24hr) for static reference data
  5. Enable Ratelimit analytics to monitor rate limit hits and adjust thresholds based on actual usage patterns rather than guessing appropriate limits

Common Issues

Cold start latency with REST protocol: Upstash uses HTTP REST instead of persistent TCP connections, adding ~50-100ms per request compared to traditional Redis. For latency-sensitive operations, use Upstash's Edge caching or pipeline multiple commands in a single HTTP request.

Rate limiter allowing bursts above limit: The sliding window algorithm allows brief bursts at window boundaries. Use the fixedWindow limiter for strict limits, or configure a token bucket limiter for smoother rate limiting that distributes requests evenly across the window.

QStash webhook verification failing: QStash signs webhook payloads for security, and verification fails if the body is parsed or modified before signature checking. Always verify the signature against the raw request body string, not the parsed JSON, and ensure your framework does not strip or modify headers before verification.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates