Closed ivands closed 2 years ago
More thinking happened. If we could just do SSR on the edge we wouldn't need API Gateway anymore. Plus we would get the additional speed benefit that the edge provides.
Both options seem like an upgrade to me. (Going fully on the edge is a lot cheaper tho)
I am trying to get this to work on the edge with this package.
I have a CloudFront instance that has 1 origin (S3 bucket with all the static files). I've attached an edge lambda (origin-response) that checks if the request is found on the origin or else execute the SSR code and return that as a response. The problem is that I cannot get the SSR code (serverless.js) to work.
I hope you understand the logic behind this and maybe can help me try to get this working.
(An upgrade to this solution is to get SSR working on the origin-request edge function)
Hi @MicMonen Do you have any logs of any errors your seeing that i could take a look at? Could you try hitting the SSR API gateway directly, and seeing if you get back the expected response?
Hi @ivands Thank You very much for your suggestions.
I disagree with your assertion that SSR pages cannot be cached, this is quite common practice and in fact it's probably more advantages to cache SSR content vs static content as there is not only a transfer cost associated with generated data, but also a time and monetary cost associated with rendering the page. I cache SSR pages for my personal blog using this adapter. I have a long cache on all the blog pages, then when a blog post is added or updated I programmatically invalidate the cache on specific paths.
I Considered all these options when developing the initial solutions before coming up with my final design, below are the Pros and Cons of each approach so i hope you get a understanding of the tradeoffs I had to consider. I have highlighted in bold the deal breaker for me with the 2 rejected options.
Pros
Hi @yarbsemaj,
Let me just be clear about the caching point. When I say "cache" I'm talking about the CloudFront CDN cache. This package can't set default caching headers for SSR pages because not every SSR page can be cached. However static content from s3 can always be cached. (And because s3 content can be cached some of your points are incorrect).
I hope you see why using this hybrid approach doesn't add any real benefit other than unlimited file size.
Hi @ivands Thank You for you comment, I thought I would do the maths on SSR at the edge just to be sure (TBH id not done it before) I just assumed it would be more expensive. I can confirm it is quite a bit more expensive (nearly 2x or more depending on how long it takes to process your page). Below are my calculations.
A few notes.
On Serve everything from a Lambda; It's not true to say Cloudfront will only hit the lambda once, I should only hit it once per edge node but there are many nodes in the network (and thus many request). AWS will also
uncache
infrequently accessed object according to my research. For example, with my blog I cache aggressively, yet only have a cache hit rate of 40% ish over a month. I think on balance from a cost perspective it's probably cheaper to go this route however as long as you're not serving any objects larger that 6MB. However when you take into account the cost of Cloudfront transfer out the price difference is marginal. For example, assume there was 0 cost associated with serving files from lambda and you were serving 1M request, 100 kilobytes each, all to the US or EU. If you combine the cost of that ($8.11) with the cost serving those request from your non cached infra it turns out the edge lambda is only around 5.4% of your cost. In reality this percentage will be significantly less because most request would be served from cache so your only paying transfer on those, not for any computation. For example with my rather mediocre cache hit rate of 40% that percentage drops to 2.6%
Don't get me wrong, those are still gains but the goal with the project is to make something that "just works" and I can see someone building something and including a video or large image in there public folder and then wondering why its not working when they go to deploy, I know you shouldn't do this, but people will.
Im very tawn on this and once sveltekit leaves alpha I may revisit this at a later date.
I'm not sure if I agree that the current hybrid version is cheaper. But I should run some tests myself.
On a different note: We have some good news 🥳: Lambda Function Urls are here. https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html
And it seems you can return any type of HTTP response. So this should eliminate the need for ApiGateway and reduce the cost of your hybrid version even more. 🎉
Hi @ivands Thank You so much for the update! I have just published a new version v0.8.0 that adds support for this. If you look at the commit history you will see the small update you need to make to your serverless.yml file. (as well updating the the latest version of the serverless framework)
I've been thinking more about improving the costs of the system, and I think it's probably best to remove the lambda edge router. The edge router is used to tell CloudFront to get the static files from s3. The problem however is that lambda edge is expensive and will now be triggered for every missed cache hit. And because SSR pages can't be cached we trigger the lambda edge function for no reason. Plus we don't gain any speed benefit by using the edge because SSR is still happening on a normal lambda function.
We could just move the lambda edge router functionality to the normal lambda that is doing SSR right now. The lambda just needs to get the static assets from s3 when necessary and return it with proper caching headers for CloudFront. If the request isn't for a static asset we just do the normal SSR stuff.
This approach should reduce costs even more. What do you think?