Both of these exist because AWS charges roughly nine cents per gigabyte to send you your own data, and both attack that from opposite ends.
R2's pitch is zero egress fees, full stop. Not discounted, not capped, not conditional on a partner CDN — you pay to store bytes and to make API calls, and downloads cost nothing. For anything with a public read path — image hosting, video, game assets, package registries, a large model download — this converts a variable, frightening line item into a fixed, boring one.
B2's pitch is cheap storage plus generous free egress. Storage per terabyte is meaningfully below R2's, and egress is free up to a multiple of your stored data, with Bandwidth Alliance partners (Cloudflare among them) waiving it entirely for traffic that goes through them.
The rule of thumb: if your egress-to-storage ratio is high, R2 wins; if you're storing a lot and serving a little, B2 wins. Backups, archives and media libraries with a long tail favour B2. Public asset delivery, an image CDN origin or anything user-facing favours R2.
The tiebreaker is usually the rest of the stack. If you already run Cloudflare, R2 binds directly to Workers with no per-request egress and no extra network hop, and that integration is worth more than the storage rate difference. If you don't, B2 is a plain S3-compatible bucket that behaves the way you expect from anywhere.