DEV Community

Henrik
Henrik

Posted on

The zero-egress trick that lets me give away a media tool for free

I run a small free tool called imgi. You drop in two images, drag a slider to compare them, and get a permanent link to paste anywhere. Before and after shots, mostly: a photo edit against the untouched shot, a game mod next to vanilla, an AI upscale against the source file.

Here's what nobody warns you about when you build one of these. The hard part isn't the slider. It's the bandwidth bill.

Every viewer who opens a comparison pulls down two full-resolution images. One link that catches on, a few thousand views, and you're pushing gigabytes out the door. On most cloud storage the egress is what gets you. AWS S3 charges about $0.09 per GB to send data out, and storage itself runs around $0.023/GB a month, so holding onto the file is cheap and handing it to people over and over is where the meter actually runs.

Run the numbers on something that's supposed to be free and shareable. A single before/after pair might be 8MB. Ten thousand views is 80GB leaving the building, call it seven bucks for one link. Feels like nothing until a few comparisons actually spread and you're looking at hundreds of them. That's the quiet reason a lot of free image tools bolt on limits, or drown the page in ads, or just disappear one morning after the founder finally does the math. imgsli, the before/after tool a ton of people leaned on for years, went offline a while back. I don't know their reasons and I won't invent them. But I recognize the shape of the problem, because I stared at the same spreadsheet before I wrote a line of code.

The one line item that changes everything

The fix that made imgi viable is boring, and it's the whole game: Cloudflare R2 doesn't charge for egress. Zero dollars per GB out, no asterisk. You pay for storage (about $0.015/GB a month, a hair under S3) and for operations, and then serving the bytes is free no matter how far a link travels. That 80GB comparison that would've cost me seven dollars on S3 costs me nothing to hand out. Cloudflare's own comparison puts a 20TB-a-month media workload at over $1,700 in S3 egress versus basically storage-only on R2.

Once the egress line reads $0, I can say "free forever, links that don't rot" and actually mean it, rather than it being the kind of promise that gets walked back in eighteen months when the invoice starts to sting.

The rest of the stack

Everything else sits on the same platform so I'm not paying for a server that idles at 3am:

  • Next.js on the App Router, but deployed to Cloudflare Workers through @opennextjs/cloudflare instead of a Node box. The SSR runs at the edge.
  • R2 for the image bytes.
  • D1, Cloudflare's SQLite, for the little scrap of metadata each comparison needs: the short ID, which two R2 keys it points at, the labels on each side.
  • Workers Analytics Engine to count views without a cookie or a third-party script.

The gotcha that cost me an afternoon

On Workers you're billed and rate-limited per request, and the obvious setup routes every image fetch through the Worker. That's one invocation per image, per viewer. It piles up fast enough to trip limits during a spike, which is exactly when you don't want your site falling over. So the images serve straight off R2's own path now, and a view doesn't wake the Worker for each file it needs. The Worker just handles the page and the routing; the actual image bytes never touch it. If you build anything media-heavy on Workers, sort that split out early, ask me how I know.

The slider, since that's what you came for

Two images stacked in the same box, identical dimensions, absolutely positioned so they overlap pixel for pixel. The top one gets clipped and you drag the clip edge across. No canvas and no library, nothing re-rendering on every frame either. Pointer events cover mouse and touch, arrow keys cover the people who'd rather not touch a mouse, and a little care keeps it from fighting the page scroll on a phone. That's most of it, honestly. Which is why it still feels a bit funny that the slider is the part everyone asks about, when it was the easy bit.

One detail I do care about: every image comes back byte-for-byte identical to what went up. No silent recompression. Plenty of hosts squeeze your file to save on, you guessed it, storage and bandwidth. When the whole job of the tool is judging fine detail in an upscale or a retouch, a quietly crushed image ruins the point. Because R2 isn't charging me for the bytes, I don't have to touch them.

Why I bothered writing this

You can go poke at imgi.co if you want, no signup, and there's an offline mode that runs the comparison entirely in your browser without uploading a thing. Mostly though I typed this up for the R2 point. The tool is just where I happened to run into it. If you've got a side project that dies on the spreadsheet the second you price the bandwidth, go re-price it against zero egress. A whole category of "too expensive to give away" ideas quietly comes back to life.


Sources for the pricing figures: Cloudflare R2 vs S3.

Top comments (0)