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/serveris the Worker: your server code and the pages rendered on demand. This is what the size limit measures.dist/clientis 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.
