Vercel storage and data
Vercel’s storage story in 2026 is bifurcated. Vercel directly offers two products: Vercel Blob (large-file storage, S3-compatible-ish) and Edge Config (globally-replicated read-optimized config). For everything else — relational DBs, key-value stores, NoSQL, vector DBs — Vercel partners through the Marketplace, which provisions third-party services (Neon, Upstash, Supabase, MongoDB Atlas, Redis Cloud) with native dashboard integration and automatic environment-variable injection. The Vercel-native KV and Postgres products that existed pre-2024 have been retired in favor of Marketplace partners (Upstash for KV, Neon for Postgres).
See also
- vercel-edge-network-and-functions — where storage clients run (Functions + Middleware)
- vercel-platform-and-deployments — environment variable injection for Marketplace resources
- databases-internals-deep — engine-level deep dives on the providers behind Marketplace
1. Vercel Blob — large file storage
Per vercel.com/docs/vercel-blob. Object storage for user-uploaded files, AI-generated assets, video, audio, large JSON exports. Built on top of Cloudflare R2 internally (per Vercel engineering posts) — same zero-egress model.
1.1 Basic usage
import { put, list, del, head } from "@vercel/blob";
// Upload (server-side or signed-URL client upload)
const { url, downloadUrl } = await put("avatars/user-7281.jpg", file, {
access: "public", // or "private"
contentType: "image/jpeg",
cacheControlMaxAge: 31536000,
});
// List
const { blobs, hasMore, cursor } = await list({
prefix: "avatars/",
limit: 1000,
});
// Read metadata
const meta = await head(url);
// Delete
await del(url);1.2 Client uploads (avoid Function 4.5MB limit)
Vercel Functions have a 4.5 MB request body limit, so large file uploads must go directly from the browser to Blob storage. Pattern:
// app/api/upload/route.ts (issues a signed token)
import { handleUpload } from "@vercel/blob/client";
export async function POST(req: Request) {
const body = await req.json();
return handleUpload({
body,
request: req,
onBeforeGenerateToken: async (pathname) => {
// Auth check, file type validation
return {
allowedContentTypes: ["image/*", "video/mp4"],
maximumSizeInBytes: 100 * 1024 * 1024,
tokenPayload: JSON.stringify({ userId: await getUserId(req) }),
};
},
onUploadCompleted: async ({ blob }) => {
// Webhook fires after browser → Blob completes
await db.assets.create({ url: blob.url, ... });
},
});
}Client side:
import { upload } from "@vercel/blob/client";
const blob = await upload(file.name, file, {
access: "public",
handleUploadUrl: "/api/upload",
});1.3 Multipart uploads
For files > 100 MB:
import { createMultipartUpload, uploadPart, completeMultipartUpload } from "@vercel/blob";
const upload = await createMultipartUpload("large.mp4", { access: "public" });
const partETags = await Promise.all(
parts.map((part, i) => uploadPart(upload.uploadId, upload.key, i + 1, part))
);
await completeMultipartUpload(upload.uploadId, upload.key, partETags);1.4 Limits and pricing
Per vercel.com/docs/storage/vercel-blob/usage-and-pricing:
| Tier | Storage | Operations | Data transfer |
|---|---|---|---|
| Hobby | 1 GB | Limited | 1 GB / month |
| Pro | 100 GB included | Generous | 1 TB included |
| Pro overage | $0.023 / GB / month | $0.0004 / operation | $0.04 / GB |
Max blob size: 5 GB. Max blobs per store: unlimited. SLA: 99.9% (Pro), 99.99% (Enterprise).
2. Edge Config — global low-latency reads
Per vercel.com/docs/edge-config. A globally-replicated key-value store designed for reads — < 1ms median latency anywhere in the world. Writes are slow by design (propagation takes seconds across all POPs).
2.1 Use cases
- Feature flags —
featureFlag = await get("new-checkout-enabled")in middleware. - A/B test config — variant rules, traffic splits.
- Redirects — table of
from → toURLs (when too dynamic forvercel.json). - Allowlists / blocklists — IP CIDR, user-agent patterns.
- Maintenance mode toggles — flip without redeploying.
- Per-tenant config — small JSON per customer subdomain.
2.2 Reading
import { get, getAll, has } from "@vercel/edge-config";
const flag = await get<boolean>("new-checkout-enabled");
const config = await getAll(); // returns full store as object
const exists = await has("feature-x");Inside middleware:
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
import { get } from "@vercel/edge-config";
export async function middleware(req: NextRequest) {
const maintenance = await get<boolean>("maintenance-mode");
if (maintenance && !req.nextUrl.pathname.startsWith("/maintenance")) {
return NextResponse.redirect(new URL("/maintenance", req.url));
}
return NextResponse.next();
}2.3 Writing
Writes are via the dashboard, API, or REST:
curl -X PATCH "https://api.vercel.com/v1/edge-config/${ID}/items" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "operation": "upsert", "key": "new-checkout-enabled", "value": true }
]
}'Or programmatically:
import { createClient } from "@vercel/edge-config";
const client = createClient(process.env.EDGE_CONFIG);
// (Read-only from client lib; for writes use REST API)2.4 Limits
Per vercel.com/docs/edge-config/edge-config-limits:
| Limit | Value |
|---|---|
| Total store size | 8 KB (Hobby), 512 KB (Pro), 1 MB (Enterprise) |
| Max keys | 1024 |
| Max value size per key | 8 KB |
| Read latency (P50) | < 1 ms |
| Read latency (P99) | < 10 ms |
| Write propagation time | ~10 seconds globally |
| Reads / month included | 1M (Hobby), unlimited (Pro/Ent) |
The 512 KB cap is real — Edge Config is not a database. Use it for config that changes < 100×/day and reads > 1000×/sec.
2.5 Stale-while-revalidate behavior
Edge Config has a small in-instance cache (~30 sec TTL inside a function instance). For ultra-stable reads, write your own additional in-memory cache:
let cached: FeatureFlags | undefined;
let cachedAt = 0;
async function getFlags() {
if (cached && Date.now() - cachedAt < 60000) return cached;
cached = await getAll();
cachedAt = Date.now();
return cached;
}3. Marketplace storage — third-party native integrations
Per vercel.com/docs/marketplace-storage. Vercel’s Marketplace provisions third-party storage with:
- Native dashboard UI — provisions, scales, deletes the resource from Vercel’s UI.
- Auto-injected env vars — connection strings appear as env vars in your project automatically.
- Single billing — charges appear on your Vercel invoice (mark-up of 0-20% depending on provider).
- Native integrations — pgbouncer for Postgres, Hyperdrive-style query pooling for Cloudflare-hosted DBs.
3.1 The current Marketplace catalog
| Category | Default partner | Alternatives |
|---|---|---|
| Postgres | Neon (serverless) | Supabase, Crunchy Bridge, Tembo |
| Redis / KV | Upstash | Redis Cloud |
| MongoDB / NoSQL | MongoDB Atlas | — |
| Vector | Upstash Vector | Pinecone, Turbopuffer |
| Search | Algolia | Elastic Cloud, Typesense |
| Other | Convex (TypeScript backend), Firebase | — |
3.2 Provisioning a Postgres (Neon)
# Via CLI
vercel install neon
# Or via Marketplace UI: Storage → Marketplace → Neon → CreateAfter provisioning, Vercel injects env vars:
DATABASE_URL(pooled connection — pgbouncer)DATABASE_URL_UNPOOLED(direct connection — for migrations)POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_HOST,POSTGRES_DATABASE
Use with any Postgres library:
import { Pool } from "@neondatabase/serverless";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const result = await pool.query("SELECT * FROM users WHERE id = $1", [id]);Or with Prisma:
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DATABASE_URL_UNPOOLED")
}3.3 Provisioning Redis (Upstash)
vercel install upstashEnv vars injected:
UPSTASH_REDIS_REST_URLUPSTASH_REDIS_REST_TOKENKV_URL(Redis URI for ioredis-style clients)KV_REST_API_URL/KV_REST_API_TOKEN(HTTP API)
import { Redis } from "@upstash/redis";
const redis = Redis.fromEnv();
await redis.set("foo", "bar");
const value = await redis.get("foo");Upstash Redis is the recommended replacement for the retired Vercel KV — same API surface (the @vercel/kv package now wraps @upstash/redis).
3.4 Pricing — Marketplace markup
Vercel’s Marketplace charges the partner’s published rates with no markup for most products, billed through your Vercel invoice. Some products have a small platform fee. Always check the partner’s pricing page to confirm.
Examples (2026-05-25, base plans):
- Neon Postgres: free tier (10 GB storage, scales to zero) → $19/mo Launch → custom for Scale.
- Upstash Redis: pay-per-request ($0.20 / 100k commands) → fixed plans from $10/mo.
- MongoDB Atlas: M0 free → M10 $57/mo → up.
4. Choosing between Vercel-native and Marketplace
| If you need… | Use |
|---|---|
| Large files (images, video, exports) | Vercel Blob |
| Feature flags / config | Edge Config |
| Relational DB (Postgres) | Marketplace: Neon |
| Key-value cache (Redis) | Marketplace: Upstash |
| Document DB | Marketplace: MongoDB Atlas or Firestore |
| Vector DB | Marketplace: Pinecone / Upstash Vector / Turbopuffer |
| Full-text search | Marketplace: Algolia / Typesense |
| TypeScript-native backend with realtime | Marketplace: Convex |
5. Local development
Per vercel.com/docs/storage. Most Marketplace integrations work the same locally as in production — pull env vars with vercel env pull and use them with the same client lib:
vercel env pull # writes .env.local with all production env varsFor Blob, the SDK works against the production Blob store from your dev machine using the production token. For test isolation, create a separate “preview” Blob store.
For Edge Config, the same applies — reads from dev hit the production store. Use a separate dev Edge Config if you want isolation.
6. Multi-region considerations
- Vercel Blob — origin is single-region (typically
iad1); reads served from POPs. Geographic latency on first read of a never-cached blob can be 100-300ms. - Edge Config — globally replicated; reads are always local-POP, < 1 ms.
- Marketplace Postgres (Neon) — your DB lives in one region. Functions running in
iad1reading from a Neon DB insin1will pay ~200ms per query. Always co-locate. - Marketplace Redis (Upstash) — multi-region option available, replicates writes across regions. Best for global apps.
For globally distributed apps with strict latency budgets, the standard architecture is:
- Edge Config for read-mostly small config (< 512 KB).
- Upstash Redis multi-region for hot cache.
- Neon Postgres single-region (where most of your read traffic comes from) for source of truth.
- Vercel Blob for binaries.
7. Transferring stores between accounts
Per vercel.com/docs/storage#transferring-your-store. Blob and Edge Config stores can be transferred between Vercel teams/accounts (upgrade Hobby → Pro, or move between team accounts). The transfer is atomic — URLs continue working.
Marketplace resources transfer separately — from the resource’s Settings page.
8. Security and access
- Vercel Blob —
access: "public"makes URLs publicly readable;access: "private"requires a signed URL token. Tokens are scoped per-blob with TTL. - Edge Config — read tokens are deployment-scoped (env var). Write requires API token from dashboard with team permissions.
- Marketplace resources — credentials are managed by the partner. Vercel injects them as env vars; rotation is partner-side.
9. Quotas and limits at a glance
| Product | Hobby | Pro |
|---|---|---|
| Blob storage | 1 GB | 100 GB included |
| Blob data transfer | 1 GB / mo | 1 TB included |
| Edge Config size | 8 KB | 512 KB |
| Edge Config reads | 1M / mo | Unlimited |
| Marketplace | Partner-dependent | Partner-dependent |