Bỏ qua

R2 Storage Overview

R2 là gì?

S3-Compatible Object Storage

┌─────────────────────────────────────────────────────────────┐
│                    CLOUDFLARE R2                             │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  S3-compatible object storage without egress fees           │
│                                                              │
│  Features:                                                   │
│  - S3 API compatibility                                     │
│  - Zero egress fees                                         │
│  - Global distribution                                      │
│  - Workers binding                                          │
│  - Public bucket support                                    │
│                                                              │
│  Use cases:                                                  │
│  - Static assets                                            │
│  - User uploads                                             │
│  - Backups                                                  │
│  - Large files                                              │
│                                                              │
└─────────────────────────────────────────────────────────────┘

R2 vs Supabase Storage

Comparison

Feature R2 Supabase Storage
Egress fees Zero Included in plan
Max file 5GB (single), unlimited (multipart) 5GB
RLS integration No Yes
Image transforms No Yes
S3 compatible Yes Yes
Edge access Native Via API

Khi nào dùng gì?

Use SUPABASE STORAGE when:
✅ Need RLS (user-specific access)
✅ Need image transformations
✅ Files tied to database records
✅ Simple setup preferred

Use R2 when:
✅ Large files (>50MB)
✅ Public static assets
✅ High egress volume
✅ Need S3 compatibility
✅ Edge Worker access

Basic Setup

Create Bucket

# Create R2 bucket
wrangler r2 bucket create my-bucket

# List buckets
wrangler r2 bucket list

Configuration

# wrangler.toml

[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-bucket"

Basic Operations

Worker Binding

interface Env {
  MY_BUCKET: R2Bucket;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    const key = url.pathname.slice(1);  // Remove leading /

    switch (request.method) {
      case 'GET':
        // Get object
        const object = await env.MY_BUCKET.get(key);
        if (!object) {
          return new Response('Not Found', { status: 404 });
        }
        return new Response(object.body, {
          headers: {
            'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream',
          },
        });

      case 'PUT':
        // Upload object
        await env.MY_BUCKET.put(key, request.body, {
          httpMetadata: {
            contentType: request.headers.get('Content-Type') || 'application/octet-stream',
          },
        });
        return new Response('Uploaded');

      case 'DELETE':
        // Delete object
        await env.MY_BUCKET.delete(key);
        return new Response('Deleted');

      default:
        return new Response('Method Not Allowed', { status: 405 });
    }
  },
};

Pricing

R2 Pricing

┌─────────────────────────────────────────────────────────────┐
│                    R2 PRICING                                │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Free tier:                                                  │
│  - 10 GB storage                                            │
│  - 1M Class A ops/month (PUT, POST, LIST)                  │
│  - 10M Class B ops/month (GET, HEAD)                       │
│                                                              │
│  Paid:                                                       │
│  - $0.015/GB storage                                        │
│  - $4.50/M Class A ops                                      │
│  - $0.36/M Class B ops                                      │
│  - $0 egress (always free!)                                 │
│                                                              │
│  Compared to S3:                                             │
│  - S3: $0.09/GB egress                                      │
│  - R2: $0 egress                                            │
│                                                              │
└─────────────────────────────────────────────────────────────┘

When to Consider R2

Good Fit

✅ High-traffic public assets
✅ CDN replacement
✅ S3 migration (API compatible)
✅ Large file storage
✅ Backup/archive storage

Not Ideal For

❌ User uploads needing RLS
   → Use Supabase Storage

❌ Image transformations
   → Use Supabase Storage

❌ Simple file needs
   → Supabase easier to set up

Tổng kết

Key Points

  • S3-compatible API
  • Zero egress fees
  • Worker native binding
  • Good for static assets

Recommendation for Light Stack

Primary: Supabase Storage
- User uploads
- RLS protection
- Image transforms

Secondary: R2 (optional)
- Very large files
- High-traffic public assets
- Cost optimization for egress

Q&A

  1. Có use case cần R2 không?
  2. File sizes thường bao nhiêu?
  3. Public hay private storage?