Skip to content
Go back

Backblaze B2 + rclone: Tiered Backup at Real-World Costs

By SumGuy 12 min read
Backblaze B2 + rclone: Tiered Backup at Real-World Costs

You Priced AWS Glacier and Rage-Quit

You sat down, calculator open, feeling responsible. You were going to do this right. Offsite backups, encrypted, versioned, cheap. AWS Glacier Deep Archive — $0.00099 per GB per month, baby. That’s practically free.

Then you hit the restore calculator.

2TB at $0.02/GB expedited retrieval. That’s $40 just to start getting your data back. Add $0.09/GB egress out of us-east-1, and suddenly you’re looking at $220 in egress fees to restore a 2TB backup you paid $2/month to store. And that’s before the per-request charges, the retrieval tier minimums, or the 90-day minimum storage penalty for objects you deleted early.

You closed 14 tabs and poured a drink.

Here’s the thing: Backblaze B2 is not a compromise. For home lab use — and honestly, for a lot of small business use — it’s genuinely the right tool. $6/TB/month storage, $0.01/GB egress, no minimum storage duration on standard tier, and egress to Cloudflare is free. Pair it with rclone and you’ve got a backup stack that won’t surprise you with a $400 invoice when you actually need it.

Let’s build it properly.


The Cloud Storage Reality Check (2026 Edition)

Before you commit, know what you’re comparing against. Here’s what actually matters for a home lab with ~2TB of data to back up.

ProviderStorage/TB/moEgress/GBGotchas
AWS S3 Standard$23$0.09Everything is expensive
AWS S3 IA$12.50$0.09 + $0.01/GB retrievalMin 30-day per object
AWS Glacier Instant$4$0.09Min 90-day, retrieval fees
Glacier Deep Archive$0.99$0.0912h retrieval, 180-day min
Wasabi$6.99$090-day minimum storage — deleting early still costs
Cloudflare R2$15$0No egress but storage ≈ 2.5x B2
Storj$4$0.07Decentralized, performance varies
Backblaze B2$6$0.01Egress to Cloudflare is free

Wasabi looks attractive until you realize the 90-day minimum. If you’re rotating backup snapshots more frequently than that — and you should be — you’re paying for deleted objects. The math gets ugly fast with incremental backups.

R2 is excellent if you’re already deep in the Cloudflare ecosystem and you’re serving files publicly. For pure backup cold storage, the storage cost differential stings.

B2’s real superpower: Cloudflare egress partnership. If you front your B2 bucket with Cloudflare, egress is $0. For restore operations, that’s meaningful. For 2TB in egress fees alone, you’re looking at $20 on B2 vs $180+ on S3. That’s not a rounding error.


rclone vs restic vs duplicacy on B2

You’ve got three serious options. They’re not interchangeable and the choice matters.

rclone — think of it as rsync for cloud storage. It syncs files, mirrors directories, moves data. It does not deduplicate. It doesn’t understand “this backup contains changed blocks.” It’s fast, it’s composable, and it integrates with everything. It’s the right choice for file-level syncs and when you want transparency into exactly what’s in your bucket.

restic — content-addressed deduplication, encrypted by default, designed for backups specifically. A restic repo on B2 will be significantly smaller than an rclone sync for large datasets with incremental changes. The tradeoff is that you can’t browse the bucket and see your files — the repo is opaque blobs. Restoring requires restic. For actual backup (not just offsite copy), restic wins on efficiency.

duplicacy — chunk-level dedup across multiple machines, sharable backend. Legitimately useful for multi-machine setups. More complex to operate, less community tooling.

The pragmatic answer for home lab:

For this article, we’re building the rclone layer. It handles the tiered storage movement, scheduling, and lifecycle management. restic can sit on top of it or alongside it.


B2 Setup: Application Keys Per Bucket

Don’t use your master key with rclone. Ever. Create a dedicated application key scoped to a specific bucket. This way, if your rclone config gets compromised, the blast radius is one bucket.

In the Backblaze console: Account → App Keys → Add a New Application Key

You’ll get a keyID and applicationKey. Save these — the applicationKey is only shown once.

Now configure rclone:

Terminal window
rclone config

Walk through the interactive setup:

n) New remote
name> b2-homelab
Storage> b2
account> your-keyID-here
key> your-applicationKey-here
hard_delete> false

