Avatares demoram muito para carregar após a migração para o R2 compatível com S3

Olá,

Acabei de migrar para o R2 e tudo ocorreu perfeitamente. Todas as imagens têm o link de URL do CDN S3. No entanto, percebi um problema: os avatares estão demorando muito para carregar. Em média, leva cerca de 3 a 4 segundos, seja clicando no avatar de um usuário ou visualizando dentro de uma publicação. Isso é esperado?

hmmm, suspeito que possa ser um de 3 problemas diferentes, mas o mais provável para mim é o redimensionamento em tempo real.

1. Redimensionamento de avatar em tempo real

quando você migrou seus uploads para o R2, ele moveu as imagens originais; no entanto, o Discourse usa vários tamanhos diferentes de avatares (por exemplo, 45px para posts, 120px para o cartão do usuário).

se esses tamanhos otimizados específicos não foram migrados perfeitamente, ou ainda não foram gerados, o Discourse precisa gerá-los de forma síncrona no momento em que o usuário clica neles:

  1. o Discourse baixa o avatar original do R2 para o servidor local
  2. redimensiona-o usando o ImageMagick
  3. faz upload do novo tamanho de volta para o R2
  4. redireciona o navegador para a nova URL, e esse processo leva de 3 a 4 segundos

para verificar: atualize forçadamente a página — se o avatar demorar 3-4 segundos na primeira vez, mas carregar instantaneamente na segunda vez, é exatamente isso que está acontecendo.

para corrigir: isso se corrigirá naturalmente à medida que os usuários navegarem e os tamanhos forem gerados. Mas você pode corrigi-lo instantaneamente, forçando o servidor a pré-gerar todos os avatares em segundo plano, acessando seu servidor via SSH e executando:

./launcher enter app
rake avatars:refresh

2. O tempo limite de 3 segundos do IPv6

se os avatares estiverem demorando 3-4 segundos todas as vezes, mesmo após várias atualizações, eles provavelmente estão atingindo um tempo limite de rede.

os endpoints da API do Cloudflare R2 são dual-stack, ou seja, usam tanto IPv4 quanto IPv6. Se a sua droplet de servidor tiver um endereço IPv6 atribuído a ela, mas o gateway IPv6 do host não estiver roteado corretamente, a conexão interna do Ruby com o bucket do R2 tentará usar o IPv6 primeiro, ficará pendurada por 3 segundos (este é o tempo limite padrão do TCP do Linux), falhará e então bem-sucedida instantaneamente usando o IPv4.

para verificar: acesse o servidor via SSH e execute:

curl -I -6 https://cloudflare.com

se ele ficar pendurado por alguns segundos e falhar, o IPv6 do servidor está quebrado, fazendo com que cada verificação interna da API S3 sofra um atraso de 3 segundos.

para corrigir: você precisará corrigir o roteamento IPv6 no painel de controle do seu host ou talvez até desativar o IPv6 na droplet completamente.

3. Atrasos do Gravatar

se o seu site estiver configurado para verificar atualizações do Gravatar, ele pode estar fazendo ping nos servidores externos do Gravatar antes de renderizar o avatar. Se o servidor tiver uma conexão de saída lenta (também frequentemente relacionada a DNS ou IPv6), é provável que isso bloqueie a renderização do avatar.

para verificar: execute isso no seu servidor
curl -I -6 https://gravatar.com
se ele ficar pendurado por 3 segundos, o IPv6 está quebrado (veja acima)

correção relacionada ao Gravatar: nas configurações do seu Discourse, vá para baixar gravatars automaticamente, desative-o temporariamente e veja se isso corrige o problema — não acho que este seja o problema, mas se for, você pode deixar a configuração desativada, ou corrigir o roteamento IPv6 como no item 2 acima, ou talvez alterar o resolvedor DNS.

Obrigado pela sua rápida resposta. Acredito que já tenha tentado o ‘rake avatars:refresh’ antes, mas não tenho certeza absoluta.

