12 Ottobre 2026

Joomla e Varnish Cache: il problema dei cookie di sessione e come portare il TTFB a pochi millisecondi

Joomla assegna un cookie di sessione anche ai visitatori anonimi e Varnish, per prudenza, non mette nulla in cache. Ecco come risolvere senza rompere login, form e aree riservate.

Il cookie di sessione di Joomla blocca la cache di Varnish

Chi mette Varnish davanti a un sito Joomla si aspetta di vedere crollare i tempi di risposta. Spesso succede il contrario: il server lavora come prima, il database macina le stesse query e nei log di Varnish compaiono quasi solo MISS e PASS. La conclusione frettolosa è che “Varnish con Joomla non funziona”. In realtà Varnish funziona benissimo: è Joomla, in configurazione standard, che gli impedisce di fare il suo lavoro.

In questo articolo spiego perché succede, come si risolve con una configurazione VCL fatta su misura e quali sono le due trappole che rompono il sito se la cache viene attivata senza criterio: gli utenti loggati e i token di sicurezza dei form.

Il problema: un cookie di sessione anche per chi non ha fatto login

Varnish, per prudenza, non mette in cache le richieste che arrivano con un cookie e le risposte che ne impostano uno. È una scelta sensata: un cookie può identificare un utente e una pagina personale non deve mai essere servita a qualcun altro.

Joomla, in configurazione standard, avvia una sessione per ogni visitatore, anche per chi non ha mai fatto login, e invia il relativo cookie di sessione già alla prima pagina. Da quel momento ogni richiesta di quel visitatore porta con sé il cookie. Il risultato è che Varnish tratta ogni visitatore anonimo come un utente potenzialmente personale e manda tutto a PHP. La cache c’è, ma non viene quasi mai usata.

C’è un secondo dettaglio che completa il quadro: Joomla risponde con intestazioni che vietano la cache (Cache-Control: no-cache e una data di scadenza nel passato). Anche togliendo il cookie, Varnish riceverebbe una risposta che dichiara di non poter essere conservata.

Percorso delle richieste Joomla con e senza cookie di sessione in Varnish
Con il cookie di sessione ogni richiesta finisce a PHP; togliendolo agli anonimi diventa un HIT

Quanto vale davvero la cache

Per dare un ordine di grandezza ho misurato dall’esterno il nostro sito, che è un WordPress dietro Varnish, sulla stessa pagina e dalla stessa connessione. Senza cache la pagina arriva in 0,63-0,69 secondi; servita da Varnish arriva in 0,10-0,12 secondi, di cui 0,07 sono solo il tempo di connessione e di negoziazione TLS dalla mia postazione. Al netto della rete, significa 30-50 millisecondi contro oltre mezzo secondo di elaborazione.

Su Joomla il rapporto è lo stesso, spesso anche più marcato su siti con molti moduli ed estensioni. Ma il guadagno dipende interamente da una cosa: quante richieste diventano HIT. Con il cookie di sessione attivo per tutti, quella percentuale è vicina a zero.

Tempo di risposta con e senza cache Varnish, misura reale
Misura reale: oltre mezzo secondo senza cache, poche decine di millisecondi con Varnish

La soluzione: tre regole da rispettare

La strategia corretta si riassume in tre regole:

  1. i visitatori anonimi ricevono pagine dalla cache, e per loro Varnish ignora il cookie di sessione;
  2. gli utenti autenticati non passano mai dalla cache, perché vedono pagine personali;
  3. le pagine con form, l’area amministrativa, il login, il carrello e il checkout sono sempre escluse.

Il problema è distinguere un anonimo da un utente loggato, visto che entrambi hanno un cookie di sessione dal nome indistinguibile. Joomla non fornisce un indicatore pensato per un reverse proxy, quindi lo creiamo noi: un piccolo plugin di sistema che al login imposta un cookie dedicato, per esempio ms_loggato=1, e al logout lo cancella. Joomla 4 e 5 mettono a disposizione gli eventi giusti (onUserAfterLogin e onUserLogout) e il plugin si scrive in poche righe. Lo stesso plugin può inviare Cache-Control: private agli utenti autenticati, così nessuna cache intermedia conserva le loro pagine.

