hmmm, i suspect it could be one of 3 different issues, but the most likely to me is on-the-fly resizing.
1. on-the-fly avatar resizing
when you migrated your uploads to R2, it moved the original images; however, discourse uses many different sizes of avatars (eg 45px for posts, 120px for the user card).
if those specific optimized sizes didn’t migrate perfectly, or haven’t been generated yet, dscourse has to generate them synchronously at the moment the user clicks them:
- discourse downloads the original avatar from R2 to the local server
- resizes it using imagemagick
- uploads the new size back to R2
- redirects the browser to the new URL, and this process takes 3 to 4 seconds
to verify: hard-refresh the page - if the avatar takes 3-4 seconds the first time, but loads instantly the second time, this is exactly what is happening.
to fix: this will naturally fix itself as users browse and the sizes are generated. but you can fix it instantly, by forcing the server to pre-generate all avatars in the background by ssh’ing into your server and running:
./launcher enter app
rake avatars:refresh
2. the 3 second IPv6 timeout
if the avatars are taking 3-4 seconds every time even after multiple refreshes, they are likely hitting a networking timeout.
cloudflare R2 api endpoints are dual-stack in that they use both ipv4 and ipv6. if your server droplet has an ipv6 address assigned to it, but the host’s ipv6 gateway isn’t routed properly, ruby’s internal connection to the R2 bucket will attempt ipv6 first, hang for 3 second (this is the default linux TCP timeout), fail and then instantly succeed using ipv4.
to verify: ssh into the server and run:
curl -I -6 https://cloudflare.com
if it hang for a few seconds and fails, the server’s ipv6 is broken, causing every internal S3 api check to suffer a 3-second delay.
to fix: you will need to either fix the ipv6 routing in in your host control panel or maybe even disable ipv6 on the droplet entirely
3. gravatar delays
if your site is configured to check for gravatar updates it may be pinging gravatar’s external servers before rendering the avatar. if the server has a slow outbound connection (also often related to DNS or ipv6) it will likely block the avatar render.
to verify: run this on your server
curl -I -6 https://gravatar.com
if it hangs for 3 seconds the ipv6 is broken (see above)
gravatar-related fix: in your discourse settings go to automatically download gravatars, turn it off temporarily, and see if that fixes it - i don’t think this is the problem but if it is, i you can leave the setting off, or fix the ipv6 routing as in 2 above, or maybe change the DNS resolver.