O que costumava funcionar para mim para ver o avatar abrir imediatamente era clicar nele pela primeira vez; na segunda vez, ele abria instantaneamente. Mas isso provavelmente se deve ao cache. Também acabei de testar sua segunda dica e ela retornou um “HTTP/2 301”, com várias outras linhas. O mesmo aconteceu com a dica 3. Vou executar o avatars:refresh novamente em alguns dias, pois precisei restaurar um snapshot. Mais uma vez, obrigado!

Gravatar

server: nginx
date: Mon, 22 Jun 2026 19:29:00 GMT
content-type: text/html; charset=utf-8
content-length: 0
content-language: en
expires: Wed, 11 Jan 1984 05:00:00 GMT
cache-control: no-cache, must-revalidate, max-age=0
x-redirect-by: Gravatar
location: https://en.gravatar.com/
alt-svc: h3=":443"; ma=86400
strict-transport-security: max-age=31536000; includeSubdomains; preload

CF

HTTP/2 301
date: Mon, 22 Jun 2026 19:27:00 GMT
content-type: text/html
content-length: 167
location: https://www.cloudflare.com/
cache-control: max-age=3600
expires: Mon, 22 Jun 2026 20:26:59 GMT
set-cookie: __cf_bm=eBP2aJ7Eg30nHPuvMMNxxKrgNtcNwKs0WDgnYyONeus-1782156420-1.0.1.1-sXpW27iuhGDF615cOfwNFybH4IMxgvZy3uA_3X_o..402T_3KSgT7CSymipL5RjdpGe3raWEqsVxQFFLPKRoDjfoT7B.0rqyDt.osbkOF98; path=/; expires=Mon, 22-Jun-26 19:57:00 GMT; domain=.cloudflare.com; HttpOnly; Secure; SameSite=None
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=QfYqSekEDPJHC2k%2BMjHN0cGjz172tmUWe2GSR8EgwNLh3TGjFYkQ0vwPxlzY1NcBcKFOMaAi4FlgjqjhETOOtHf%2BH9KdQSvqN3OME2Uh1i4nHIw%2Fy1qkvSpf4jxDchM7CaDW80tJkjBV4OqF"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
strict-transport-security: max-age=15780000; includeSubDomains
server: cloudflare
cf-ray: a0fda5d8ecd6b26d-LAX
alt-svc: h3=":443"; ma=86400

Sim, dada a sua resposta, estou quase certo de que se trata do problema #1, porque os resultados do comando curl para o Cloudflare e o Gravatar parecem estar conforme o esperado. Tente executar rake avatars:refresh quando for conveniente para você e me avise se funcionar.

E aí, Lilly, ainda estou tendo o mesmo problema. Mesmo depois de rodar o rake avatars:refresh. O problema também aparece na rota /latest. Testei limpando o cache do meu navegador e do Cloudflare, mas sem sucesso até agora. Será que preciso esperar um pouco? Estou testando isso em um fórum com 4500 usuários.

não limpe mais o cache do seu navegador ou do Cloudflare. quando você executa rake avatars:refresh para tantos usuários, isso não acontece instantaneamente. em vez disso, ele envia milhares de jobs para o Sidekiq processarem em segundo plano, o que pode levar várias horas, dependendo da CPU do seu servidor. desculpe por isso, eu deveria ter mencionado o Sidekiq e que isso pode demorar um pouco, dependendo de quantos usuários houver.

vá para your-forum.com/sidekiq/queues e observe a fila. espere até que ela fique completamente vazia. assim que o Sidekiq terminar, todos os tamanhos devem estar permanentemente no seu bucket R2, e acho que o carregamento dos seus avatares deve voltar à velocidade normal.

Ok, acho que está acontecendo outra coisa. Não tenho nada nas minhas filas. Mas se eu clicar no avatar de qualquer usuário, isso aparece em ‘tail -f log/production.log’: Sent file /var/www/discourse/tmp/avatar_proxy/3689d91eb5e1013beef831c585b5e62edeeecbd6.jpeg (0.2ms)

Uau, ok. Isso provavelmente é a prova definitiva e aponta para um problema diferente.