La configurazione VCL

Ecco una base per Varnish 6 o 7, da adattare al singolo sito:

vcl 4.1;

sub vcl_recv {
    # Solo GET e HEAD possono finire in cache
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }

    # Area amministrativa, utenti, form e percorsi dinamici
    if (req.url ~ "^/administrator" ||
        req.url ~ "option=com_users" ||
        req.url ~ "[?&]task=" ||
        req.url ~ "^/(login|accedi|registrazione|carrello|checkout)") {
        return (pass);
    }

    # Utente autenticato o con "ricordami": niente cache
    if (req.http.Cookie ~ "ms_loggato=1" ||
        req.http.Cookie ~ "joomla_remember_me_") {
        return (pass);
    }

    # Parametri di tracciamento: non cambiano la pagina
    if (req.url ~ "[?&](utm_[a-z]+|gclid|fbclid|msclkid)=") {
        set req.url = regsuball(req.url, "(utm_[a-z]+|gclid|fbclid|msclkid)=[^&]*&?", "");
        set req.url = regsub(req.url, "[?&]+$", "");
    }

    # Visitatore anonimo: il cookie di sessione non serve
    unset req.http.Cookie;
    return (hash);
}

sub vcl_backend_response {
    if (bereq.uncacheable) {
        return (deliver);
    }
    # Joomla invia un cookie di sessione e "no-cache" anche agli ospiti
    unset beresp.http.Set-Cookie;
    unset beresp.http.Cache-Control;
    unset beresp.http.Expires;
    unset beresp.http.Pragma;
    set beresp.ttl = 10m;
    set beresp.grace = 6h;
    return (deliver);
}

Alcune note su queste regole. I percorsi esclusi vanno adattati agli alias di menu reali del sito: se la pagina di login si chiama /area-riservata, è quella che va esclusa. Il cookie joomla_remember_me_ serve a non “dimenticare” gli utenti che hanno scelto di restare collegati: senza quella regola, Varnish toglierebbe il cookie e Joomla non potrebbe riconoscerli. Il grace di sei ore permette a Varnish di servire una copia appena scaduta mentre ne prepara una nuova, evitando che un picco di traffico arrivi tutto insieme su PHP proprio allo scadere della cache.

La trappola dei token di sicurezza

Joomla protegge i form con un token CSRF: un codice inserito nell’HTML che deve corrispondere alla sessione di chi invia il form. Se una pagina che contiene un form finisce in cache, tutti i visitatori ricevono lo stesso token, che non corrisponde a nessuna delle loro sessioni. Il risultato è il classico errore sul token non valido al momento dell’invio.

Il caso più frequente è il modulo di login mostrato in tutte le pagine, magari nella barra laterale o nell’intestazione. Con la cache attiva diventa inutilizzabile. Le soluzioni pulite sono due: mostrare il form di login solo nella pagina di login, che è esclusa dalla cache, oppure sostituirlo con un semplice link a quella pagina. Lo stesso vale per i moduli di contatto e per qualsiasi form inserito in pagine pubbliche: o vivono in pagine escluse, o vengono caricati separatamente.

La cache di Joomla serve ancora?

Joomla ha un proprio sistema di cache: la cache di sistema (conservativa o progressiva) e il plugin “System – Page Cache”, che conserva le pagine intere per i visitatori ospiti. Con Varnish davanti, la cache di pagina di Joomla diventa in gran parte ridondante: Varnish risponde prima ancora che PHP venga avviato, quindi le pagine intere conservate da Joomla vengono raramente richieste.

La cache conservativa dei moduli, invece, resta utile: rende più veloce la generazione delle pagine quando Varnish deve chiederle a PHP, cioè sui MISS e per gli utenti autenticati. È la combinazione che consigliamo: Varnish per le pagine intere, cache conservativa di Joomla per i pezzi.

Aggiornare la cache quando si pubblica