hard_delete = false keeps deleted files as hidden versions — critical for recovery from accidental deletes. Set lifecycle rules to expire old versions on a schedule (covered below).

Test it:

Terminal window
rclone lsd b2-homelab:homelab-backups
rclone ls b2-homelab:homelab-backups --max-depth 1

Your config lives at ~/.config/rclone/rclone.conf. Protect it:

Terminal window
chmod 600 ~/.config/rclone/rclone.conf

If you’re running rclone as root or a service account, move the config accordingly and reference it with --config /path/to/rclone.conf.


Encryption: Pick One and Commit

You have three options. Pick one. Using multiple in combination is how you lose data.

Option 1: B2 SSE (Server-Side Encryption) Backblaze encrypts at rest using their managed keys. You get encryption at rest without any complexity. But: Backblaze holds the keys. This is fine for “protect against storage breach” scenarios, not fine for “protect from Backblaze” scenarios. Enabled per bucket in the console.

Option 2: rclone crypt rclone wraps your B2 remote in an encryption layer. Files are encrypted client-side before upload. The bucket contains opaque encrypted blobs — not browseable without the rclone crypt config.

Terminal window
rclone config
# Add new remote
n) New remote
name> b2-homelab-crypt
Storage> crypt
remote> b2-homelab:homelab-backups/encrypted
filename_encryption> standard
directory_name_encryption> true
password> [enter a strong password, store in your password manager]
password2> [salt, also store this]

Now use b2-homelab-crypt: as your target. Everything written goes through encryption transparently.

Option 3: restic encryption If you’re using restic on top of rclone or natively, restic handles encryption itself with a repo password. The B2 SSE or rclone crypt layer is redundant here — restic is the encryption boundary.

Recommendation: For rclone-synced files, use rclone crypt. For restic repos, let restic handle it and skip the crypt wrapper (it adds overhead for no benefit).


The Tiered Backup Strategy

Here’s the actual architecture for a 2TB home lab:

[Local: mergerfs/ZFS pool] HOT tier — instant access, no cost/GB
↓ rclone sync nightly
[B2 Standard bucket] WARM tier — $6/TB/mo, $0.01/GB egress
↓ lifecycle rule (90 days old)
[B2 archive/lifecycle hidden] COLD tier — old versions expired or archived

Optionally, for true cold archival (config snapshots, annual backups):

[B2 Standard] → rclone copy to Glacier Deep Archive via AWS CLI

But honestly, for most home labs, B2 Standard with versioning and lifecycle rules is your cold tier. You’re not running a compliance regime. If something catastrophic happens and you need a 90-day-old backup, B2 has it. The restore cost on 2TB would be $20 in egress — fine.


rclone Config for Real Use

Create a dedicated config file for your backup operations (keeps it separate from interactive use):

/etc/rclone/backup.conf
[b2-homelab]
type = b2
account = your-keyID
key = your-applicationKey
hard_delete = false
[b2-homelab-crypt]
type = crypt
remote = b2-homelab:homelab-backups/encrypted
filename_encryption = standard
directory_name_encryption = true
password = your-encrypted-password
password2 = your-encrypted-salt

Note: rclone stores passwords in its own obfuscated format. Use rclone config to set passwords interactively — it handles the encoding. Don’t put plaintext passwords in the config file.

A typical sync command:

Terminal window
rclone sync \
/data/media \
b2-homelab-crypt:media \
--config /etc/rclone/backup.conf \
--transfers 8 \
--checkers 16 \
--bwlimit "08:00,512K 19:00,off" \
--stats 60s \
--log-file /var/log/rclone/backup.log \
--log-level INFO \
--exclude "*.tmp" \
--exclude ".Trash-*/**"

The --bwlimit "08:00,512K 19:00,off" is gold. Saturate the uplink overnight (no limit outside the schedule), cap at 512K during work hours, and pause entirely 7pm-8am. Adjust to your ISP’s off-peak window.

--transfers 8 and --checkers 16 tune concurrency. On a 1Gbps symmetric connection with an NVMe source, you can push these higher. On a 500Mbps upload with spinning rust, stay conservative.


Lifecycle Rules: Expire Your Versions

With hard_delete = false, every deleted or overwritten file stays in B2 as a hidden version. This is great for recovery. It’s also how you accidentally accumulate 4TB of hidden junk on a 2TB dataset.

Set lifecycle rules in the Backblaze console per bucket:

