Vercel Blob Storage: When It Makes Sense (and When It Doesn't)
Average-based billing, 15-minute sampling, and when Vercel Blob beats S3/R2—and when it doesn't.
Vercel Blob is convenient—SDK integration, CDN-backed delivery, seamless deploys. But before you migrate from S3 or R2, understand the billing model: storage is charged on 15-minute averages, not peak usage, and the decision matrix gets interesting fast.
The 15-Minute Average Billing Model
Unlike AWS S3 (billed on max monthly storage), Vercel Blob samples your storage every 15 minutes and charges on the monthly average. This creates some non-obvious billing scenarios:
// Scenario: Upload 100GB, delete after 1 hour
// Traditional S3: Charged for 100GB for the month
// Vercel Blob: 4 samples × 100GB = 400GB-samples
// Monthly average = 400 / (30 days × 24 hours × 4) = ~0.14GB
// The math works in your favor for temporary uploadsThis makes Blob excellent for transient workloads—image processing pipelines, build artifacts, temporary user uploads that get cleaned up. The 15-minute sampling means brief spikes barely register on your bill.
Where Blob Wins
- Vercel Function integration: Native SDK, no AWS credentials to manage, same deploy
- Built-in CDN: Public blobs served from edge, automatic cache invalidation
- Client uploads: Direct browser-to-Blob uploads without proxying through Functions
- Short-lived data: Temp files, processing artifacts—average billing saves money
// Client-side direct upload (no Function bandwidth cost)
import { upload } from '@vercel/blob/client';
const { url } = await upload('profile.png', file, {
access: 'public',
handleUploadUrl: '/api/upload',
});
// File goes directly to Blob, bypassing your FunctionWhere Blob Loses
Blob's pricing per GB is higher than S3 or R2. At scale, this matters:
// Storage pricing comparison (approximate, check current rates)
// Vercel Blob: $0.023/GB-month
// AWS S3: $0.023/GB-month (but often cheaper with tiers)
// Cloudflare R2: $0.015/GB-month + zero egress
// Data transfer is where it diverges:
// Vercel Blob: $0.05/GB egress (via Blob Data Transfer)
// AWS S3: $0.09/GB (first 10TB)
// Cloudflare R2: $0.00/GB egress ← The killer featureFor read-heavy workloads with high egress, R2's zero egress fees win. For write-heavy workloads where data lives briefly, Blob's average billing wins.
The Decision Matrix
// Use Vercel Blob when:
✓ Already on Vercel, want simple integration
✓ Data is transient (processing pipelines, temp uploads)
✓ Using client-side uploads (avoid Function bandwidth)
✓ Small-to-medium storage (<100GB)
✓ Public CDN delivery is primary use case
// Use S3 when:
✓ Complex IAM/bucket policies needed
✓ Need cross-region replication
✓ Already have AWS infrastructure
✓ Lifecycle policies matter
✓ Large-scale, long-term storage
// Use R2 when:
✓ Egress costs are killing you
✓ Read-heavy workloads (media, downloads)
✓ Want S3-compatible API
✓ Data lives long-termHidden Costs: Operations and CDN
Storage is just part of the bill. Operations add up:
- Simple Operations: Cache MISS reads,
head()calls - Advanced Operations:
put(),copy(),list() - Edge Requests: Every blob access counts (HIT or MISS)
- Fast Origin Transfer: Cache MISS data transfer
// Dashboard browsing counts as operations!
// Each file view in Vercel Dashboard = Advanced Operation
// Multipart uploads multiply operations:
// 1 start + N parts + 1 complete = N+2 operations
const blob = await put('large-file.mp4', file, {
multipart: true // Careful with part count
});Private vs Public: Delivery Cost Difference
Public blobs serve directly from CDN. Private blobs route through your Function:
// Public blob delivery (cheaper):
// Browser → CDN → Blob Store
// Cost: Blob Data Transfer + Fast Origin Transfer (on MISS)
// Private blob delivery (more expensive):
// Browser → Function → Blob Store → Function → Browser
// Cost: Blob Data Transfer + Fast Origin Transfer (Function→Store)
// + Fast Data Transfer + Fast Origin Transfer (Function→Browser)
// Public Blob Data Transfer is ~3x cheaper than Fast Data TransferIf you don't need authentication, prefer public blobs with signed URLs over private storage proxied through Functions.
The Cache Size Trap
Blobs >512MB don't cache at the CDN layer:
// Every access to a 600MB file:
// - Always a cache MISS
// - Always incurs Simple Operation
// - Always incurs Fast Origin Transfer
// For large files, consider:
// 1. External storage (S3/R2) with signed URLs
// 2. Splitting into smaller chunks if possible
// 3. Accepting the cost for infrequent accessWhen to Use Each
The real answer is workload-dependent:
// Profile pictures, thumbnails → Vercel Blob (public, CDN-cached)
// User-generated video → R2 (egress matters)
// Build artifacts → Vercel Blob (short-lived, average billing)
// Static assets → Vercel native (deployed with app)
// Backup archives → S3 Glacier (long-term, rarely accessed)
// Media processing temp → Vercel Blob (transient, auto-cleanup)Don't default to Blob because it's convenient. Model your actual workload against the pricing calculators. Sometimes the SDK convenience is worth the premium; often it isn't.
Advertisement
Explore these curated resources to deepen your understanding
Official Documentation
Tools & Utilities
Related Insights
Explore related edge cases and patterns
Advertisement