Next.js Edge Config Tutorial: Ultra-Low-Latency Reads
Use Vercel Edge Config to serve feature flags, redirects, and small config blobs from the edge with single-digit-millisecond reads — when to use it, how it differs from KV, and a working example.
What you'll learn
- ✓What Edge Config is and what it is not
- ✓How reads achieve single-digit-millisecond latency
- ✓How to use it from middleware and route handlers
- ✓When to choose Edge Config over KV or a database
Prerequisites
- •A Next.js project deployed to Vercel
What and Why
Vercel Edge Config is a read-optimized, globally replicated key-value store designed for tiny config blobs you read on every request — feature flags, A/B test buckets, allow/deny lists, redirect maps. It is not a database. Writes are slow and rate-limited; reads are nearly free and sit right next to your edge functions.
The point is to remove the cold-start network hop. If middleware needs to decide “is this user in the beta?” before rendering anything, a normal database query adds 30–100 ms to every request. Edge Config makes that decision in 1–2 ms because the data is colocated with the function.
Mental Model
An Edge Config is essentially a JSON document that Vercel embeds into every edge region. When you read a key, your function does not call a remote store — it consults a local copy. Writes happen through the Vercel API or dashboard and propagate to all regions within seconds. The trade-off is shape: total size is capped (around 512 KB), and you cannot do queries, only key lookups.
Think of it as process.env that you can update without redeploying.
Hands-on Example
Create an Edge Config in the Vercel dashboard (Storage tab) and add some keys:
{
"betaUsers": ["user_123", "user_456"],
"maintenanceMode": false,
"redirects": { "/old-pricing": "/pricing" }
}
Connect it to your project — Vercel sets the EDGE_CONFIG env var automatically. Install the client:
npm install @vercel/edge-config
Now use it from middleware, which runs on the edge before every request:
// middleware.ts
import { NextResponse } from 'next/server';
import { get } from '@vercel/edge-config';
export const config = { matcher: '/((?!_next|favicon).*)' };
export async function middleware(req) {
const maintenance = await get('maintenanceMode');
if (maintenance) {
return NextResponse.rewrite(new URL('/maintenance', req.url));
}
const redirects = (await get('redirects')) ?? {};
const target = redirects[req.nextUrl.pathname];
if (target) {
return NextResponse.redirect(new URL(target, req.url));
}
return NextResponse.next();
}
You just added a kill switch and a dynamic redirect map without deploying.
Edge Config (colocated):
request -> edge function -> local replica (~1ms) -> response
[no network hop]
Remote KV / DB:
request -> edge function -> network -> regional KV (~30-100ms) -> response
Write path (Edge Config):
dashboard / API -> control plane -> propagate to all regions (~seconds) For non-middleware code (route handlers, server components), the same get('key') call works. Reads are still fast because the runtime caches the local copy.
Common Pitfalls
The first mistake is treating Edge Config as a general database. Writes are eventually consistent across regions, rate-limited, and slow relative to reads. Storing per-user state (sessions, carts) here will both blow the size cap and miss the propagation window.
Second, forgetting it is read-only from your code. There is no set() from inside a function. You write via the Vercel REST API or the dashboard. If your feature needs server-side writes, you need KV or a real database.
Third, size creep. The store is small. Dumping a 200 KB JSON of redirects works at first; add a few more entries and you hit the limit. Keep payloads compact and prefer external storage for large data.
Fourth, stale-during-deploy. A new deploy may briefly see the previous Edge Config version until propagation completes. Do not couple a code rollout to an Edge Config update for the same release — write the config first, deploy second.
Best Practices
Use Edge Config for things every request reads and almost nothing writes — feature flags, allowlists, redirect tables, maintenance switches, A/B variant rosters. Keep the JSON small and version your key names (flags.v2.checkoutRedesign) so old code keeps working during transitions. Wrap reads in a thin helper with a typed schema (Zod or similar) so a bad write does not crash production. For local development, mock the values via the EDGE_CONFIG URL or a small fallback object. Finally, treat the dashboard like a deploy: review who can write and audit changes.
Wrap-up
Edge Config is a small, focused tool: globally replicated, read-cheap, write-slow. Used for the right job — flags, redirects, kill switches — it removes a network hop from your hot path and lets you change behavior without shipping code. Used as a database, it will frustrate you. Pick the right tool and it disappears into the background.
Related articles
- Next.js Next.js Middleware and the Edge Runtime
What Next.js middleware actually is, how it runs on the Edge, what you can and cannot do there, and the patterns that work in production.
- Next.js Error Boundaries in the Next.js App Router
How error.tsx, global-error.tsx, and not-found.tsx work in the Next.js App Router — when each one fires, how segments isolate failures, and patterns for recovery and observability.
- Next.js Deploying Next.js on Vercel: A Practical Guide
A hands-on walkthrough for shipping a Next.js app to Vercel — connecting Git, configuring environment variables, understanding preview deployments, and avoiding the usual production gotchas.
- Next.js Next.js Server Actions: A Form Actions Deep Dive
How Next.js Server Actions replace API routes for form submissions — progressive enhancement, useFormState and useFormStatus, validation, revalidation, and avoiding the most common mistakes.