[{"data":1,"prerenderedAt":567},["ShallowReactive",2],{"blog-self-hosted-image-transformation-with-repix":3,"blog-md-self-hosted-image-transformation-with-repix":565,"blog-surround-self-hosted-image-transformation-with-repix":566},{"id":4,"title":5,"author":6,"body":11,"category":554,"date":555,"description":556,"extension":557,"image":558,"meta":559,"navigation":560,"path":561,"seo":562,"stem":563,"__hash__":564},"posts\u002Fblog\u002Fself-hosted-image-transformation-with-repix.md","Self-Hosted Image Transformation with Repix",{"name":7,"avatar":8,"bio":9,"to":10},"Jiten Bansal","\u002Fimages\u002Favatar-filled.png","Fractional CTO and AI consultant.","\u002F",{"type":12,"value":13,"toc":542},"minimark",[14,18,28,33,36,47,58,61,102,113,117,120,190,208,212,215,236,239,265,272,276,289,296,385,404,414,419,422,442,445,449,452,458,464,493,496,500,503,535,538],[15,16,17],"p",{},"Every app that serves user-uploaded photos eventually needs image resizing, cropping, and format conversion. Managed CDNs like Cloudflare Images solve this well — until your traffic grows and the meter starts running.",[15,19,20,27],{},[21,22,26],"a",{"href":23,"rel":24},"https:\u002F\u002Frepix.bansal.io\u002F",[25],"nofollow","Repix"," is a self-hosted image transformation service I built for teams that want URL-based transforms without SDK lock-in or per-request billing. Resize, crop, and convert images on the fly via a simple path pattern. Deploy it once, pay a flat monthly fee, and keep your storage backend hidden behind your own domain.",[29,30,32],"h2",{"id":31},"what-repix-does","What Repix does",[15,34,35],{},"Repix fetches images from any public HTTPS origin and transforms them at request time:",[37,38,43],"pre",{"className":39,"code":41,"language":42},[40],"language-text","https:\u002F\u002Fimg.yourdomain.com\u002Fsm\u002Fcdn.example.com\u002Fphotos\u002Fhero.jpg\n","text",[44,45,41],"code",{"__ignoreMap":46},"",[15,48,49,50,53,54,57],{},"The ",[44,51,52],{},"sm"," preset maps to ",[44,55,56],{},"w=128,q=85",". No SDK, no upload pipeline — just URLs.",[15,59,60],{},"Out of the box you get:",[62,63,64,84,90,96],"ul",{},[65,66,67,71,72,75,76,79,80,83],"li",{},[68,69,70],"strong",{},"Preset system"," — ",[44,73,74],{},"xs"," through ",[44,77,78],{},"xl",", plus ",[44,81,82],{},"full"," and a blur placeholder for LQIP",[65,85,86,89],{},[68,87,88],{},"Modern formats"," — JPEG, PNG, WebP, and AVIF with automatic conversion",[65,91,92,95],{},[68,93,94],{},"Security controls"," — dimension limits, fetch timeouts, preset-only mode, and hostname allowlists",[65,97,98,101],{},[68,99,100],{},"Docker-ready"," — multi-stage Dockerfile, deployable to Render, Railway, Fly.io, or Cloudflare",[15,103,104,105,108,109,112],{},"Your S3 bucket, R2 store, or CDN origin stays invisible. Users see ",[44,106,107],{},"img.yourdomain.com",", not ",[44,110,111],{},"bucket.s3.amazonaws.com",".",[29,114,116],{"id":115},"why-self-host","Why self-host?",[15,118,119],{},"Managed image services are convenient at small scale. Self-hosting wins when you care about predictable costs, control, and portability.",[121,122,123,136],"table",{},[124,125,126],"thead",{},[127,128,129,133],"tr",{},[130,131,132],"th",{},"Benefit",[130,134,135],{},"What it means",[137,138,139,150,160,170,180],"tbody",{},[127,140,141,147],{},[142,143,144],"td",{},[68,145,146],{},"Flat pricing",[142,148,149],{},"One server bill regardless of how many transforms you serve",[127,151,152,157],{},[142,153,154],{},[68,155,156],{},"Your domain",[142,158,159],{},"Image URLs and referrers show your brand, not a third-party CDN",[127,161,162,167],{},[142,163,164],{},[68,165,166],{},"Any origin",[142,168,169],{},"Mix S3, R2, and other HTTPS sources in the same instance",[127,171,172,177],{},[142,173,174],{},[68,175,176],{},"No vendor lock-in",[142,178,179],{},"Move hosts, change presets, or fork the code — it's yours",[127,181,182,187],{},[142,183,184],{},[68,185,186],{},"Abuse controls you own",[142,188,189],{},"Cap dimensions, restrict presets, block slow origins",[191,192,193],"tip",{},[15,194,195,196,199,200,203,204,207],{},"Use ",[44,197,198],{},"ALLOW_CUSTOM_TRANSFORMS=false"," with a tight ",[44,201,202],{},"PRESETS"," config to prevent open-proxy abuse. Pair it with ",[44,205,206],{},"SOURCE_HOSTNAME"," to allowlist only your storage domains.",[29,209,211],{"id":210},"deploy-on-flyio-for-319month","Deploy on Fly.io for $3.19\u002Fmonth",[15,213,214],{},"Repix is a lightweight Node service. A single Fly Machine with 512MB RAM is enough for most personal sites and small SaaS apps.",[15,216,217,218,223,224,227,228,231,232,235],{},"On ",[21,219,222],{"href":220,"rel":221},"https:\u002F\u002Ffly.io\u002Fdocs\u002Fabout\u002Fpricing\u002F#started-fly-machines",[25],"Fly.io's pricing page",", a ",[68,225,226],{},"shared-cpu-1x"," Machine with ",[68,229,230],{},"512MB RAM"," costs ",[68,233,234],{},"$3.19\u002Fmonth"," when running continuously. That's the entire compute bill — no per-transformation surcharge on top.",[15,237,238],{},"A minimal deployment looks like this:",[240,241,242,245,248,260],"ol",{},[65,243,244],{},"Build and push the Repix Docker image (or use the published one)",[65,246,247],{},"Create a Fly app in a region close to your users",[65,249,250,251,253,254,253,257],{},"Set environment variables: ",[44,252,202],{},", ",[44,255,256],{},"IMAGE_MAX_WIDTH",[44,258,259],{},"CORS_ORIGIN",[65,261,262,263],{},"Attach a custom domain like ",[44,264,107],{},[15,266,267,268,271],{},"Repix caches transformed output, so repeated requests for the same preset and source image don't re-run the pipeline. For a blog or product catalog, a 512MB instance handles thousands of daily transforms comfortably. For heavier traffic, scale horizontally — Fly.io lets you run up to ",[68,269,270],{},"5 parallel Machines"," behind the same app.",[29,273,275],{"id":274},"cost-comparison-100000-transformations","Cost comparison: 100,000 transformations",[15,277,278,279,284,285,288],{},"Here's where self-hosting gets interesting. ",[21,280,283],{"href":281,"rel":282},"https:\u002F\u002Fdevelopers.cloudflare.com\u002Fimages\u002Fpricing\u002F",[25],"Cloudflare Images"," charges for ",[68,286,287],{},"unique transformations"," — one image plus one parameter set, counted once per calendar month. Repeat requests for the same combo don't add to the bill.",[15,290,291,292,295],{},"Assume you need ",[68,293,294],{},"100,000 unique transformations per month"," (e.g. 10,000 images × 10 size variants, or a catalog that generates a new crop for each product view).",[121,297,298,309],{},[124,299,300],{},[127,301,302,304,307],{},[130,303],{},[130,305,306],{},"Repix on Fly.io",[130,308,283],{},[137,310,311,324,340,353,368],{},[127,312,313,318,321],{},[142,314,315],{},[68,316,317],{},"Base cost",[142,319,320],{},"$3.19\u002Fmonth (512MB Machine)",[142,322,323],{},"$0 (Free plan) or Paid plan subscription",[127,325,326,331,334],{},[142,327,328],{},[68,329,330],{},"Transform pricing",[142,332,333],{},"Included — unlimited within server capacity",[142,335,336,337],{},"First 5,000 included, then ",[68,338,339],{},"$0.50 \u002F 1,000",[127,341,342,347,350],{},[142,343,344],{},[68,345,346],{},"Billable transforms",[142,348,349],{},"—",[142,351,352],{},"95,000",[127,354,355,360,363],{},[142,356,357],{},[68,358,359],{},"Transform cost",[142,361,362],{},"$0",[142,364,365],{},[68,366,367],{},"$47.50",[127,369,370,375,380],{},[142,371,372],{},[68,373,374],{},"Total (transforms only)",[142,376,377],{},[68,378,379],{},"~$3.19",[142,381,382],{},[68,383,384],{},"~$47.50",[15,386,387,388,391,392,395,396,399,400,403],{},"That's roughly ",[68,389,390],{},"15× cheaper"," for this volume, and the gap widens as transforms grow. At 500,000 unique transforms, Cloudflare Images costs around ",[68,393,394],{},"$247.50\u002Fmonth"," in transformation fees alone. Repix still costs ",[68,397,398],{},"$3.19"," on a single Machine — or run up to ",[68,401,402],{},"5 parallel instances"," for high workload (~$16\u002Fmonth total) — but you're never paying per thousand.",[405,406,407],"note",{},[15,408,409,410,413],{},"Cloudflare's free tier includes 5,000 unique transformations per month. Beyond that, new transforms fail with error ",[44,411,412],{},"9422"," unless you're on the Paid plan. Repix has no monthly transform cap — only the limits you configure.",[415,416,418],"h3",{"id":417},"when-cloudflare-images-still-makes-sense","When Cloudflare Images still makes sense",[15,420,421],{},"Self-hosting isn't always the answer:",[62,423,424,430,436],{},[65,425,426,429],{},[68,427,428],{},"Under 5,000 unique transforms\u002Fmonth"," — Cloudflare's free tier costs nothing",[65,431,432,435],{},[68,433,434],{},"You want zero ops"," — no Machines to monitor, no Docker deploys",[65,437,438,441],{},[68,439,440],{},"Global edge caching built in"," — Cloudflare's network is hard to replicate on a single Fly region",[15,443,444],{},"But if you're consistently above the free tier — especially past 20,000–50,000 unique transforms — a $3.19 Fly Machine running Repix is the better economics.",[29,446,448],{"id":447},"clean-urls-with-presets","Clean URLs with presets",[15,450,451],{},"One of Repix's best features is readable URLs. Compare:",[37,453,456],{"className":454,"code":455,"language":42},[40],"# Clean — preset name\nhttps:\u002F\u002Fimg.yourdomain.com\u002Fcard\u002Fcdn.example.com\u002Fphoto.jpg\n\n# Verbose — inline parameters\nhttps:\u002F\u002Fimg.yourdomain.com\u002Fw=400,h=300,fit=cover,f=webp,q=85\u002Fcdn.example.com\u002Fphoto.jpg\n",[44,457,455],{"__ignoreMap":46},[15,459,460,461,463],{},"Define your own presets in the ",[44,462,202],{}," env var:",[37,465,469],{"className":466,"code":467,"language":468,"meta":46,"style":46},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","PRESETS='{\"thumb\":\"w=200,h=200,fit=cover\",\"card\":\"w=400,h=300,fit=cover\",\"hero\":\"w=1200,h=600,fit=cover\"}'\n","bash",[44,470,471],{"__ignoreMap":46},[472,473,476,479,483,486,490],"span",{"class":474,"line":475},"line",1,[472,477,202],{"class":478},"sTEyZ",[472,480,482],{"class":481},"sMK4o","=",[472,484,485],{"class":481},"'",[472,487,489],{"class":488},"sfazB","{\"thumb\":\"w=200,h=200,fit=cover\",\"card\":\"w=400,h=300,fit=cover\",\"hero\":\"w=1200,h=600,fit=cover\"}",[472,491,492],{"class":481},"'\n",[15,494,495],{},"Short names in templates, full control in configuration.",[29,497,499],{"id":498},"getting-started","Getting started",[15,501,502],{},"Repix is open source and ready to deploy:",[62,504,505,515,525],{},[65,506,507,510,511],{},[68,508,509],{},"Docs and presets",": ",[21,512,514],{"href":23,"rel":513},[25],"repix.bansal.io",[65,516,517,510,520,524],{},[68,518,519],{},"Deploy target",[21,521,523],{"href":220,"rel":522},[25],"Fly.io Machines pricing"," — $3.19\u002Fmonth for 512MB",[65,526,527,510,530,534],{},[68,528,529],{},"Comparison baseline",[21,531,533],{"href":281,"rel":532},[25],"Cloudflare Images pricing"," — $0.50 per 1,000 unique transforms after the first 5,000",[15,536,537],{},"If your image pipeline is quietly costing more than your app server, it's worth running the numbers. A self-hosted transform layer might be the cheapest upgrade you make this year.",[539,540,541],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":46,"searchDepth":543,"depth":543,"links":544},2,[545,546,547,548,552,553],{"id":31,"depth":543,"text":32},{"id":115,"depth":543,"text":116},{"id":210,"depth":543,"text":211},{"id":274,"depth":543,"text":275,"children":549},[550],{"id":417,"depth":551,"text":418},3,{"id":447,"depth":543,"text":448},{"id":498,"depth":543,"text":499},"Infrastructure","2026-07-06","Run Repix on Fly.io for $3.19\u002Fmonth and skip per-transformation fees. A cost comparison with Cloudflare Images at 100,000 transforms.","md",null,{},true,"\u002Fblog\u002Fself-hosted-image-transformation-with-repix",{"title":5,"description":556},"blog\u002Fself-hosted-image-transformation-with-repix","B9TKEitoifTtTs77O46tVMkFAA8eLda_U7QOz3Q4sA0","Every app that serves user-uploaded photos eventually needs image resizing, cropping, and format conversion. Managed CDNs like Cloudflare Images solve this well — until your traffic grows and the meter starts running.\n\n[Repix](https:\u002F\u002Frepix.bansal.io\u002F) is a self-hosted image transformation service I built for teams that want URL-based transforms without SDK lock-in or per-request billing. Resize, crop, and convert images on the fly via a simple path pattern. Deploy it once, pay a flat monthly fee, and keep your storage backend hidden behind your own domain.\n\n## What Repix does\n\nRepix fetches images from any public HTTPS origin and transforms them at request time:\n\n```text\nhttps:\u002F\u002Fimg.yourdomain.com\u002Fsm\u002Fcdn.example.com\u002Fphotos\u002Fhero.jpg\n```\n\nThe `sm` preset maps to `w=128,q=85`. No SDK, no upload pipeline — just URLs.\n\nOut of the box you get:\n\n- **Preset system** — `xs` through `xl`, plus `full` and a blur placeholder for LQIP\n- **Modern formats** — JPEG, PNG, WebP, and AVIF with automatic conversion\n- **Security controls** — dimension limits, fetch timeouts, preset-only mode, and hostname allowlists\n- **Docker-ready** — multi-stage Dockerfile, deployable to Render, Railway, Fly.io, or Cloudflare\n\nYour S3 bucket, R2 store, or CDN origin stays invisible. Users see `img.yourdomain.com`, not `bucket.s3.amazonaws.com`.\n\n## Why self-host?\n\nManaged image services are convenient at small scale. Self-hosting wins when you care about predictable costs, control, and portability.\n\n\u003Ctable>\n\u003Cthead>\n  \u003Ctr>\n    \u003Cth>\n      Benefit\n    \u003C\u002Fth>\n    \u003Cth>\n      What it means\n    \u003C\u002Fth>\n  \u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Flat pricing\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      One server bill regardless of how many transforms you serve\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Your domain\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      Image URLs and referrers show your brand, not a third-party CDN\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Any origin\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      Mix S3, R2, and other HTTPS sources in the same instance\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        No vendor lock-in\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      Move hosts, change presets, or fork the code — it's yours\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Abuse controls you own\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      Cap dimensions, restrict presets, block slow origins\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n::tip\nUse `ALLOW_CUSTOM_TRANSFORMS=false` with a tight `PRESETS` config to prevent open-proxy abuse. Pair it with `SOURCE_HOSTNAME` to allowlist only your storage domains.\n::\n\n## Deploy on Fly.io for $3.19\u002Fmonth\n\nRepix is a lightweight Node service. A single Fly Machine with 512MB RAM is enough for most personal sites and small SaaS apps.\n\nOn [Fly.io's pricing page](https:\u002F\u002Ffly.io\u002Fdocs\u002Fabout\u002Fpricing\u002F#started-fly-machines), a **shared-cpu-1x** Machine with **512MB RAM** costs **$3.19\u002Fmonth** when running continuously. That's the entire compute bill — no per-transformation surcharge on top.\n\nA minimal deployment looks like this:\n\n1. Build and push the Repix Docker image (or use the published one)\n2. Create a Fly app in a region close to your users\n3. Set environment variables: `PRESETS`, `IMAGE_MAX_WIDTH`, `CORS_ORIGIN`\n4. Attach a custom domain like `img.yourdomain.com`\n\nRepix caches transformed output, so repeated requests for the same preset and source image don't re-run the pipeline. For a blog or product catalog, a 512MB instance handles thousands of daily transforms comfortably. For heavier traffic, scale horizontally — Fly.io lets you run up to **5 parallel Machines** behind the same app.\n\n## Cost comparison: 100,000 transformations\n\nHere's where self-hosting gets interesting. [Cloudflare Images](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fimages\u002Fpricing\u002F) charges for **unique transformations** — one image plus one parameter set, counted once per calendar month. Repeat requests for the same combo don't add to the bill.\n\nAssume you need **100,000 unique transformations per month** (e.g. 10,000 images × 10 size variants, or a catalog that generates a new crop for each product view).\n\n\u003Ctable>\n\u003Cthead>\n  \u003Ctr>\n    \u003Cth>\n    \u003C\u002Fth>\n    \u003Cth>\n      Repix on Fly.io\n    \u003C\u002Fth>\n    \u003Cth>\n      Cloudflare Images\n    \u003C\u002Fth>\n  \u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Base cost\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      $3.19\u002Fmonth (512MB Machine)\n    \u003C\u002Ftd>\n    \u003Ctd>\n      $0 (Free plan) or Paid plan subscription\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Transform pricing\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      Included — unlimited within server capacity\n    \u003C\u002Ftd>\n    \u003Ctd>\n      First 5,000 included, then \u003Cstrong>\n        $0.50 \u002F 1,000\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Billable transforms\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      —\n    \u003C\u002Ftd>\n    \u003Ctd>\n      95,000\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Transform cost\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      $0\n    \u003C\u002Ftd>\n    \u003Ctd>\n      \u003Cstrong>\n        $47.50\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cstrong>\n        Total (transforms only)\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      \u003Cstrong>\n        ~$3.19\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      \u003Cstrong>\n        ~$47.50\n      \u003C\u002Fstrong>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\nThat's roughly **15× cheaper** for this volume, and the gap widens as transforms grow. At 500,000 unique transforms, Cloudflare Images costs around **$247.50\u002Fmonth** in transformation fees alone. Repix still costs **$3.19** on a single Machine — or run up to **5 parallel instances** for high workload (~$16\u002Fmonth total) — but you're never paying per thousand.\n\n::note\nCloudflare's free tier includes 5,000 unique transformations per month. Beyond that, new transforms fail with error `9422` unless you're on the Paid plan. Repix has no monthly transform cap — only the limits you configure.\n::\n\n### When Cloudflare Images still makes sense\n\nSelf-hosting isn't always the answer:\n\n- **Under 5,000 unique transforms\u002Fmonth** — Cloudflare's free tier costs nothing\n- **You want zero ops** — no Machines to monitor, no Docker deploys\n- **Global edge caching built in** — Cloudflare's network is hard to replicate on a single Fly region\n\nBut if you're consistently above the free tier — especially past 20,000–50,000 unique transforms — a $3.19 Fly Machine running Repix is the better economics.\n\n## Clean URLs with presets\n\nOne of Repix's best features is readable URLs. Compare:\n\n```text\n# Clean — preset name\nhttps:\u002F\u002Fimg.yourdomain.com\u002Fcard\u002Fcdn.example.com\u002Fphoto.jpg\n\n# Verbose — inline parameters\nhttps:\u002F\u002Fimg.yourdomain.com\u002Fw=400,h=300,fit=cover,f=webp,q=85\u002Fcdn.example.com\u002Fphoto.jpg\n```\n\nDefine your own presets in the `PRESETS` env var:\n\n```bash\nPRESETS='{\"thumb\":\"w=200,h=200,fit=cover\",\"card\":\"w=400,h=300,fit=cover\",\"hero\":\"w=1200,h=600,fit=cover\"}'\n```\n\nShort names in templates, full control in configuration.\n\n## Getting started\n\nRepix is open source and ready to deploy:\n\n- **Docs and presets**: [repix.bansal.io](https:\u002F\u002Frepix.bansal.io\u002F)\n- **Deploy target**: [Fly.io Machines pricing](https:\u002F\u002Ffly.io\u002Fdocs\u002Fabout\u002Fpricing\u002F#started-fly-machines) — $3.19\u002Fmonth for 512MB\n- **Comparison baseline**: [Cloudflare Images pricing](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fimages\u002Fpricing\u002F) — $0.50 per 1,000 unique transforms after the first 5,000\n\nIf your image pipeline is quietly costing more than your app server, it's worth running the numbers. A self-hosted transform layer might be the cheapest upgrade you make this year.\n",[558,558],1783327614747]