New:Upstash has a remote MCP server
·9 min read

Backblaze B2 Pricing Explained (October 2026): Storage, Egress and API Costs vs. Upstash Blob

JoshJoshDevRel @Upstash
https://upstash.com/blog/backblaze-b2-pricing-explained-2026

You probably know that Backblaze’s B2 service is billed at $6.95 per Terabyte (TB) per month. You probably also know that there’s no charge for uploads or the majority of API calls. So if you’re using B2 for backups or archives where things generally sit in a bucket, that $6.95 TB/month is pretty much what you’ll pay.

If you’re using B2 to build applications that serve files to users, though, there’s another number you should know: B2 includes free downloads of up to three times your data storage amount, but each Gigabyte (GB) after that costs $0.01.

So if you’ve got a 20 GB bucket of images, you can serve 60 GB of downloads for free, but if users download 500 GB of images in a month, you’ll be billed for the other 440 GB.

With Upstash Blob, you get 1 TB of free downloads each month, regardless of your storage amount. For the example image app above, it would cost $1.38/month on Upstash Blob instead of $4.47/month on Backblaze B2.

How much does Backblaze B2 cost?

Backblaze B2 pricing is $6.95 per TB per month ($0.00695 per GB per month) on a pay-as-you-go model. You get the first 10 GB for free. Downloading is free up to 3x the average data stored, then $0.01 per GB.

So for example:

ItemPrice
Storage$6.95 per TB per month ($0.00695 per GB), billed by the byte-hour
Free storageFirst 10 GB
UploadsFree
Downloads (egress)Free up to 3x your average monthly storage, then $0.01 per GB
Downloads to partner CDNsFree (Cloudflare, Fastly, bunny.net and others)
Class A, B and C API callsFree
Class D callsFirst 2,500 a day free, then $0.004 per 10,000
Minimum file size or storage timeNone
B2 OverdriveFrom $15 per TB per month with free downloads, for multi-petabyte commitments

Class A, B and C transactions include pretty much everything an application does - uploading, downloading, copying, listing and deleting objects, while Class D transactions only cover outbound event notifications.

You select a region - US West, US East, EU Central or CA East - when you create a Backblaze B2 account. Although Backblaze B2 pricing is identical across all four regions, you can’t move an account from one region to another; if you want to store data in a different region, you must create a new account in that region.

How the 3x free egress works

For B2, multiply your average storage during the billing month, in byte-hours, by three. That is your free download allowance for the month. Each additional GB is $0.01.

Take a 50 GB bucket that users download 1 TB (1,000 GB) from in a month:

Free downloads:  3 x 50 GB         = 150 GB
Paid downloads:  1,000 - 150 GB    = 850 GB x $0.01    = $8.50
Storage:         50 - 10 free GB   = 40 GB x $0.00695  = $0.28
Total                                                  = $8.78

Downloads are $8.50 of $8.78 - that's 97% of the total bill. This shows that the advertised price of $6.95/TB is mostly irrelevant to determining price here; the deciding factor is the download frequency of individual files.

B2 vs Upstash Blob for files your users download

Profile pictures, product images, PDFs and exports are written once but read many times. This means that they can exceed the 3x allowance on B2.

On Upstash Blob, the download allowance is not tied to the amount you have stored: you get 1 TB of free downloads every month on the pay-as-you-go plan.

The two rate sheets side by side:

Backblaze B2Upstash Blob
Storage$0.00695 per GB (first 10 GB free)$0.02 per GB
Free downloads3x what you store1 TB a month
Downloads after that$0.01 per GB$0.02 per GB
ReadsFree$0.30 per million
Uploads, copies, listsFree$4.50 per million
DeletesFreeFree
CDNBring your ownGlobal CDN included
RegionsOne per accountGlobal, no region to pick

A little helper script I made:

type Month = {
  storedGB: number
  downloadedGB: number
  reads: number
  uploads: number
}
 
// Backblaze B2 pay-as-you-go
function b2(m: Month) {
  const storage = Math.max(m.storedGB - 10, 0) * 0.00695
  const egress = Math.max(m.downloadedGB - 3 * m.storedGB, 0) * 0.01
  return storage + egress
}
 
// Upstash Blob pay-as-you-go
function upstashBlob(m: Month) {
  const storage = m.storedGB * 0.02
  const egress = Math.max(m.downloadedGB - 1000, 0) * 0.02
  const ops = (m.reads / 1e6) * 0.3 + (m.uploads / 1e6) * 4.5
  return storage + egress + ops
}
 