Joomla non ha un’integrazione nativa con Varnish per svuotare le pagine modificate. Con un TTL di dieci minuti il problema è contenuto: un articolo modificato appare aggiornato entro pochi minuti. Quando servono aggiornamenti immediati, lo stesso plugin di sistema può intercettare il salvataggio dei contenuti (evento onContentAfterSave) e chiedere a Varnish di invalidare la pagina dell’articolo, la sua categoria e la home, con una richiesta autorizzata solo dal server stesso. In questo modo si può allungare il TTL e aumentare ancora la percentuale di HIT.

Come verificare che funzioni

Tre controlli bastano:

  • da visitatore anonimo, ricaricando una pagina due volte, la seconda risposta deve arrivare da Varnish (l’intestazione Age diventa maggiore di zero);
  • da utente loggato, le pagine devono mostrare il proprio nome e il proprio menu, mai quelli di altri;
  • i form (login, contatti, registrazione) devono funzionare al primo invio, senza errori sul token.

Su un sito in produzione conviene poi guardare per qualche giorno il rapporto tra HIT e MISS con varnishstat: è il numero che dice se la configurazione sta davvero alleggerendo il server.

Conclusioni

Varnish e Joomla funzionano molto bene insieme, a patto di conoscere il punto in cui si scontrano: il cookie di sessione assegnato a tutti. Togliendolo agli anonimi, riconoscendo gli utenti autenticati con un cookie dedicato e tenendo fuori dalla cache form e aree riservate, si passa da una cache inutilizzata a tempi di risposta di poche decine di millisecondi per la grande maggioranza delle visite.

Se il tuo sito Joomla è lento o se hai già provato Varnish senza risultati, sul nostro hosting Joomla configuriamo cache, plugin ed esclusioni su misura del sito, e con il servizio di assistenza Varnish Cache interveniamo anche su infrastrutture esistenti.

Hai dei dubbi? Non sai da dove iniziare? Contattaci !

Abbiamo tutte le risposte alle tue domande per aiutarti nella giusta scelta.

Chatta con noi

Chatta direttamente con il nostro supporto prevendita.

0256569681

Contattaci telefonicamente negli orari d’ufficio 9:30 – 19:30

Contattaci online

Apri una richiesta direttamente nell’area dei contatti.

