A light crate with a gear inside sits on a scale that barely moves, next to a separate tall shelf full of framed pictures.
Astro & web· 3 min read

Images don't count toward the Cloudflare Worker size limit

Images in an Astro site on Cloudflare Workers ship as static assets, not inside the Worker. What I measured, which limits apply, and what images still cost.

Today I was getting my blog ready for cover images on Cloudflare Workers, and one thing worried me: the images live in the repo, right next to the posts. I remembered the Worker size limit as 10 MB, and a few screenshots would fill that fast. So I built the site with and without images and compared.

Images don’t count toward the Worker size limit at all. Astro puts them in static assets, which Cloudflare stores and serves separately from the Worker’s code. And the limit itself is 64 MiB uncompressed now, not 10 MB.

The short version: images never enter the Worker, so the Worker size limit ignores them.

  • Measured: adding two 2 MB images left the Worker at 1.3 MB, while static assets grew from 1.6 MB to 6.5 MB.
  • The limits that apply: 25 MiB per file and 100,000 files per deploy on the paid plan (20,000 on free).
  • What images still cost: Astro ships your originals next to the WebP versions it generates, and every image stays in git forever. Convert them before you commit.

Where images go when Astro builds for Workers

The Cloudflare adapter splits the build in two folders:

  • dist/server is the Worker: your server code and the pages rendered on demand. This is what the size limit measures.
  • dist/client is static assets: prerendered pages, CSS, fonts and every image. Wrangler uploads these on their own, and Cloudflare serves them without loading your Worker code.

An image you import or reference from Markdown ends up in dist/client/_astro/, as the original file plus the resized WebP versions Astro generates for it.

What I measured

I built my blog twice: once as it is, once with a test post holding two PNGs of 2.5 MB and 2.1 MB, one as the cover and one inside the text.

npm run build
du -sh dist/server dist/client
Build dist/server (Worker) dist/client (static assets)
Without the images 1.3 MB 1.6 MB
With the images 1.3 MB 6.5 MB

The Worker didn’t change by a byte that du could see. Almost all of the 4.9 MB growth is the two original PNGs, copied as they are. The WebP versions Astro made were small: the cover came out at 11 KB to 161 KB depending on width.

Which limits apply?

From Cloudflare’s Workers limits page:

Limit Free Paid
Worker size (uncompressed) 64 MiB 64 MiB
Files per Worker version 20,000 100,000
Size of one static file 25 MiB 25 MiB

There is no compressed size limit anymore, only the uncompressed one. The 100,000 files need Wrangler 4.34.0 or newer.

Astro makes several files per image (the original plus one WebP per width it needs), so count a few files per image when you estimate. Even at five per image, 20,000 files is thousands of images.

Shrink images before you commit them

What images do cost is repo size. Every screenshot you commit stays in git history forever, and the original ships to production next to the optimized versions.

I convert covers and screenshots to WebP before they go in the post folder:

cwebp -q 82 -resize 1600 0 screenshot.png -o screenshot.webp

The cover on this post is an 80 KB WebP, 1600 pixels wide. Astro still makes its smaller versions from it, but the file that ships and the file that sits in git are both small.

If you get to video, or to files over 25 MiB, that’s when R2 makes sense. For a blog’s images, static assets are enough.

Also in

Română

Get my new posts by emailWant to hear when I write the next one?

I send at most one email a week, and only when there’s something new on the site. No new posts, no email. No spam, and you can unsubscribe with one click.Thanks for reading! Leave your email and I’ll write to you at most once a week, only when there’s something new. No spam, one click to unsubscribe.

Just your email. One click to unsubscribe. Privacy