EdgeCases Logo
Mar 2026
Next.js
Surface
6 min read

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-storage
s3
r2
cloud-storage
pricing
infrastructure

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 uploads

This 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 Function

Where 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 feature

For 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-term

Hidden 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 Transfer

If 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 access

When 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

Related Insights

Explore related edge cases and patterns

Next.js
Deep
Neon on Vercel: The Connection Pooling Maze
7 min
Next.js
Expert
Vercel Billing Demystified: Edge Requests, Function Duration, and ISR Costs
8 min
Next.js
Surface
ISR Build Time Reduction: From Minutes to Seconds
6 min

Advertisement