avatar_proxy nos logs geralmente significa que o Discourse está se recusando a servir o avatar diretamente da CDN R2 do Cloudflare. Em vez disso, o Discourse está interceptando agressivamente a solicitação e baixando a imagem do R2 para a pasta /tmp do servidor local, e então usando Ruby para servir a imagem ao navegador. Então, acho que isso está contornando completamente a CDN e explica o atraso de 3 segundos — suspeito que o servidor esteja buscando e carregando o arquivo manualmente em cada solicitação :grimacing:

O Discourse usa o avatar_proxy em alguns cenários muito específicos e, geralmente, é uma configuração de privacidade ou segurança que força o servidor a mascarar a URL externa.

Verifique essas configurações em Admin - Configurações do site:

Encontre external system avatars url — se houver algo nessa caixa (como /letter_avatar_proxy/v4/...), exclua para deixá-la vazia. Isso deve impedir que o Discourse faça proxy dos avatares de letra padrão. Também vale a pena verificar uploaded avatars allowed groups e garantir que esteja definido como TL_0.

Talvez verifique novamente DISCOURSE_S3_CDN_URL para garantir que esteja correto, sem barra no final ou erro de digitação?

Remapear avatares personalizados:
Parece provável que seu banco de dados ainda contenha as URLs brutas do bucket R2 em vez da sua nova URL de CDN; como elas não coincidem, seu fórum provavelmente está fazendo proxy delas por motivos de segurança.

Verifique no console do Rails para ver exatamente com o que o Discourse está lutando:

./launcher enter app
rails c

Escolha um usuário com um avatar de carregamento lento

u = User.find_by_username("o_usuario_escolhido")
u.user_avatar.custom_upload.url

Se a saída retornar uma URL de bucket bruta, seus remapeamentos anteriores não capturaram tudo (talvez tenha perdido um subdomínio ou um esquema).

Para corrigir, faça SSH no seu servidor, volte para o seu container novamente (não o Rails) (./launcher enter app) e execute a ferramenta de remapeamento (de novo, rs) para trocar a URL bruta pela sua URL de CDN:

discourse remap "https://<sua-url-bruta-cloudflare>.r2.cloudflarestorage.com" "https://cdn.seu-dominio.com"

Em seguida, execute novamente usando // em vez de https://, só para garantir.

A propósito, por curiosidade, qual serviço de hospedagem você está usando? Tenho a mesma configuração geral que você e ainda não experimentei esse problema. Então, também estou interessado na sua configuração e quero tentar reproduzi-la de alguma forma.

a URL que obtenho mostra a URL do CDN da S3, e consigo abrir a imagem no navegador.

Vou deixar a S3 de lado por enquanto, pois realmente não preciso dela neste momento.

e eu uso o Advinservers há muito tempo.

obrigado pela ajuda, muito apreciado

Terminei os testes adicionais e posso confirmar que o problema não está relacionado ao R2. O mesmo comportamento (avatares carregando lentamente nas postagens e ao clicar em um nome de usuário) persiste mesmo com um AWS S3 configurado corretamente. Também não é um problema de firewall, pois “ufw status” confirma que o firewall está atualmente desativado. Planejo realizar mais testes neste fim de semana em um ambiente de staging, onde posso manter o fórum em execução por períodos mais longos e tirá-lo do ar, se necessário, sem nenhum problema.

Você tem os CDNs do site e do S3 configurados?

Sim, estou usando ambos. O bucket está conectado ao CloudFront para a URL do CDN do S3, e o mesmo para a URL do CDN do Discourse.

Para os testes do R2, não estava usando a URL do CDN do Discourse.

Exceto no que não está funcionando?

E o R2 sem o CDN do Discourse é onde você está tendo problemas?

Não vou fingir que entendo exatamente qual é o seu problema ou exatamente como as imagens de avatar funcionam, mas eu configuraria o CDN antes de fazer mais testes, e pode ser que o problema seja que você mudou para um novo bucket e as imagens precisam ser regeneradas.

Os avatares aqui são carregados do que parece ser um CDN do Discourse: https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lilly/48/555832_2.png

