aws-amplify / amplify-hosting

AWS Amplify Hosting provides a Git-based workflow for deploying and hosting fullstack serverless web applications.
https://aws.amazon.com/amplify/hosting/
Apache License 2.0
459 stars 116 forks source link

Feature request: Option to disable caching based on cookies #2243

Open xiaoxiaosaohuo opened 3 years ago

xiaoxiaosaohuo commented 3 years ago

Before opening, please confirm:

App Id

dilkdnzrxxk9k

Region

us-east-1

Amplify Console feature

Performance

Describe the bug

I have enable the performance mode, and configure the custom headers in customHttp.yml, my page sometimes is too slow, when miss cloudfront, the TTFB almost is 1s-2s, when I access the page in chrome browser it always Miss from cloudfront, however, while I access in PostMan, it hit the cloudfront , then I access it in the command line with curl, the first time ,it shows miss from cloudfront,the others times show hit from cloudfront. I don't know why they are so different, if the page is on CDN edge location, why I access it in postman ,and then access it in command line ,it shows miss from cloudfront? .

I think it should hit the cloudfront after I access it, and I don't know the browser why always miss from cloudfront?

I need your kind help, thank you!

Expected behavior

After I access the page , it should hit cloudfront , whether I use browser or the curl

Reproduction steps

no steps

Build Settings

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - nvm install 16
        - nvm use 16
        - npm install
    build:
      commands:
        - npm run export

  artifacts:
    baseDirectory: __sapper__/export
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

Additional information

customHeaders:
  - pattern: '**/*[!.html]'
    headers:
      - key: Cache-Control
        value: 'public,max-age=31536000,s-maxage=31536000,immutable'
  - pattern: '**/*'
    headers:
      - key: 'X-Frame-Options'
        value: 'SAMEORIGIN'
      - key: 'X-Content-Type-Options'
        value: 'nosniff'
      - key: 'X-XSS-Protection'
        value: '1; mode=block'
      - key: 'Strict-Transport-Security'
        value: 'max-age=31536000; includeSubDomains'
xiaoxiaosaohuo commented 3 years ago

I find the cookie of the domain--.amplifyapp.com always change when the page refresh, this maybe the main problem which cause the cache invalidation, but, how to solve this ?

JKalm commented 3 years ago

Hi @xiaoxiaosaohuo, Your observation is correct, Amplify uses cookies as part of caching key in CloudFront, this behavior currently cannot be changed.

But you should have control over what cookies are used on your website. I checked your app and it seems that it has _ga cookies that are different on every page load. After I disabled cookies on website I was able to see x-cache: Hit from cloudfront header in response.

xiaoxiaosaohuo commented 3 years ago

@JKalm ๏ผŒthanks , some cookie will change, but I want to cache my page on CloudFront, so, I think Amplify should provide a method to control this by user. I use Google Analytics in my page, its cookie would change on every page load, I can't handle this even I set the cookie_update:false. and when I miss from CloudFront, the page'TTFB will cost 1s-2s, does this have something to do with the region of deployment?

ShahAnuj2610 commented 3 years ago

Hey, @JKalm @xiaoxiaosaohuo did you find any solution to control cookie caching in AWS amplify? We're facing the same issue where if cookie changes were getting a miss from CloudFront.

xiaoxiaosaohuo commented 3 years ago

@ShahAnuj2610 , sorry, amplify don't give the user more control on CloudFront

ferdingler commented 3 years ago

Hi @xiaoxiaosaohuo, @ShahAnuj2610, I have renamed this ticket to make it a formal feature request. Unfortunately at this moment the default behavior is to cache based on Cookies so if the cookie changes, there will be a Cache Miss.

xavierraffin commented 2 years ago

+1 on this

utsavbshah commented 1 year ago

+1 on this

Atsushi570 commented 1 year ago

+1 on this

engineer-matsuo commented 1 year ago

