← All case studies Amazon S3 → Backblaze B2

CloudSpot moved 700TB and 120 million images off S3

Gavin Wade copied CloudSpot's galleries from Amazon S3 to Backblaze B2 with Flexify.IO. The public write-up is a vendor case study. New uploads stayed on S3 until a one-day catch-up.

CloudSpot is a photographer gallery platform from Irvine, California. Founder Gavin Wade started it in 2014 because wedding delivery felt like a Dropbox link after a several-thousand-dollar shoot.

The public write-up is a Backblaze customer story, so it is a vendor page. I could not find a matching post on CloudSpot’s own blog. This case study stays with what Gavin said there, plus the official docs that match the steps.

They moved about 700TB and more than 120 million files from Amazon S3 to Backblaze B2. Backblaze says the copy took six days and that customers did not see an outage.

If you are looking at the same route, start with the Amazon S3 → Backblaze B2 playbook. Backblaze’s upload and migrate page is the generic menu. CloudSpot’s version used Flexify.IO so the bytes never crossed the office network.

Why they left S3

S3 was the default when CloudSpot was a startup. Gavin said they treated it like every other fire. If the handle was not too hot, they left it.

Around 2018 the storage bill started to get in the way. The team first rebuilt the upload path. Images used to pass through a chain of checkpoints (metadata, analysis) before they landed in S3. One failure stopped the whole pipeline. They moved to Kubernetes and uploaded straight to S3. Microservices then queried the object after it was already stored.

The rebuild made each service survive on its own. The storage bill kept climbing.

A year later customers were uploading close to one million images a week. After a busy fall 2019 season, volume was five times the prior year. Forecasts for the next year made the S3 line look like a product constraint. They had already talked themselves into being stuck with Amazon.

Gavin had found Backblaze earlier and put the move off because the copy looked too big. The forecast is what sent him back. On the vendor page he says B2 would cut storage cost a lot and slow how fast that cost compounded.

Backblaze’s summary also lists a 50% cut in broader operating cost and a 90% cut in transfer cost. Those are the vendor’s headline numbers. Gavin’s own quote later in the same page is the monthly range I am using below.

How they moved

Galleries were the product, and one of them opened every one or two seconds, so the copy had to stay live.

Flexify.IO ran the transfer on cloud links instead of CloudSpot’s office bandwidth. Flexify’s own site describes that as cloud-native copy with no downtime, plus engines that sit in the same cloud and region as the source so you are not paying yourself to pull the data home.

Backblaze’s current Flexify guide is the self-serve path: add S3 credentials, add a B2 application key, pick buckets, start the job. The same docs tell you to run the engines in the source AWS region. They also say self-serve Flexify is for less than 50TB, and that you should talk to sales above that. CloudSpot was 700TB, so treat today’s 50TB cutoff as current docs, not as their exact ticket.

Customers kept uploading to S3 while Flexify copied the existing objects. That dual-run was required because the galleries were live. After about 700TB landed, they tested for a week. Then they pointed new uploads at B2, copied the interim S3 objects in one more day, and stopped writing to S3.

Gavin called himself the bottleneck on the upload flip. Once new writes went to B2, the rest was easy. The other microservices just started reading from a new location.

B2’s S3-compatible API is why an app already written for S3 can often change endpoint and keys. The same page lists the gaps: no object-level ACLs, no IAM roles, no object tagging, no website configuration, and no browser POST to a pre-signed URL. CloudSpot’s write-up does not list which of those they hit.

What they gained

Gavin said no customer or end user could tell anything had changed. Speed and reliability, in his telling, stayed the same. The difference was the bill.

He put the immediate saving at $10,000 to $12,000 a month, with more as they grew. That is his quote on a vendor page, not an invoice I can open.

The saving let them turn a product back on. CloudSpot used to offer free gallery migration to photographers who switched platforms. S3 transfer fees made that a loss. Internal research on the vendor page says 90% of CloudSpot customers would not have moved without that free import. Within weeks of the B2 flip they restored the offer, and Gavin said transfer-out was about one tenth of the old cost.

They also hired another developer with money that used to go to AWS.

I am not treating the “infinite scale” line as a measured result. It is how Gavin described the new cost curve to investors.

What the vendor page skips

Backblaze does not publish a failed copy, a checksum miss, or a rollback. We only know the shape they chose: copy first, keep S3 writable, test for a week, flip new uploads, then catch the delta in a day.

That is a different cutover than the playbook’s default. The Amazon S3 → Backblaze B2 playbook wants a write freeze before the last delta. CloudSpot accepted a live S3 for the whole Flexify job, then a one-day catch-up. If you do that, you need a second pass for every object written after the first job started.

Versions, delete markers, lifecycle rules, KMS keys, and bucket policies are not in the story. The playbook treats those as rebuilds. ETags can also change across providers. Do not use ETag equality as the only pass.

The page also does not say how long S3 stayed readable after ingress stopped. I would keep it until you have proven B2 on a real gallery open, a new upload, and a download of a file that arrived during the copy.

If you need to go the other way, the reverse playbook is Backblaze B2 → Amazon S3. CloudSpot did not describe using it.

What I would copy

Do not freeze photographers on day one if the product is a live gallery. Copy the existing objects first. Keep S3 as the writer. Then flip new uploads and run one more job for the gap.

Use a cloud-to-cloud copier so the 700TB does not come through your laptop. Put the engines in the S3 region. That is the Flexify setting Backblaze documents.

Point the app at B2 with the S3-compatible endpoint and a scoped application key. Confirm the API gaps you actually use (ACLs, tags, POST uploads) before you call the pilot done.

After the flip, open an old gallery, upload a new image, and fetch a file that was written during the copy. Those three checks cover the bulk job, the new writer, and the delta.

The Amazon S3 → Backblaze B2 playbook is the checklist I would run. Use the Backblaze interview for the dual-run plus one-day catch-up, and remember it is a vendor page.