DISCLAIMER, Note Legali e Copyright. Red Hat, Inc. detiene i diritti su Red Hat®, RHEL®, RedHat Linux®, e CentOS®; AlmaLinux™ è un marchio di AlmaLinux OS Foundation; Rocky Linux® è un marchio registrato di Rocky Linux Foundation; SUSE® è un marchio registrato di SUSE LLC; Canonical Ltd. detiene i diritti su Ubuntu®; Software in the Public Interest, Inc. detiene i diritti su Debian®; Linus Torvalds detiene i diritti su Linux®; FreeBSD® è un marchio registrato di The FreeBSD Foundation; NetBSD® è un marchio registrato di The NetBSD Foundation; OpenBSD® è un marchio registrato di Theo de Raadt; Oracle Corporation detiene i diritti su Oracle®, MySQL®, MyRocks®, VirtualBox® e ZFS®; Percona® è un marchio registrato di Percona LLC; MariaDB® è un marchio registrato di MariaDB Corporation Ab; PostgreSQL® è un marchio registrato di PostgreSQL Global Development Group; SQLite® è un marchio registrato di Hipp, Wyrick & Company, Inc.; KeyDB® è un marchio registrato di EQ Alpha Technology Ltd.; Typesense® è un marchio registrato di Typesense Inc.; REDIS® è un marchio registrato di Redis Labs Ltd; F5 Networks, Inc. detiene i diritti su NGINX® e NGINX Plus®; Varnish® è un marchio registrato di Varnish Software AB; HAProxy® è un marchio registrato di HAProxy Technologies LLC; Traefik® è un marchio registrato di Traefik Labs; Envoy® è un marchio registrato di CNCF; Adobe Inc. detiene i diritti su Magento®; PrestaShop® è un marchio registrato di PrestaShop SA; Shopware® è un marchio registrato di shopware AG; OpenCart® è un marchio registrato di OpenCart Limited; Automattic Inc. detiene i diritti su WordPress®, WooCommerce®, e JetPack®; Open Source Matters, Inc. detiene i diritti su Joomla®; Dries Buytaert detiene i diritti su Drupal®; Shopify® è un marchio registrato di Shopify Inc.; BigCommerce® è un marchio registrato di BigCommerce Pty. Ltd.; TYPO3® è un marchio registrato di TYPO3 Association; Ghost® è un marchio registrato di Ghost Foundation; Amazon Web Services, Inc. detiene i diritti su AWS® e Amazon SES®; Google LLC detiene i diritti su Google Cloud™, Chrome™, e Google Kubernetes Engine™; Alibaba Cloud® è un marchio registrato di Alibaba Group Holding Limited; DigitalOcean® è un marchio registrato di DigitalOcean, LLC; Linode® è un marchio registrato di Linode, LLC; Vultr® è un marchio registrato di The Constant Company, LLC; Akamai® è un marchio registrato di Akamai Technologies, Inc.; Fastly® è un marchio registrato di Fastly, Inc.; Let’s Encrypt® è un marchio registrato di Internet Security Research Group; Microsoft Corporation detiene i diritti su Microsoft®, Azure®, Windows®, Office®, e Internet Explorer®; Mozilla Foundation detiene i diritti su Firefox®; Apache® è un marchio registrato di The Apache Software Foundation; Apache Tomcat® è un marchio registrato di The Apache Software Foundation; PHP® è un marchio registrato del PHP Group; Docker® è un marchio registrato di Docker, Inc.; Kubernetes® è un marchio registrato di The Linux Foundation; OpenShift® è un marchio registrato di Red Hat, Inc.; Podman® è un marchio registrato di Red Hat, Inc.; Proxmox® è un marchio registrato di Proxmox Server Solutions GmbH; VMware® è un marchio registrato di Broadcom Inc.; CloudFlare® è un marchio registrato di Cloudflare, Inc.; NETSCOUT® è un marchio registrato di NETSCOUT Systems Inc.; ElasticSearch®, LogStash®, e Kibana® sono marchi registrati di Elastic N.V.; Grafana® è un marchio registrato di Grafana Labs; Prometheus® è un marchio registrato di The Linux Foundation; Zabbix® è un marchio registrato di Zabbix LLC; Datadog® è un marchio registrato di Datadog, Inc.; Ceph® è un marchio registrato di Red Hat, Inc.; MinIO® è un marchio registrato di MinIO, Inc.; Mailgun® è un marchio registrato di Mailgun Technologies, Inc.; SendGrid® è un marchio registrato di Twilio Inc.; Postmark® è un marchio registrato di ActiveCampaign, LLC; cPanel®, L.L.C. detiene i diritti su cPanel®; Plesk® è un marchio registrato di Plesk International GmbH; Hetzner® è un marchio registrato di Hetzner Online GmbH; OVHcloud® è un marchio registrato di OVH Groupe SAS; Contabo® è un marchio registrato di Contabo GmbH; IONOS® è un marchio registrato di IONOS SE; International Business Machines Corporation detiene i diritti su IBM® e IBM Cloud®; Terraform® è un marchio registrato di HashiCorp, Inc.; Ansible® è un marchio registrato di Red Hat, Inc.; cURL® è un marchio registrato di Daniel Stenberg; Facebook®, Inc. detiene i diritti su Facebook®, Messenger® e Instagram®. Questo sito non è affiliato, sponsorizzato o altrimenti associato a nessuna delle entità sopra menzionate e non rappresenta nessuna di queste entità in alcun modo. Tutti i diritti sui marchi e sui nomi di prodotto menzionati sono di proprietà dei rispettivi detentori di copyright. Ogni altro marchio citato appartiene ai propri registranti. MANAGED SERVER® è un marchio registrato a livello europeo da MANAGED SERVER SRL, con sede legale in Via Flavio Gioia, 6, 62012 Civitanova Marche (MC), Italia e sede operativa in Via Enzo Ferrari, 9, 62012 Civitanova Marche (MC), Italia.

SOLO UN ATTIMO !

Ti sei mai chiesto se il tuo Hosting faccia schifo ?

Scopri subito se il tuo hosting provider ti sta danneggiando con un sito lento degno del 1990 ! Risultato immediato.

Close the CTA
Torna in alto