Serve fallback image instead of 404 from r2
I'm using R2 to serve user avatars. If no avatar exists in the bucket for the given user ID, I'd like to return a default avatar as the 404 response. Is there any way to do this without using workers?
23 Replies
I don’t believe there’s any way to do this outside of Workers
As a side note, just curious, is there a reason you woudn't want to use workers for this scenerio?
Costs, I would imagine
^^
We are doing this for user avatars, which get millions of loads. Also it just feels wrong to put compute in front of a bucket to change the server's 404 response
... I reluctantly put up a worker 😂
Well, If i was to implement, I would use Workers KV in-betwee to avoid going to R2 each time to check.
Don’t know what your client code looks like but you could have it make a second request to the default user icon if the user specific one returns a 404
KV is more expensive than R2 so thats not going to help
Embed default avatar in Worker base64 encoded, use Cache (or a library like kotx/render to handle it for you) when getting the R2 Object/Image, if nothing return the default avatar. Wouldn't be too bad
render even has the 404 behaviour as a native feature :) you can just do
NOTFOUND_FILE = "404.png"
oh does it? That's nice, would still be another R2 GET though I assume, whereas embedding it would be free (although a bit silly/limits you on size)
Oh yeah for sure :P
I also dont know if we cache 404s in render, I wrote the feature but I dont remember
This is my very naive worker implementation for serving avatars with a fallback. Is there a material perf/cost penalty to just using fetch vs getting from the bucket directly? (FWIW both the bucket itself and the worker have aggressive cache rules)
Not sure I understand though, why aren’t you using an R2 Binding?
the simple answer is I haven't (yet) taken the time to understand them. That's probably the better call, but to get things going quickly I was basing this on https://www.mickaelvieira.com/blog/2020/01/27/custom-404-page-with-cloudflare-workers.html
we have no other workers and this was just my quick and dirty attempt to get custom 404 responses
Mickaël Vieira
Custom 404 page with Cloudflare Workers - Mickaël Vieira - Software...
Hijacking 404 errors and returning a custom 404 page with Cloudflare Workers
That said I'm open to learning if you think it would be value add
One thing is that you can make it so that your R2 bucket isn't publicly available
If that matters to you
Since these are public user avatars it's ok (intentional) to be publicly accessible, but mainly concerned about cost and perf. This worker will see millions of requests a day next month and want to brace myself 😂
No, I mean that, do you need the bucket to be publicly available without your Worker in front?
Not necessarily, but it's not a deal breaker either way
(ty for looking by the way)
It could be something as simple as this:
You would just need to set up the bindings, and add a bundling rule for
webp
files
Then you also don't get billed twice when a user avatar doesn't existI don't know your back-end, but wouldn't it be a lot cheaper if you just store a boolean in your database to see if the user has an avatar or not. Also, if your user will get an avatar, the cache will probably still show the default avatar.
The code above specifically doesn't add cache headers to fallback images, if that's it