Os perfis dos usuários carregam mais rápido depois que carregam pela primeira vez?

Novamente, não prometo que entendo e não olhei o código, mas uma suposição é que esses estão sendo servidos pelo CDN do Discourse, e o Discourse então depende de solicitações subsequentes para buscar no CDN. Acho que isso explica por que não funciona (ou funciona lentamente) na versão do R2 que não tem um CDN do Discourse.

talvez eu não esteja entendendo o que você quer dizer aqui, mas tenho 2 sites executando armazenamento de objetos R2 que não experimentam esse problema. :woman_shrugging:t2:

Eles não têm CDNs do Discourse? Se não tiverem, estou errado. Se tiverem, pode ser que a falta de um CDN do Discourse (quando você tem um bucket S3?) cause esse problema.

Mas parece estranho que os avatares se comportem de forma diferente com o S3 do que sem ele.

Na verdade, testei isso com 4 configurações diferentes:

  1. R2 sem o CDN do Discourse

  2. R2 com o CDN do Discourse

  3. AWS S3 com o CDN do Discourse

  4. AWS S3 sem o CDN do Discourse

Em todos os casos, usei a URL do CDN do S3: files.mydomain.com.

Para os casos com o CDN do Discourse, usei: cdn.mydomain.com.

O problema é que, em cada cenário, o carregamento dos avatares é sempre muito lento.

Se eu abrir um tópico, vejo os avatares carregando um por um. No entanto, isso só acontece uma vez. Por exemplo, se eu for para admin/users, só vejo os apelidos e, então, os avatares começam a carregar um por um.

Se eu clicar em um apelido, o cartão do usuário abre e o avatar aparece 3-4 segundos depois. Isso também só acontece uma vez; se eu clicar novamente, o avatar aparece imediatamente, provavelmente devido ao cache.

PS: Ao realizar cada teste, restauro o snapshot de quando não estava usando S3/R2, apago o bucket e começo de novo.

Vou apenas chutar que não tem nada a ver com a configuração do armazenamento de objetos. Acho que seus avatares estão lentos em todos os quatro setups porque o gargalo não é o provedor de armazenamento, mas sim a latência de rede entre o droplet do seu site e o bucket, ou o CPU do seu servidor está com dificuldade para redimensionar as imagens em tempo real. Não sei nada sobre a configuração do seu servidor/CDN e que distâncias estão envolvidas aqui. Mas acho que, uma vez que o cache de borda esteja construído, não deveria importar qual armazenamento você usa, desde que você fique com um e deixe o cache se construir. No entanto, estou apenas especulando neste ponto porque não tenho outras ideias. :woman_shrugging:t2: :grinning_cat_with_smiling_eyes:

Também não sei mais o que pensar. Para o R2, eu estava usando a região Europa Ocidental (WEUR), e para o S3, eu estava usando eu-north-1. Estas são as especificações do meu VPS:

Processador AMD Turin (4 vCores) 8GB de Memória DDR5 ECC 256GB de Armazenamento NVMe SSD 5TB de Largura de Banda (10 Gbit) Localizado em Los Angeles, CA

Talvez eu devesse testar com uma região nos Estados Unidos da próxima vez? Não acho que eu possa fazer isso com o R2.

É o que eu esperaria. É lento gerar todos os avatares. As tarefas de rake farão com que isso aconteça, mas levam muito tempo, especialmente se houver muitos usuários. Na primeira vez que você acessar um usuário, o avatar é gerado e leva alguns segundos para executar um programa externo que processa os dados da imagem em vários tamanhos. Depois disso, tudo está bem. Acho que você só precisa executar a tarefa de rake e esperar que ela gere todos os avatares nos vários tamanhos?

é, acho que era isso que eu queria dizer, mas talvez não tenha explicado bem:

mas acho que você disse que estava carregando lento toda vez. :thinking:

acho que toda vez que você altera a configuração do S3 ou limpa o cache, está recomeçando do zero. se você tiver muitos avatares de usuários, isso vai demorar muito.