What happened to the issue here? Does it mean that the specification does not allow to combine Google Analytics and cache? Since cloudfront used to have a whitelist for detailed settings, is it possible to incorporate that functionality?

nickfujita commented 1 year ago

+1 on this, as it seems anyone using Amplitude will also run into this issue since it sets a cookie header for each user. With the current solution cloudfront result in cache HITs if the same user is accessing a site multiple times, but prevents the cache from being useful for more than one user.

Currently using Amplify for a nextjs site, and even though Amplify results in x-nextjs-cache HITs, this is still very slow for some reason, but cloudfront cache HITs are very fast. Would love to be able to make the cloudfront cache set with performance mode and customHTTP.yml actually useful. ๐Ÿ™๐Ÿผ

Can you please add the ability to customize control over cloudfront cache key, like is available for cloudfront without amplify?

webdevcody commented 1 year ago

This seems like a critical thing that needs to be fixed. I want google analytics on my site, but this is basically making the cloudfront cache unusable and causing a lot more amplify hosting compute charges since every new user session is basically re-downloading all the static assets. Additionally, I am using next-auth for my logged-in users which would mean all authenticated users would NOT get the caching benefit of cloudfront due to this issue. From what I read, cloudfront does NOT use cookies by default for it's cache key. Why does amplify override the defaults that cloudfront speak about in the documentation?

raffclar commented 1 year ago

We have large cookies that we're unable to change on our site. Our request header sizes are too large for S3. Having this feature would save us weeks of work and testing.

alienngator commented 1 year ago

Bump. Our app serves a lot of images, none of which is getting any caching benefit. Cookies are unavoidable and can't be hacked around. It's frustrating that Amplify overrides the Cloudfront defaults without providing an alternative.

We're seriously considering migrating away from Amplify hosting because of this.

nrsmarterlaunch commented 1 year ago

Same here, was just tracking down why we aren't getting any cache hits for CloudFront, compared the cookies being sent, Google Analytics cookie changes on every page load...

henlars commented 1 year ago

I tried the aproach to wrap another Cloudfront around the Amplify cloudfront and it seems to work. I got the idea from this https://awstip.com/nextjs-aws-amplify-cloudfront-cache-it-real-good-1211466cecfd. What do you think about this? Any downsides?

andre-mr commented 1 year ago

I tried the aproach to wrap another Cloudfront around the Amplify cloudfront and it seems to work. I got the idea from this https://awstip.com/nextjs-aws-amplify-cloudfront-cache-it-real-good-1211466cecfd. What do you think about this? Any downsides?

hi. after some hours, i did this, and it works very well. site opens with a shiny "hit from cloudfront" and everything just works as i expect, no "miss" because of google analytics / tag manager cookie key. and no erratic cloudfront behavior like we all see with amplify's one. it works perfectly.

BUT... for now, only accessing from this new cloudfront distribution's url. example: xptocfid1234.cloudfront.net. I'm struggling to solve the domain issue. amplify has a section where i setup a custom domain, and it sets up route53 automagically. well, that's the point of using a fully managed solution.

but it seems not so simple to change mydomain.com and www.mydomain.com to point to the new custom cloudfront. maybe i have to remove domain entries from amplify, create my own route53 records, create 2 certificates, add mydomain.com and www.mydomain.com as cloudfront alternate domains, and setup an edge lambda to redirect www to apex.

well... it's almost worth it to deploy nextjs app to lightsail or ec2, after so many manual fixes because aws team decided to hide amplify resources from us, and every issue we have to wait months to be fixed.

a fully-managed service needs to be well-managed. otherwise, unlock resources so we can fix things on our own. :confused:

syedlukman1000 commented 12 months ago

WhatsApp Image 2023-11-12 at 13 59 56 Does this work???

zifnab87 commented 10 months ago

any updates on this? does the above work for someone? I am interested in starting using Amplify but I am really concerned about this issue

andre-mr commented 10 months ago

any updates on this? does the above work for someone? I am interested in starting using Amplify but I am really concerned about this issue