const workloads: Record<string, Month> = {
  images: { storedGB: 20, downloadedGB: 500, reads: 2_500_000, uploads: 50_000 },
  pdfs: { storedGB: 100, downloadedGB: 1000, reads: 500_000, uploads: 20_000 },
}
 
for (const [name, m] of Object.entries(workloads)) {
  console.log(
    name.padEnd(8),
    `B2 $${b2(m).toFixed(2)}`.padEnd(12),
    `Upstash Blob $${upstashBlob(m).toFixed(2)}`,
  )
}
images   B2 $4.47     Upstash Blob $1.38
pdfs     B2 $7.63     Upstash Blob $2.24

Our (example) image app stores 20 GB of ~200 KB images. Users access them 2.5 million times a month (500 GB downloaded) and upload 50 thousand new images.

The PDF app stores 100 GB of 2 MB files. Users access them 500 thousand times a month (1 TB downloaded).

Cost for an app that stores 100GB and has 1TB of egress

Free downloads through Cloudflare take extra setup

B2 does not charge for downloads that go through partner CDNs like Cloudflare, Fastly, or bunny.net. To take advantage of this, your users must download the files through the CDN using your own domain name. If your bucket is public and you’re using Cloudflare, this requires several steps:

  1. Make the bucket public. Your first public bucket requires you to verify your email and have a billing history or pay a small fee by card.
  2. Add your domain to Cloudflare and switch to its nameservers.
  3. Add a proxied CNAME record that points a subdomain (e.g. photos.yoursite.com) to your bucket’s B2 host.
  4. Add a URL rewrite rule that adds /file/your-bucket to every request path.
  5. Set the SSL configuration to ‘Full (Strict)’ and configure cache rules (Cloudflare only caches certain types of files by default).

An easy mistake to make, and one with serious security implications, is to forget step 4. Your CNAME points to a B2 host that is shared with other customers, each with their own public buckets. Without the rewrite rule, anyone can use your domain name to access files from other customers’ public buckets on the same host.

The process is even more complex for private files. Cloudflare must sign every request it makes to your private bucket, so you must write and deploy a Cloudflare Worker that includes a B2 application key. Cloudflare does not cache signed requests by default, so you must also add a Cache-Control directive to the bucket's info in B2.

None of this is necessary with Upstash Blob. Every file is replicated to a global CDN, and a public bucket is accessible through its own URL. Reads from a private bucket can be served with time-limited signed URLs, which the SDK creates for you.

Uploading from the browser

You can upload files from the browser directly to storage to keep large uploads off your server. Both Blob and B2 support this, but there is a big difference in how much code you need to write.

On B2, you use the S3-compatible API. Your server signs a URL with the AWS SDK, and the browser uploads the file with a PUT request. (B2 does not support browser uploads with a presigned POST.) You must configure CORS rules on your bucket to allow your site.

Showing upload progress, retrying uploads, and breaking large files into parts are all up to you.

Upstash Blob's SDK has an upload handler for your server and React hooks for the browser. The handler decides who can upload, where each file goes, and which sizes and types are allowed:

import "server-only"
import { uploadHandler } from "@upstash/blob"
 
export const uploads = uploadHandler({
  constraints: {
    maxSize: "20mb",
    contentTypes: ["image/*", "application/pdf"],
  },
  onBeforeUpload: ({ file }) => ({ path: `images/${file.name}` }),
})

The browser uploads directly to Blob.

By using the useUpload hook, you get the following for free:

  • Multipart uploads > 16 MB with pause/resume and per part retries
  • File selector that blocks if file size is too big before initiating any request
  • Consistent upload progress updates (whether single PUT request or 200 parts)
  • Typings from the server handler to the client

Which one to pick

B2 is designed for data that sits there. It’s for backups and archives that you write once and rarely read. The cost of storage is low, and the 3x free allowance lets you restore from that backup if you need to.

Upstash Blob is designed for files that your app needs to serve. For images and avatars, PDFs and exports, the terabyte free allowance covers the downloads that B2 charges you for, while the CDN, signed URLs, and browser uploads are included with your bucket.

You can create a bucket in the console, then use the quickstart to upload your first file.

If you’d like to see more price examples, check out AWS S3 pricing explained, or our comparison of object storage for SaaS applications.