R2 foundations
Choose Workers API or S3 API
Use a binding inside Workers and reserve S3-compatible credentials for external tools and clients that need them.
8 minute lesson
A Worker accesses R2 through an in-process bucket binding such as env.UPLOADS. This avoids Cloudflare REST credentials and network overhead inside the Worker.
The S3-compatible API lets existing backup tools, SDKs, and external systems use R2. Scope access credentials narrowly, rotate them, and never expose a secret key in browser JavaScript. Presigned URLs can delegate one bounded operation.
List which parts of a file service run in Workers and which external maintenance tool genuinely needs S3 compatibility.
Use a Worker binding when the request already runs on Workers:
const object = await env.FILES.get('reports/july.pdf')
if (!object) return new Response('Not found', { status: 404 })
return new Response(object.body)
Use the S3-compatible API for external tools and existing SDKs. Keep both credential paths server-side. Test a missing key and a large object so the implementation proves it streams rather than buffering the whole file.
Lesson completed