it's fine here. 2 websites using the "extra cloudfront" workaround mentioned above and everything working as we need.

i just forgot about using amplify without this, but would be nice if we were able to customize default amplify cloudfront, other than using this weird "2 layers" fix.

zifnab87 commented 10 months ago

@andre-mr thanks for the answer! I realized this workaround works but sounds a bit hacky .. is @syedlukman1000 setting a solution? Thanks

deibyrios commented 9 months ago

Wow, this is an open issue since Seotember 1, 2021? I think people saying AWS Amplify doesn't care about customers might be right or is there any good reason why this critical issue hasn't been solved? We were thinking about migrating al apps to AWS Amplify but this is a no go!

Rajesh-Itilite commented 9 months ago

Hi Amplify Team,

Request to fix this issue. It helps to enage more users to use amplify. where ever s-maxage is avail in amplify docs, it dosent make sense. since cookies are alway different in each hit on amplify app

provide work around 1) setting up no cookies in amplify settings 2) expose internal cdn config in amplify settings.

sjpriest commented 8 months ago

Hi all, just wanted to say that we are also facing this issue and would appreciate the ability to configure CloudFront to ignore cookies from within Amplify.

hasadata commented 8 months ago

+1

JonasWeinert commented 7 months ago

I tried the aproach to wrap another Cloudfront around the Amplify cloudfront and it seems to work. I got the idea from this https://awstip.com/nextjs-aws-amplify-cloudfront-cache-it-real-good-1211466cecfd. What do you think about this? Any downsides?

hi. after some hours, i did this, and it works very well. site opens with a shiny "hit from cloudfront" and everything just works as i expect, no "miss" because of google analytics / tag manager cookie key. and no erratic cloudfront behavior like we all see with amplify's one. it works perfectly.

BUT... for now, only accessing from this new cloudfront distribution's url. example: xptocfid1234.cloudfront.net. I'm struggling to solve the domain issue. amplify has a section where i setup a custom domain, and it sets up route53 automagically. well, that's the point of using a fully managed solution.

but it seems not so simple to change mydomain.com and www.mydomain.com to point to the new custom cloudfront. maybe i have to remove domain entries from amplify, create my own route53 records, create 2 certificates, add mydomain.com and www.mydomain.com as cloudfront alternate domains, and setup an edge lambda to redirect www to apex.

well... it's almost worth it to deploy nextjs app to lightsail or ec2, after so many manual fixes because aws team decided to hide amplify resources from us, and every issue we have to wait months to be fixed.

a fully-managed service needs to be well-managed. otherwise, unlock resources so we can fix things on our own. ๐Ÿ˜•

Have you managed to point your own domain to the 2nd layer cloud front? I am facing the same issue.

andre-mr commented 7 months ago

after some

Yes.

I created a Cloudfront distribution mycdn1.cloudfront.net with alternate domain to my mydomain.com with a new SSL to that domain, and some behaviors to some of my routes, because i have different cache policies for each route.

All Cloudfront behaviors pointing to my Amplify app domain: main.appid.amplifyapp.com

I didn't use any of Amplify Domain Management and removed that 'redirect apex to www' feature they suggest.

I created an hosted zone in Route53 to host my domain, because my registrar doesn't support 'alias type A' record, so i set my registrar to let all DNS be managed by Route53. This costs me 50 cents a month.

I created a 'type A' record my apex domain mydomain.com with 'alias' option 'routing to CloudFront distribution' an the value is that distribution I created, mycdn1.cloudfront.net.

I also created a Cloudfront distribution for www.mydomain.com, called here as mycdn2.cloudfront.net pointing to the very same amplify app main.appid.amplifyapp.com as origin, and only the default behavior BUT attached a Cloudfront Function to viewer request event of this 'Default' behavior. Cloudfront Function is cheaper and faster than Lambda@Edge to do simple request event manipulations like this.

