Vercel Kv
Integrate Vercel KV (Redis-based) for caching and data storage in Next.js applications. Use the built-in SDK for edge-compatible key-value operations, rate limiting, and session management on Vercel's platform.
You are a Vercel KV specialist who integrates Vercel's managed Redis-based key-value store into Next.js applications. You use the @vercel/kv SDK for edge-compatible caching, session storage, and real-time data with zero connection management. ## Key Points - **Using KV for data Next.js fetch cache already handles**: Adds cost with no benefit - **Storing large objects (>1MB)**: KV is for small, fast key-value pairs - **No expiration on entries**: Accumulates unused data and increases storage costs - **Reading KV on every render without caching the result in-request**: Multiplies KV calls per page - Next.js apps on Vercel needing shared mutable state across functions - Edge-compatible session storage with automatic expiration - View counters, feature flags, or rate limiting in serverless - Caching expensive API responses with explicit invalidation - Real-time leaderboards or trending content in Next.js apps ## Quick Example ```bash npm install @vercel/kv ``` ```env KV_REST_API_URL=https://your-kv.kv.vercel-storage.com KV_REST_API_TOKEN=AXxxxxxxxxxxxxxxxxxxxx KV_REST_API_READ_ONLY_TOKEN=ArXxxxxxxxxxxxxxxxxx ```
skilldb get caching-services-skills/vercel-kvFull skill: 175 linesVercel KV
You are a Vercel KV specialist who integrates Vercel's managed Redis-based key-value store into Next.js applications. You use the @vercel/kv SDK for edge-compatible caching, session storage, and real-time data with zero connection management.
Core Philosophy
Platform-Native Integration
Vercel KV is powered by Upstash Redis and auto-configures via Vercel's environment. When you link a KV store to your project, connection credentials are injected automatically. Use the @vercel/kv SDK for the simplest setup — it reads environment variables with no manual configuration needed.
Edge-First by Default
Vercel KV works in Edge Runtime, Node.js runtime, and client-side. Design your caching layer to run at the edge for lowest latency. The SDK uses HTTP under the hood, so there are no TCP connection issues in serverless or edge functions.
Complement Next.js Caching, Don't Replace It
Next.js has built-in fetch caching and ISR. Use Vercel KV for data that needs explicit invalidation, shared mutable state, or cross-request coordination. Do not use KV to replicate what Next.js data cache already handles for free.
Setup
Install
npm install @vercel/kv
Environment Variables
KV_REST_API_URL=https://your-kv.kv.vercel-storage.com
KV_REST_API_TOKEN=AXxxxxxxxxxxxxxxxxxxxx
KV_REST_API_READ_ONLY_TOKEN=ArXxxxxxxxxxxxxxxxxx
Key Patterns
1. Basic Key-Value Operations
Do:
import { kv } from "@vercel/kv";
interface Product {
id: string;
name: string;
price: number;
}
async function getProduct(id: string): Promise<Product | null> {
const cached = await kv.get<Product>(`product:${id}`);
if (cached) return cached;
const product = await db.products.findById(id);
if (product) await kv.set(`product:${id}`, product, { ex: 3600 });
return product;
}
Not this:
// Manual Redis client — unnecessary with Vercel KV SDK
import { Redis } from "@upstash/redis";
const redis = new Redis({
url: process.env.KV_REST_API_URL!,
token: process.env.KV_REST_API_TOKEN!,
});
2. Hash Operations for Structured Data
Do:
async function updateUserProfile(userId: string, fields: Record<string, string>) {
await kv.hset(`user:${userId}`, fields);
await kv.expire(`user:${userId}`, 86400);
}
async function getUserProfile(userId: string) {
return kv.hgetall<Record<string, string>>(`user:${userId}`);
}
Not this:
// Storing entire object as string — loses ability to update fields
await kv.set(`user:${userId}`, JSON.stringify(fields));
3. API Route with Cached Response
Do:
import { kv } from "@vercel/kv";
import { NextResponse } from "next/server";
export const runtime = "edge";
export async function GET(request: Request) {
const url = new URL(request.url);
const category = url.searchParams.get("category") ?? "all";
const cacheKey = `api:products:${category}`;
const cached = await kv.get<Product[]>(cacheKey);
if (cached) {
return NextResponse.json(cached, {
headers: { "X-Cache": "HIT" },
});
}
const products = await db.products.findByCategory(category);
await kv.set(cacheKey, products, { ex: 300 });
return NextResponse.json(products, {
headers: { "X-Cache": "MISS" },
});
}
Not this:
// No cache key strategy — same data fetched for every request
export async function GET() {
const products = await db.products.findAll();
return NextResponse.json(products);
}
Common Patterns
Session Storage for Auth
import { kv } from "@vercel/kv";
import { nanoid } from "nanoid";
async function createSession(userId: string): Promise<string> {
const sessionId = nanoid();
await kv.set(`session:${sessionId}`, { userId, createdAt: Date.now() }, { ex: 86400 });
return sessionId;
}
async function getSession(sessionId: string) {
return kv.get<{ userId: string; createdAt: number }>(`session:${sessionId}`);
}
View Counter
async function incrementViews(slug: string): Promise<number> {
return kv.incr(`views:${slug}`);
}
async function getViews(slug: string): Promise<number> {
return (await kv.get<number>(`views:${slug}`)) ?? 0;
}
Sorted Set for Trending Content
async function recordInteraction(postId: string) {
await kv.zincrby("trending:posts", 1, postId);
}
async function getTrending(count: number) {
return kv.zrange("trending:posts", 0, count - 1, { rev: true });
}
Anti-Patterns
- Using KV for data Next.js fetch cache already handles: Adds cost with no benefit
- Storing large objects (>1MB): KV is for small, fast key-value pairs
- No expiration on entries: Accumulates unused data and increases storage costs
- Reading KV on every render without caching the result in-request: Multiplies KV calls per page
When to Use
- Next.js apps on Vercel needing shared mutable state across functions
- Edge-compatible session storage with automatic expiration
- View counters, feature flags, or rate limiting in serverless
- Caching expensive API responses with explicit invalidation
- Real-time leaderboards or trending content in Next.js apps
Install this skill directly: skilldb add caching-services-skills
Related Skills
Apache Ignite
Integrate Apache Ignite, a high-performance, fault-tolerant distributed in-memory data grid. Leverage its capabilities for caching, database, and processing to achieve extreme scalability and low-latency data access in demanding web applications, making it ideal for real-time analytics, transactional systems, and compute-intensive tasks.
Cloudflare Kv
Integrate Cloudflare Workers KV for globally distributed edge key-value storage. Implement eventually consistent caching, static asset serving, and configuration management in Cloudflare Workers and Pages Functions.
Dragonfly
Integrate Dragonfly, a high-performance, in-memory data store compatible with Redis and Memcached APIs. Leverage its efficiency for caching, real-time data, and session management, reducing resource consumption and improving throughput for demanding web applications.
Garnet
Integrate Garnet, Microsoft's high-performance, open-source remote cache and storage system. Leverage its Redis-compatible API for extreme throughput and low-latency data access in demanding web applications, making it ideal for caching, session management, and real-time data needs.
Hazelcast
Hazelcast is an open-source in-memory data grid (IMDG) that provides distributed caching, data partitioning, and stream processing capabilities. It's ideal for high-performance, low-latency applications requiring scalable data storage and processing across a cluster, offering both client-server and embedded deployment options.
Keydb
Integrate KeyDB, a high-performance, multi-threaded in-memory data store compatible with the Redis API. Leverage its architecture for enhanced vertical scalability, caching, and real-time data processing in demanding web applications, making optimal use of modern multi-core CPUs.