Vercel Blob's SDK is genuinely good. `put()` a file, get back a URL. `list()`, `head()`, `del()`, all typed, all boring in the way infrastructure should be boring. That's worth saying plainly before picking it apart, because the usual reaction to leaving Vercel is to abandon the whole shape of that API along with the platform, drop straight into raw AWS SDK calls, and rebuild something clumsier than what was replaced. The API shape is worth keeping. Only the meter underneath it needs to change. `del()` being free, for what it's worth, is a genuinely nice detail worth noticing before you assume every operation on a managed store costs something.
What does Vercel Blob actually bill you for?
Five separate things, not one. Storage is the obvious one — a monthly average of your blob store's size, past a small included allowance. Simple Operations count every blob accessed by its own URL that results in a cache miss, plus every `head()` call. Advanced Operations count `put()`, `copy()`, and `list()` calls, and a multipart upload counts as several of these at once: one for starting, one per part, one for completing. Blob Data Transfer bills for the bytes actually downloaded. And Fast Origin Transfer bills separately, on cache misses, for pulling the blob from storage to the edge in the first place. Pair this with XenGrowth's growth engineering practice if Vercel blob alternatives for self-hosted apps sits inside a wider growth programme.
Meter | What it counts | Rate beyond included allowance |
|---|---|---|
Storage | Monthly average blob store size | $0.023/GB (5 GB included) |
Simple Operations | URL access on cache miss, plus head() | $0.40 per million (100K included) |
Advanced Operations | put(), copy(), list() — multipart counts each part | $5.00 per million (10K included) |
Blob Data Transfer | Bytes actually downloaded | $0.05/GB (100 GB included) |
Fast Origin Transfer | Store-to-edge fetch on cache miss | $0.06/GB (100 GB included) |
Vercel's own documentation walks through a worked example that's worth quoting directly because it shows how these meters compound: 50 GB of average storage, 2.5 million downloads at a 70% cache hit rate, and 120,000 uploads with some multipart activity comes out to $15.73 for that month. None of the individual line items look alarming — it's the five of them stacking that adds up, and it's exactly the kind of bill that's hard to predict from usage alone, because nobody's tracking cache hit rate as a cost variable until the invoice explains why it should have been.
Does it matter whether the upload goes through your server?
On Vercel Blob, yes, directly. Uploads made with Client Uploads — the browser talking straight to Blob storage — don't incur data transfer charges at all. Uploads routed through a Server Upload, where your own function receives the file first, do incur Fast Data Transfer charges for that hop. There's a second, less obvious distinction buried in the same documentation: private blob delivery (your function fetches the file, then streams it to the browser) pays both Blob Data Transfer and Fast Data Transfer, while public blob delivery (the browser fetches the file directly) only pays the first — and Vercel's own docs state Blob Data Transfer runs roughly three times more cost-efficient than Fast Data Transfer on average. None of this is a reason to avoid private storage when you need it; it's a reason to know which of these four paths a given file is taking before you're surprised by which meter it hit.
Option one: Cloudflare R2
R2 replaces the storage and transfer side of this directly, and it does it by deleting one of the five meters outright: there is no egress charge, at any volume. Standard storage runs $0.015/GB-month, undercutting Vercel Blob's $0.023 even before the transfer meters are counted. The operations pricing is genuinely comparable in structure — Class A (write-like) operations and Class B (read-like) operations, priced per million, mirroring Vercel's split between advanced and simple operations — so the mental model barely changes even though the exact numbers do. There is a longer treatment of the operations side of this in The XenGrowth resource library.
The migration itself is mostly mechanical: swap the Vercel Blob SDK calls for the AWS SDK pointed at R2's S3-compatible endpoint, replace `put()`'s return value with a presigned PUT URL your own code generates, and keep the rest of your upload flow intact. The part worth budgeting real time for isn't the API surface, it's re-testing every place in your app that assumed a Vercel Blob URL shape — image components, download links, anything that parsed or displayed the URL directly instead of treating it as an opaque string.
Option two: Amazon S3
S3 is the right answer specifically when the rest of your stack is already AWS — Lambda, CloudFront, IAM roles already wired up, and egress you can predict because you already run infrastructure at that scale. Storage runs $0.023/GB-month for the first 50 TB, and the tradeoff versus R2 is explicit: you get the broadest ecosystem integration in exchange for an actual egress bill, $0.09/GB beyond the first 100 GB each month. For a small self-hosted app with no other AWS dependency, that trade rarely pays for itself; for a team already inside AWS's blast radius, it usually does, if only because avoiding one more vendor relationship is worth something on its own.
Option three: self-hosted MinIO
MinIO removes the vendor bill entirely — no per-GB storage charge, no per-operation charge, nothing metered by a third party. What it doesn't remove is bandwidth: egress from a self-hosted bucket rides on whatever traffic allowance your VPS provider already sells you, throttled or overage-billed by that host, not itemized anywhere on a storage invoice. It's also worth knowing before adopting it now rather than after: MinIO's GitHub repository was archived in April 2026 with a "no longer maintained" notice, and the community edition currently ships as source code only, with no precompiled binaries. "Free and self-hosted" is still true; "actively maintained and easy to install" is a separate question you should answer for yourself before betting production uploads on it. On AI agents and marketing automation specifically, XenGrowth on governed AI marketing workflows is worth reading.
Option four: Postgres large objects, for the small cases
This one only belongs on the list for a narrow case, and it's worth naming so nobody reaches for it outside that case: small blobs, genuinely small, that a database you're already backing up can absorb without changing its own operational story — a user's avatar, a small generated PDF, a config blob. Postgres can store this as `bytea` directly in a row or via its large object facility, and the appeal is that it rides along with your existing database backups instead of needing a separate storage system at all. It stops being a good idea the moment file sizes grow past a few megabytes or upload volume grows past what a database row was ever meant to carry — at that point it's competing with your actual application data for the same disk and the same backup window, which is precisely the problem keeping uploads off your app server is meant to avoid in the first place.
There's a mechanical reason the size ceiling is real, not just a rule of thumb: Postgres stores oversized column values using TOAST, transparently compressing and splitting them into chunks behind the scenes so a table storing large `bytea` values doesn't grind to a halt. That mechanism works, but it means a growing blob table is quietly growing your main database's storage and vacuum workload right alongside your actual application rows, whether or not anyone's watching that table specifically. It's a fine trade for a handful of small files. It's the wrong trade for anything that looks like general file storage, which is exactly why this option stays fourth on the list rather than first.
Do rate limits change once you leave Vercel Blob?
Vercel Blob itself isn't unlimited, which is worth knowing before assuming any alternative needs to match some infinite bar. Its own operation rate limits scale by plan — Hobby is capped at 1,200 simple operations and 900 advanced operations per minute, Pro at 7,200 and 4,500, Enterprise at 9,000 and 7,500. A batch job that deletes a hundred files in one call counts as a hundred operations against that limit, not one — the unit being metered is the operation, not the request that triggered it, and that distinction is exactly the kind of detail a migration checklist skips if nobody reads the fine print first. Whichever alternative you move to will have its own version of this ceiling — R2 and S3 both rate-limit at the API level too — so the honest migration checklist includes checking your actual peak operation rate against the new provider's limits, not just assuming a bigger-sounding vendor has no ceiling at all. For the AI search, GEO and discovery angle, see XenGrowth on building one SEO and GEO content system.
Option | Egress model | Best fit | Watch out for |
|---|---|---|---|
Cloudflare R2 | Free at any volume | Most self-hosted apps replacing Vercel Blob | Slightly different operations pricing shape — re-check your own usage pattern |
Amazon S3 | Billed past 100 GB/mo free | Teams already committed to AWS | Egress is the one line item that can genuinely surprise you at scale |
Self-hosted MinIO | Rides your VPS's own bandwidth allowance | Low-traffic, genuinely private storage on hardware you control | Archived upstream repo, source-only builds going forward |
Postgres large objects / bytea | Whatever your DB connection already costs | Small blobs only, already inside your backup plan | Stops making sense past a few MB or meaningful upload volume |
What actually changes in your upload code?
Less than switching storage vendors usually implies. Vercel Blob's client-upload feature — letting the browser upload directly to Blob storage without the request passing through your server — is the same presigned URL pattern every one of these alternatives already supports through its own S3-compatible API. Your server-side code that issues the upload permission is the part that changes; the flow the browser follows barely does. The bigger question every one of these options forces is whether uploads should stay public or move behind private, authenticated access — a decision Vercel Blob makes per-store, and one worth revisiting deliberately during a migration rather than carrying over by default just because that's how it worked before.
Vercel Blob was never the hard part to replace. The hard part was always going to be re-testing every place your app quietly assumed a specific URL shape, a specific cache behavior, or a specific upload path — and that work exists regardless of which storage backend replaces it.
Audit which of your uploads currently go through Client Uploads versus Server Uploads before migrating — that distinction changes which meter matters most on the new backend too
Decide public versus private access per bucket deliberately, rather than defaulting to whatever Vercel Blob happened to default to
Re-check any code that parses or constructs blob URLs directly instead of treating them as opaque strings — this is where migrations actually break, not in the SDK calls
For most apps leaving Vercel, R2 is the closest thing to a drop-in replacement for Blob's cost model — same rough storage price, no egress meter to worry about as traffic grows. S3 earns its place inside an existing AWS footprint. MinIO earns its place on hardware you already run, with eyes open about its current maintenance status. And Postgres large objects earn their place exactly once, for the small blobs that were never going to justify a separate storage system regardless of which one you picked. None of them ask you to give up the part of Vercel Blob actually worth keeping — a small, typed wrapper around presigned URLs is easy enough to rebuild against any of the four that there's no reason to fall back to raw, unwrapped SDK calls just because the managed version is gone.
Further reading from XenGrowth
The XenGrowth resource library — what you'll learn: how the commercial side of this work is run, across search, automation and revenue operations.
XenGrowth on governed AI marketing workflows — what you'll learn: how the teams running AI marketing agents keep them governed and measurable.
XenGrowth on building one SEO and GEO content system — what you'll learn: how search and AI-answer visibility get run as a single content system.
Where this work meets go-to-market
If Vercel blob alternatives for self-hosted apps is part of a growth programme rather than a standalone build, XenGrowth's operator guides is the companion reading.
Four questions about your objects rather than your preferences. The answer is usually S3-compatible storage; which one depends on how the bytes leave again.