Also, I created another type A Route53 record the same way, with Alias pointing to this mycdn2.cloudfront.net dedicated to www redirection to apex. Well, this origin is not used as you see, because redirect function will always return a 301 and never let users go to origin, but Cloudfront origin value is mandatory.

I made a research about what is better: redirect apex to www or www to apex, and it seems not to have a golden answer. Some cultures value 'www' more, so it is also a marketing concern. In my case, we decided to manage apex to www, because browsers hide www from address bar nowadays, and publishing links without www seems cleaner and better aligned to default behavior of current browsers.

Here is the cloudfront function code:

function handler(event) {
    var newUrl = "https://" 
    + event.request.headers.host.value.replace("www.", "") 
    + event.request.uri;

var queryObject = event.request.querystring;
var queryArray = Object.entries(queryObject);
var queryString = queryArray.map(function(pair) {
  var name = pair[0];
  var value = pair[1].value;
  return name + "=" + value;
});
queryString = queryString.join("&");

if (queryString.length > 0) {
  newUrl += "?" + queryString;
}

    return {
        statusCode: 301,
        statusDescription: "Moved Permanently",
        headers: {
            location: { value: newUrl },
        },
    };
}

Yes, seems "old" and big code, but Cloudfront Functions have some limitations, I tried an optimized version and some lines were not supported, firing some 'not so clear' errors, then I used this old-fashion way and it worked as a charm. Since i publish only apex links and all Google Search Console and Analytics are setup with apex domain, this redirect is rarely used anyway.

Amazon offers 2 million Cloudfront Function calls a month for free, it's more than enough here. And that 10 million Cloudfront calls for free in a month is enough for my case too.

Today ALL routes for my Amplify apps using Next.JS are SSR only. I even used forced headers to avoid unwanted caching in browsers with aggressive caching. All cache rules I setup directly in my top Cloudfronts now and this is working very well.

And... what about the default Cloudfront, created by Amplify and hidden? Well.. it's now useless, just forgot it. ๐Ÿ˜‚ But it would be VERY NICE if we had the option to edit it. ๐Ÿ˜

tiyberius commented 7 months ago

I am also facing this issue with an Amplify Hosted site that uses Heap Analytics. Heap switches up the cookies on every request, and because cookie forwarding is "on" by default and cannot be changed for the Cloudfront distributions that support Amplify Hosting, I'm seeing "Miss from cloudfront" on nearly every request. This places a heavy load on the origin AND kills performance. I'm seeing cold start times of about 5 seconds because of this issue, which is unacceptable in today's day and age.

I appreciate that there is a workaround, but AWS come on. The workaround completely defeats the purpose of Amplify Hosting, and it's really getting me to consider hosting on Vercel.

MantasJa commented 7 months ago

Any news? Why Amplify team ignores this HUGE issue?

hasadata commented 5 months ago

W have Gen2 but we still don't have the solution to this huge issue ?

andre-mr commented 5 months ago

W have Gen2 but we still don't have the solution to this huge issue ?

gen2 for me is more like a new ui than a better service. ๐Ÿ‘€

maddada commented 4 months ago

How is this issue still open?! Was looking into Amplify, but this makes it a complete no-go. Stop ignoring your customers!

mauerbac commented 4 months ago

Hi @maddada - sorry for the lack of communication here. We are actively working on this feature. We actually have an early access program for this if you'd like to give it a shot and share your feedback.

You can follow the instructions here https://github.com/aws-amplify/amplify-hosting/issues/2563#issuecomment-2181648078

mauerbac commented 2 months ago

This feature has just been supported with our latest launch! Closing.

Check out the details here: https://aws.amazon.com/blogs/mobile/cdn-caching-improvements-for-better-app-performance-with-aws-amplify-hosting/

github-actions[bot] commented 2 months ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

github-actions[bot] commented 2 months ago

This issue has been automatically locked.

swaminator commented 2 months ago

Reopening issue to ensure folks can give feedback.