Bucket → Lifecycle Rules:

In B2’s console this translates to:

For a more aggressive setup (tighter version window):

B2 Lifecycle Policy (via API)
{
"bucketId": "your-bucket-id",
"lifecycleRules": [
{
"daysFromHidingToDeleting": 14,
"daysFromUploadingToHiding": null,
"fileNamePrefix": ""
}
]
}

Apply via B2 CLI if you prefer scriptable setup:

Terminal window
b2 update-bucket --lifecycle-rule \
'{"daysFromHidingToDeleting": 14, "fileNamePrefix": ""}' \
homelab-backups

Systemd Service + Timer

Don’t run this from cron if you’re on a modern Linux system. Systemd timers give you better logging, dependency management, and manual trigger support.

/etc/systemd/system/rclone-b2-backup.service
[Unit]
Description=rclone B2 backup sync
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=backup
ExecStart=/usr/bin/rclone sync \
/data/media \
b2-homelab-crypt:media \
--config /etc/rclone/backup.conf \
--transfers 8 \
--checkers 16 \
--bwlimit "08:00,512K 19:00,off" \
--log-file /var/log/rclone/backup.log \
--log-level INFO \
--stats 60s \
--exclude "*.tmp" \
--exclude ".Trash-*/**"
StandardOutput=journal
StandardError=journal
/etc/systemd/system/rclone-b2-backup.timer
[Unit]
Description=Run rclone B2 backup nightly
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=30m
Persistent=true
[Install]
WantedBy=timers.target
Terminal window
systemctl daemon-reload
systemctl enable --now rclone-b2-backup.timer
systemctl status rclone-b2-backup.timer
journalctl -u rclone-b2-backup.service -f

RandomizedDelaySec=30m staggers the start across 30 minutes — useful if you’re running this on multiple machines. Persistent=true means if the system was off at 2 AM, it runs the missed backup when it comes back up.


The Restore Test You’re Not Doing

Every quarter. Set a calendar reminder right now.

Pick a known directory from your backup. Not a tiny one. Something meaningful — a config directory, a media subfolder, a database dump. Restore it to a temp location and verify the hashes match.

Terminal window
# Pick a test directory from your backup
RESTORE_TARGET="/tmp/restore-test-$(date +%Y%m%d)"
mkdir -p "$RESTORE_TARGET"
# Restore from B2
rclone copy \
b2-homelab-crypt:media/important-configs \
"$RESTORE_TARGET" \
--config /etc/rclone/backup.conf \
--transfers 4 \
--progress
# Verify hashes match the source
rclone check \
/data/media/important-configs \
"$RESTORE_TARGET" \
--one-way
# Clean up
rm -rf "$RESTORE_TARGET"

rclone check compares checksums both directions. --one-way checks that everything in the source exists in the destination (not the reverse). If you get errors, you have a problem. Better to find out on a Tuesday afternoon than during an actual incident.

Log the results. Date them. Keep them somewhere outside the system you’re backing up.


Real-World Cost Math for 2TB

Let’s be honest about what this actually costs.

Storage:

Egress (normal operations):

Compare to S3 Standard:

Annual difference: ~$420/year saved just on storage. The restore egress gap is another $160 when you need it.

Bandwidth cost from your ISP: This is real but usually not metered for home use. If you’re on a capped plan, factor in ~60GB/month for incremental changes on a 2TB dataset (rough rule of thumb: 3% churn rate).


The Bottom Line

AWS is a great product. It is not the right product for a home lab’s backup tier. The pricing model is designed for enterprises that can negotiate volume discounts and have billing teams to manage the complexity.

B2 + rclone is straightforward: you know what you’re paying, you know what restore costs, and there are no surprises at the end of the month. $12-15/month for 2TB of offsite backup that you actually tested and can restore from is a good deal. The fact that the tooling is all open source and runs on a Raspberry Pi if necessary is a bonus.

Set up the application keys, enable encryption at the rclone layer, configure the lifecycle rules, and put the restore test on a calendar. The backup that nobody tests is a backup nobody should trust.

Your 2 AM self — the one dealing with a failed ZFS pool or a misconfigured rm -rf — will appreciate having verified this works before they needed it.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Glance vs Homepage vs Dashy: Home Lab Dashboards Compared
Next Post
Trivy vs Grype vs Docker Scout

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts