Lifecycle, security, and operations

Operate and recover R2

Monitor object operations, storage, errors, and credentials while maintaining tested copies for data whose loss is unacceptable.

Storing data in R2 is the easy part. Keeping track of it, and getting it back when something goes wrong, is where the work is.

Know what you have

For every bucket I want to answer a few questions without opening a ticket. Who owns it? Which Workers bind to it? Which S3 API tokens can reach it? Which lifecycle rules run on it? Which custom domains serve it? Then the numbers: object count, storage size, and error rate.

The dashboard shows the metrics per bucket. Wrangler shows the inventory:

npx wrangler r2 bucket list
npx wrangler r2 bucket lifecycle list my-app-files
npx wrangler r2 bucket domain list my-app-files

If a bucket has a lifecycle rule you don’t recognize, find out who added it before the rule finds out for you.

Rotate credentials without an outage

S3 API tokens are what external tools use to reach the bucket. Rotate them in this order: create the new token, deploy it to every client, watch traffic succeed, then revoke the old one. Never commit a token to source.

If a token leaks, flip the order. Revoke first, fix the clients after. A short outage is cheaper than an open door.

Durability is not backup

R2 stores your objects redundantly, so a failing disk is not your problem. That protects you from hardware. It does not protect you from yourself.

A delete with the wrong key, a bug that overwrites objects with empty bodies, a stolen token that wipes a bucket: all of these succeed. R2 does exactly what it was told.

So decide which data needs a copy that lives somewhere else. That can be a second bucket you copy into, or an export to another provider. Then test the restore path, because an untested backup is a hope.

Inventory before deleting or changing lifecycle rules:

npx wrangler r2 object get practice-files/reports/july.pdf --file restored.pdf --remote
shasum -a 256 restored.pdf

Compare the checksum with the source or manifest. Object replication and lifecycle cleanup are not the same as a recoverable backup. Restore into a different key or bucket first, verify the application can read it, and only then change the production object.

Try this on a disposable object: delete it, restore it from your copy, and check both the body bytes and the metadata. The content type and custom metadata are easy to lose in a copy, and the application will notice before you do.

Lesson completed