# Storage and sizing

> Store Frame's photos and videos on local disk or in Cloudflare R2 (or any S3-compatible bucket, encrypted before upload), and estimate the disk, bandwidth and money a group needs.

Source: https://crow.sg/apps/frame/docs/storage/

Decide on storage **before** your friends start posting: switching an existing server between local disk and R2 is not automatic.

## Local disk (default)

Photos and videos are stored as files in the data directory: `/var/lib/frame/media` with the Linux installer, or the `frame-data` volume with Docker. This is the simplest option, and backups are copies of the folder. Files are stored as uploaded; use full-disk encryption on the host if that matters to you.

## Cloudflare R2 or another S3 bucket

Useful when your disk is small (a Pi's SD card, a tiny VPS) or you want media off the machine. R2 has **10 GB of free storage and free egress**, so viewing photos costs nothing. Frame **encrypts every file before uploading it** (AES-256-GCM), so the bucket only ever stores ciphertext.

1. **Open R2**

   In the Cloudflare dashboard, open **R2 Object Storage**. The first time, Cloudflare asks for a payment method; you aren't charged within the free tier.

2. **Create a private bucket**

   Create a bucket, for example `frame-media`, with automatic location. Leave it **private**: don't enable public access or a public `r2.dev` URL. Frame serves the media itself.

3. **Create a token for that bucket only**

   Under **R2 → Manage API tokens → Create API token**, choose the permission **Object Read & Write** and **Apply to specific buckets only**, then pick `frame-media`. Copy the **Access Key ID**, the **Secret Access Key** (shown only once) and the **S3 endpoint** (`https://<account-id>.r2.cloudflarestorage.com`).

4. **Configure Frame**

   ```ini title="frame.conf"
   FRAME_STORAGE=s3
   FRAME_S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
   FRAME_S3_BUCKET=frame-media
   FRAME_S3_REGION=auto
   FRAME_S3_ACCESS_KEY_ID=<access key id>
   FRAME_S3_SECRET_ACCESS_KEY='<secret access key>'
   # FRAME_S3_ENCRYPT=true   (the default; keep it)
   ```

   Restart (`sudo systemctl restart frame`, or `docker compose up -d`), post a photo, and check that objects appear under `frame/` in the bucket.

5. **Back up the encryption key**

   Frame created `secrets.json` in its data directory. It holds the key that encrypts your bucket's objects. Keep a copy somewhere safe, such as a password manager or an offline USB stick ([Backups & restore](https://crow.sg/apps/frame/docs/backups/)).

> [!WARNING] Lose `secrets.json`, lose the photos
> Without `secrets.json`, every photo in the bucket is unreadable forever. Keep `frame.conf` private too: it now holds the bucket credentials.

## How much disk, bandwidth and money?

Assumptions: photos are about **400 KB** and their thumbnails about **60 KB**; a 10-second video is about **3 MB**. Each photo or video is stored **once**, however many friends receive it. The server never re-encodes images or video.

| Scenario | Uploads per day | Storage per day | **Storage per year** |
|---|---|---|---|
| 10 friends × 5 photos a day | 50 photos | 50 × 460 KB = 23 MB | **≈ 8.4 GB** |
| 10 friends × (4 photos + 1 ten-second video) a day | 40 photos + 10 videos | 18.4 MB + 30.6 MB = 49 MB | **≈ 18 GB** |
| 4 people × 3 photos a day (family) | 12 photos | 5.5 MB | **≈ 2 GB** |

The database (messages, reactions, accounts) stays tiny in comparison: a few hundred MB after years.

**Bandwidth.** In the photos-only case, if every moment reaches 9 friends who each load the thumbnail and the full photo, that's about 200 MB a day, or roughly **6 GB a month** of downloads. With videos it's about 13 GB a month. Cheap VPSs include terabytes, and R2 egress is free.

| Setup | Monthly |
|---|---|
| A VPS with local storage | About €4–6. A 40 GB disk lasts the photos-only group about 4 years. |
| A Raspberry Pi at home | Electricity: a Pi 4 draws about 3–5 W, roughly €1 a month. |
| + Cloudflare R2 | **€0** up to 10 GB. Beyond that, about $0.015 per GB-month (≈ $0.15 a month for 20 GB). |
| + a domain | About €10 a year. |

**Hardware:** 1 CPU core and 512 MB–1 GB of RAM are enough. Frame itself uses roughly 30–60 MB, and even a Pi stays idle most of the time.
