type: runbook
status: active
timestamp: 2026-06-22
tags: [runbook, hosting, free-tier, image-cdn, cloudinary, imagekit, imgbb, github-releases, replication]

Free hosting — image CDN + transforms + durability replication (Cloudinary, ImageKit, imgbb, GitHub Releases, Uploadcare)

4-host replicate-everywhere image CDN strategy

Image CDN + transforms + durability replication — free tiers (2026-06-22)

Family pattern for user-uploaded images: compress once at upload, replicate across 4 no-card hosts, first-200-wins on the client. Cloudinary + ImageKit serve transforms and edge bandwidth; imgbb and GitHub Releases are durability rails.

Build-time images on static sites stay where they are — bundled into the Pages build and served from the Cloudflare Pages CDN. Replication is for runtime user-uploads only.

The table

#ProviderFree tierCard@signupCard to use freeKYCRoleVerdict
1Cloudinary25 credits/mo (1 credit = 1K transforms OR 1 GB storage OR 1 GB bandwidth), 3 usersNONONOCDN + transformsKEEP
2ImageKit20 GB storage + 20 GB bandwidth/mo, unlimited transforms, free-foreverNONONOCDN + transformsKEEP
3imgbbNo expiry, no signup required, 32 MB per image capNONONODurability + no-account fallbackKEEP
4GitHub Releases2 GB per asset, soft repo cap ~5 GB, unlimited public reposNONONOCold-storage durability railKEEP
5Uploadcare”Trial” plan (de-facto perma-free): 10K ops + 10 GB storage + 10 GB traffic/moNONO (adding card auto-upgrades to Pro)NOCDN + transformsKEEP (don’t add card)
6Bunny Optimizer14-day trial only; post-trial $9.50/mo + $1/mo minimumNONODROP
7Imgix30-day trial only; paid after ($0.25/credit)NONODROP

The 4-host replicate-everywhere pattern

Upload flow (client → master upload Worker):
  1. Compress + optimise image to AVIF/WebP at target sizes (max 2400px long edge)
     — ORIGINAL is NEVER stored. Optimisation is the only step.
  2. Fan-out upload to all 4 hosts in parallel:
       a. Cloudinary       (POST signed upload, get publicId)
       b. ImageKit          (POST upload API, get fileId)
       c. imgbb             (POST https://api.imgbb.com/1/upload?key=..., get url)
       d. GitHub Releases   (gh release upload <tag> <file>, get browser_download_url)
  3. Persist tuple in Firestore:
       imageUrls: {
         cloudinary: "https://res.cloudinary.com/.../image.avif",
         imagekit:   "https://ik.imagekit.io/.../image.avif",
         imgbb:      "https://i.ibb.co/.../image.jpg",
         ghRelease:  "https://github.com/.../releases/download/.../image.avif"
       }

Read flow (client <Img4Way> wrapper):
  1. Try cloudinary URL  → if 200, done.
  2. Else imagekit       → if 200, done.
  3. Else imgbb          → if 200, done.
  4. Else ghRelease      → if 200, done.
  5. Else error placeholder.

This gives 4 independent uncorrelated rails. If Cloudinary credit-pool exhausts mid-month, ImageKit picks up. If both transform-CDNs go down, imgbb (a no-signup public bucket) and GitHub (the most durable host in the world for a hobby family) cover. Same image, 4 hosts, first 200 wins.

Optimisation is the only mutation. We compress once at upload-time (AVIF preferred, WebP fallback) and store ONLY the optimised version. The original RAW upload is never persisted anywhere. This:

Why each host has a role

How the family uses image CDNs today

Build-time static images: bundled into the Pages build, served from Cloudflare Pages CDN. No replication needed because the binary lives in git, mirrored across chirag127/<repo> on GitHub + Cloudflare Pages deploy storage.

User-uploaded runtime images (avatars, journal photos, content app uploads): use the 4-host pattern above. The master upload Worker wraps the fan-out; the <Img4Way> component in astro-shell-npm-pkg wraps the read.

Quirks per provider

Recommendation for the family

  1. All user-uploaded images flow through the 4-host replicate-everywhere pattern. Master upload Worker handles fan-out; <Img4Way> handles read failover.
  2. Build-time images stay on Cloudflare Pages CDN (no replication needed; git + Pages mirrors are durable enough).
  3. Never store the original. Compress at upload, replicate the AVIF/WebP. Saves storage, egress, and on-the-fly transform credits.
  4. Don’t add a card to Uploadcare if you ever sign up — it auto-upgrades to Pro.

Sources


Edit on GitHub · Back to index