Storage Tiering
Picora automatically moves assets you haven’t accessed in 30 days into a cheaper archive storage tier. The change is mostly invisible — your URLs keep working, your quotas stay the same — but your storage bill (or the bill we pay so we can keep your prices low) drops by 30–75%.
The basics
| Tier | What it is | Access speed |
|---|---|---|
| Hot (default) | Standard CF R2 / Aliyun OSS storage | Sub-50 ms CDN hit, 5–20 ms storage read |
| Archive | R2 Infrequent Access on the global deployment; OSS Archive in CN | Global: identical (transparent). CN: first hit takes 30 s–5 min to restore |
| Restoring | (CN-only intermediate state) The asset is being copied back to hot | Browser sees a placeholder PNG + Retry-After: 60 header |
| Archive locked | 30+ minutes stuck in restoring; ops alerted | Asset shows a “contact support” banner |
How it works
A lifecycle worker runs every night at 02:00 UTC. It looks for assets that have been in the hot tier for more than 30 days without anyone accessing them. For each one:
- It moves the bytes to archive storage on the underlying cloud.
- It updates the database row to mark
tier = 'archive'. - It logs an audit row in
sys_tier_migrations(kept for 365 days for ops).
The worker is idempotent — if step 1 succeeds but step 2 fails, the next run reconciles the orphan automatically. You’ll never lose data, and you’ll never be billed for both tiers at once.
Accessing archived assets
On the global deployment (picora.me)
Cloudflare R2 Infrequent Access is transparent. Hit the URL exactly like before; the CDN call adds ~100–200 ms the first time, then it’s hot at the edge for 24 hours.
On the China deployment (picora.cn)
Aliyun OSS Archive needs an explicit RestoreObject request. The first access:
- Picora’s
image-servereturns a placeholder PNG withHTTP 202 AcceptedandRetry-After: 60. - Behind the scenes, Picora has triggered the restore.
- After 30 s–5 min, the asset is hot again.
- Subsequent requests serve the real bytes at full speed.
You can also proactively warm up archived assets by calling POST /v1/me/storage-tier/promote with up to 100 IDs at once.
Savings
The “Saving X / month” badge in your dashboard is computed live from the current archive footprint × the price difference per GB. Real numbers:
| Platform | Hot $/GB·month | Archive $/GB·month | Savings |
|---|---|---|---|
| Cloudflare R2 (US default) | $0.015 | $0.010 | 33% |
| Aliyun OSS (cn-hangzhou) | ¥0.12 | ¥0.03 | 75% |
These prices are stored in sys_pricing_config and admin-tunable; historical migrations aren’t recomputed when prices change, so your “saved this month” figure may shift slightly as we update tariffs.
Quotas don’t change
Your plan limit (e.g. 10 GB total on Pro+) covers hot + archive combined. The split is purely an internal cost optimization — you should not worry about it. If you upload 8 GB and 6 GB is archived, you’ve used 8 GB of your 10 GB quota.
Bulk delete helper
Hand-in-hand with tiering, the picora-center “Bulk delete” dialog lets you find old / large / tagged assets and remove them in a single confirmed action:
- Filter by created-before date, minimum size, tags, or visibility.
- Click Preview — you’ll see a confirmed match count and total bytes.
- Type
DELETEin the confirmation field to unlock the irreversible button. - Picora deletes them in one sweep using a server-side snapshot token so the count you saw is exactly what gets removed (no race conditions with new uploads).
The snapshot expires after 5 minutes; if you wait too long you’ll need to re-preview.
Edge cases
- Stuck in
restoringfor 30+ minutes. Picora marks the assetarchive_lockedand emails you. Ops will fix it; the asset doesn’t count against your quota while locked. - Promote a recently uploaded asset. No-op —
tier='hot'already, the API returnsalready_hot. - Promote a 2-day-old archive asset right after the lifecycle ran. Should never happen (lifecycle requires 30 days idle), but if it does, the API treats
archivelike normal and triggers restore. - Plan downgrade leaving you over quota. Existing archived assets remain accessible; uploads are blocked until you delete enough. Hot assets do not automatically migrate to archive on downgrade.
Privacy
Tier transitions log only the resource id, user id, sizes, and timing — never the content. Audit rows are pruned after 365 days.