Technical article
Cloudflare R2 for WooCommerce Product Images
Use Cloudflare R2 for WooCommerce product images and galleries safely, with generated-size coverage, migration, verification, restore, cache checks, and a clear boundary around protected downloads.
Cloudflare R2 can be a strong object-storage target for WooCommerce product imagery, especially for stores with a large catalog and substantial public image traffic.
The useful reason is not simply that R2 is “S3-compatible.” For a storefront, the combination of S3-style object storage, Cloudflare delivery options and R2’s current no-egress-bandwidth-charge model can make it worth evaluating.
But WooCommerce correctness still comes first: product images have generated sizes, gallery contexts, responsive variants and cache behavior that all need to survive an offload or migration.
What WooCommerce media belongs in R2?
WooCommerce product images are normal WordPress Media Library attachments. WooCommerce’s official product-image documentation describes main product images, catalog images and thumbnails used across the storefront.
Those public images are a good fit for Media Library offload.
Protected downloadable products are different. WooCommerce has separate handling for paid downloads and explicitly notes that ordinary Media Library files are public by default. Universal Storage should not be used as a substitute for WooCommerce download authorization.
That boundary is important enough to design before migration, not after it.
Why R2 can be attractive for a store
Cloudflare’s R2 pricing documentation currently charges for stored data and operations while listing internet egress bandwidth as free. Standard and Infrequent Access classes have different storage/request/retrieval economics, so the total cost still depends on the workload.
Official pricing: Cloudflare R2 pricing.
Product imagery can generate a high read-to-write ratio:
- an image is uploaded once
- WooCommerce generates multiple variants
- catalog pages request images repeatedly
- product pages request larger images and gallery assets
- search, related products and carts request thumbnails
- bots, social previews and feeds can add more reads
For that pattern, bandwidth economics are worth modeling alongside storage and operation charges.
R2 architecture for WooCommerce imagery
A typical flow is:
WooCommerce / WordPress
|
v
Media Library attachment + generated sizes
|
v
Cloudflare R2 bucket
|
v
custom delivery domain / Cloudflare edge
|
v
store visitors
The attachment record remains in WordPress. R2 stores the binary files. A public delivery domain can be configured separately from the S3-compatible API endpoint used for storage operations.
Configure R2 as a storage provider
With Universal Storage, an R2 profile uses:
- bucket name
- account-specific S3-compatible endpoint
- R2 credentials
- the expected R2 region behavior
- delivery hostname/custom domain when used
Start with the current Cloudflare R2 provider docs and the broader WordPress R2 offload guide.
Test the provider connection before enabling production offload.
Product-image variants are first-class objects
WooCommerce uses product images in several contexts, and the active theme can influence the generated image sizes.
A single source image can produce:
shoe.jpg
shoe-150x150.jpg
shoe-300x300.jpg
shoe-600x600.jpg
shoe-768x768.jpg
...
The storefront might choose a different variant depending on product page, catalog grid, cart, gallery or device viewport.
A correct R2 migration must therefore account for the original and the generated sizes. Checking only the full-size product image is insufficient.
Migrate the existing catalog gradually
Do not move a large WooCommerce library in one unobserved operation.
A safer sequence:
- back up the WordPress database
- configure and test R2
- keep local files intact
- migrate a small set of representative products
- verify originals and generated sizes
- test live storefront contexts
- inspect failed/pending state
- continue in batches
Universal Storage Free includes migration of the existing Media Library.
The detailed workflow is in Migrate existing media.
Verification before local cleanup
For a store, the cost of a wrong cleanup decision is not abstract: customers can see missing products immediately.
Universal Storage keeps verification separate from cleanup. A tracked object can be verified, missing, failed or temporarily unknown depending on what the provider actually returned.
That distinction prevents a provider timeout from being interpreted as permission to delete the local copy.
Use:
Test every storefront context
After offload, inspect more than the product edit screen.
Test:
- main product image
- product gallery
- shop/category/archive grids
- related products
- upsells and cross-sells
- cart thumbnails
- block-based product layouts
- mobile responsive images
- old products and newly uploaded products
The official WooCommerce image documentation is useful when identifying which image role a theme is rendering: Adding Product Images and Galleries.
Cache behavior can hide problems
Cloudflare caching can be useful for storefront images, but cache state is not the same as object-storage state.
After migration, image replacement or regeneration:
- verify the remote object independently
- inspect the public custom-domain URL
- purge stale cache where necessary
- test an uncached request
- confirm the response contains the expected object
A cached 200 can temporarily hide a broken origin. A cached 404 can also remain after the object has been created until the cache is purged or expires.
Cloudflare documents R2’s storage consistency separately from cache behavior; see R2 consistency.
Thumbnail regeneration needs a remote follow-up
WooCommerce documents thumbnail regeneration when image dimensions or themes change.
That operation can create new local image files after the original attachment had already been offloaded.
After regeneration:
- identify the new image variants
- ensure they are included in offload/inventory state
- verify them in R2
- test storefront markup and
srcset - only then clean the local variants
This should be part of a theme-change runbook on a remote-media store.
R2 vs S3 for WooCommerce
R2 and S3 can both serve WooCommerce product media correctly. The more useful comparison is operational:
R2 can be attractive when:
- public image bandwidth is high
- the site already uses Cloudflare heavily
- R2’s current egress model materially changes the cost model
- S3-compatible provider portability is valuable
S3 can be attractive when:
- the rest of the infrastructure is already AWS-centric
- IAM/CloudFront and AWS operations are already established
- AWS-native integrations matter more than R2’s bandwidth model
Read the deeper Cloudflare R2 vs Amazon S3 comparison.
Moving an existing WooCommerce catalog from S3 to R2
Do not edit a live S3 profile into an R2 profile before the destination is populated.
With Universal Storage Pro:
- keep S3 as the source profile
- add R2 as a separate destination
- test both provider connections
- copy tracked media
- verify the R2 destination
- switch delivery only after verification
- keep S3 for a rollback window
- optionally clean the source later
The full runbook is Move WordPress Media from Amazon S3 to Cloudflare R2 Safely.
Do not confuse product media with paid download files
WooCommerce’s downloadable-product documentation allows files to be uploaded through the product editor or referenced by external URL, and its security documentation distinguishes protected download methods from public Media Library URLs.
If a store sells digital files:
- product/gallery images can use the Media Library offload workflow
- protected ZIP/PDF/software downloads need their own authorized delivery design
- do not assume a public R2 custom domain is suitable for paid downloads
See WooCommerce digital/downloadable product handling.
WooCommerce R2 checklist
- Back up the database.
- Configure R2 credentials and bucket.
- Test the connection.
- Upload one new product image.
- Confirm original and generated variants.
- Test product, catalog, gallery and cart views.
- Migrate a small existing batch.
- Verify remote objects.
- Test restore.
- Validate custom-domain/cache behavior.
- Re-verify after thumbnail regeneration.
- Keep protected downloadable-product files outside the public-image offload assumption.
- Clean local images only after verified remote state.
Build for reversibility
The best WooCommerce media-storage setup is not the one that saves the most disk space on day one. It is the one that can be verified, restored and migrated later without rewriting the catalog.
Use R2 for public product media when its network and cost model fit the store, but keep WordPress in control of attachment metadata and keep the recovery path explicit.
Start with KAZCODE Universal Storage Free or review the Cloudflare R2 provider docs.