Image/file caching? Is there any caching for files on a CDN?
Looking to improve some image load times and was wondering if there's any caching going on.
I'm also considering caching locally w/ NextJS Image and/react native fast image.
18 Replies
there isn't yet, but we have future plans to tie Convex's existing read-only query cacheability semantics with things like storage fetches (which also have no side effects) so that you get CDN-type benefits from every bit of data inside Convex. this will possibly power an automatically cached server-side rendering solution as well. this isn't implemented yet, so images currently come straight from S3 every time and are slower than we'd like
There are some browser cache headers set, so a given user shouldn’t have to download it twice. However, if you’re returning it from an httpAction you’ll have to set those cache headers yourself.
One thing I’ve done for carousel type usecases is to preload the images by creating image tags in js, so they can be downloading before they’re shown to the user.
Just wanted to check on this!
I'm about to build out asset features in the project I'm building and I wanted to know the pro's and con's (and roadmap) for file storage before I double down on hosting it in Convex:
- Image optimization
- CDN support
- File limitations (I'll be rendering and storing video)
1. We don't have any built-in image optimization
2. The performance currently (from the storage url directly) is comparable to serving from an S3 bucket.
3. Uploading directly to a storage url can support gigabytes, but currently for an HTTP action the request/response size is limited to 20MB. For video streaming I'm assuming you'll be using chunks like HLS or similar, so each chunk should be fine being sent via URL or HTTP action. If it's one big file you'd want to stick to the storage URLs.
Make sense?
If the built-in storage doesn't work, I'd suggest using a third party to store and serve content, and do the business logic & authorization in Convex
If you do end up with a different provider let us know what their benefits were, thanks!
Quick question on
ctx.storage.getUrl
- is that URL permanent or timed?
As in, can I persist it?@nipunn ^
generateUploadUrl
is timed. getUrl
gives a url that is permanent.
https://docs.convex.dev/api/interfaces/server.StorageWriter#generateuploadurl
Note to self - it would be good if the getUrl docs documented this!
https://docs.convex.dev/api/interfaces/server.StorageWriter#geturlInterface: StorageWriter | Convex Developer Hub
server.StorageWriter
We have a product roadmap plan to support timed URLs for get (similar to getPresignedUrl in S3), but haven't prioritized that work.
Hopefully that helps. I believe you should be able to persist the urls generated by
getUrl
. If you take a look, it should just be {origin}/api/storage/{storage_id}
.One other thing to note - is that you can write an HTTP Action that gets the file - and then you can have whatever URL you want with whatever conditional logic inside that you want. This is documented here https://docs.convex.dev/file-storage/serve-files#serving-files-from-http-actions
Serving Files | Convex Developer Hub
Files stored in Convex can be served to your users by generating a URL pointing
Great! Thank you for that
Is there any progress on this issue? Reading images from storage is very slow in most scenarios. I can use an external tool, but convex needs a smart cdn solution like supabase.
it's blocked on the general components framework. pretty easy to build once that's out
first version of that is 1-2 months away
It comes ahead of our project's release schedule. I'm looking forward to.
Are you currently storing smaller image resolutions for serving? Is it slower than S3, or what is the benchmark for "slow" here? One of the big benefits of a hosted image solution is just that they downsample images, so they don't have to serve as much data. If you store a smaller resolution in Convex when you're uploading it and serving, I wonder whether that'd be sufficient? Yes CDNs can have a physically closer cache, but slow client networks are mostly in the SSL termination hop, so minimizing data I think is higher leverage.
Performance comparison where the same image is presented via both azure cdn, convex and Supabase (for Türkiye)
I cannot share the file link directly from Azure S3, it is closed to the end user.
Tests were performed with the browser cache turned off.
----------------------
Convex Storage
https://opulent-dalmatian-773.convex.cloud/api/storage/6678134b-2ac3-45e1-bad8-d88e1139d430
Time: 830ms
----------------------
Azure S3 => Azure Cdn
https://cdn3.hipicon.com/images/bd/products/2024/05/15/edizione-living--ayakl-seramik-servis--171577197812370.jpg
Time: 77ms
----------------------
Supabase Storage
https://ghwkjyyrykhxrclbjcaf.supabase.co/storage/v1/object/public/test/edizione-living--ayakl-seramik-servis--171577197812370.jpg
Time: 86ms
----------------------
In this scenario, I do not need to make a more detailed comparison, because it is impossible not to understand that the photos are loaded late in terms of user experience.
And in our new project, each photo will largely be shown to the user only once. (tinder-like). Therefore, browser caching will not solve our problem.
I don't know how supabase solves this technically, but I think it is a place that should be taken as an example.
The problem with Supabase is that image transformations are extremely expensive.
(100 origin images included
then $5 per 1000 origin images) It is impossible to overcome the cost, especially for e-commerce or image-based applications.
(I added image transformations as a note, I assume you don't have a priority)
Thanks for that! I suspect the cost of their image transformations may be covering their CDN bill. I just tested (from my nice wifi in SF, California) and saw very different results, which I think points to the effect of the CDN here. Agree the images are all the same size.
With Components it'll be easier to build abstraction layers like:
- Add an image and have it generate and store different resolutions (will likely require hosting / paying for an image resizing service, or running them in a serverless environment like Convex node actions if memory and tooling suffices)
- Push new versions and resolutions of assets to a CDN of your choosing.
Later Convex may also offer more networking features baked in, like a CDN in front of file storage (like Supabase seems to do), but for now you can use an existing CDN and just connect it to your Convex data using code you write or libraries. Does that make sense/ meet your needs?
Since we do not have any urgency until the publication of our app, we will follow the developments on convex. If there is no improvement in convex until the publication process, then we will try external cdn solutions as you said. We will continue to use convex as the main storage.
Thanks.