A developer built a Next.js app on Vercel. He needed rate limiting. Regular Redis needs a persistent connection — doesn't work in serverless. Upstash Redis works over HTTP — perfect for serverless functions.
What Upstash Offers for Free
Upstash free tier:
- Redis: 10,000 commands/day, 256 MB storage
- Kafka: 10,000 messages/day, 256 MB storage
- QStash (message queue): 500 messages/day
- Vector (vector DB): 10,000 queries/day, 10,000 vectors
- HTTP-based — works in any serverless environment
- Global replication — multi-region by default
- No credit card required
Redis over HTTP
# Works from Vercel Edge, Cloudflare Workers, Lambda, etc.
curl 'https://YOUR_ENDPOINT.upstash.io/set/mykey/hello' \
-H 'Authorization: Bearer YOUR_TOKEN'
curl 'https://YOUR_ENDPOINT.upstash.io/get/mykey' \
-H 'Authorization: Bearer YOUR_TOKEN'
# Returns: "hello"
SDK
import { Redis } from '@upstash/redis';
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN
});
// Basic operations
await redis.set('user:123', { name: 'Alice', plan: 'pro' });
const user = await redis.get('user:123');
// Set with expiry
await redis.setex('session:abc', 3600, { userId: '123' });
// Increment
await redis.incr('page:views:home');
// Sorted set (leaderboard)
await redis.zadd('leaderboard', { score: 100, member: 'alice' });
await redis.zadd('leaderboard', { score: 200, member: 'bob' });
const top = await redis.zrange('leaderboard', 0, 9, { rev: true });
Rate Limiting (Serverless)
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(10, '10 s'), // 10 requests per 10 seconds
});
// In your API route (Next.js, Vercel Edge, etc.)
export default async function handler(req) {
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': String(limit),
'X-RateLimit-Remaining': String(remaining),
'X-RateLimit-Reset': String(reset)
}
});
}
return new Response('OK');
}
QStash (Message Queue)
import { Client } from '@upstash/qstash';
const qstash = new Client({ token: process.env.QSTASH_TOKEN });
// Send a message to a URL (will be delivered reliably)
await qstash.publishJSON({
url: 'https://yourapp.com/api/process-order',
body: { orderId: '123', action: 'fulfill' },
retries: 3,
delay: '10s' // deliver after 10 seconds
});
// Schedule recurring messages
await qstash.publishJSON({
url: 'https://yourapp.com/api/daily-report',
body: { type: 'daily' },
cron: '0 9 * * *' // every day at 9 AM
});
Vector Database
import { Index } from '@upstash/vector';
const index = new Index({
url: process.env.UPSTASH_VECTOR_REST_URL,
token: process.env.UPSTASH_VECTOR_REST_TOKEN
});
// Upsert vectors
await index.upsert([{
id: 'doc-1',
vector: [0.1, 0.2, 0.3, ...], // 384-dim embedding
metadata: { title: 'How to use Redis', category: 'tutorial' }
}]);
// Query similar vectors
const results = await index.query({
vector: [0.1, 0.2, 0.3, ...],
topK: 5,
includeMetadata: true
});
Perfect For
- Vercel/Netlify — HTTP Redis works in Edge Functions
- Rate limiting — built-in library
- Caching — serverless-friendly cache layer
- Background jobs — QStash for reliable job processing
- AI apps — vector DB for RAG/embeddings
Need serverless web scraping? Check out my web scraping actors on Apify — serverless by design.
Need serverless infrastructure? Email me at spinov001@gmail.com.
Top comments (0)