L’hosting Drupal è all’origine della maggior parte della fama di lentezza di Drupal, ed è quasi sempre una decisione di acquisto più che un problema di software. Un sito viene costruito bene, poi va online su un piano tariffato per un sito vetrina con una manciata di file PHP. Il risultato è un content management system con una pipeline di rendering seria che gira dentro un limite di memoria che non può cambiare, su una cache di opcode che non controlla, senza una shell per eseguire i propri strumenti.

Il confronto che tutti fanno mentalmente è quello con WordPress, ed è quello sbagliato. WordPress gira in modo accettabile su quasi tutto perché la sua quota di mercato ha costretto gli hoster a farlo girare in modo accettabile su quasi tutto. Drupal dà per scontati un PHP attuale, un database recente, un vero backend di cache, una riga di comando e un processo di deploy che tratta la codebase come un artefatto di build invece che come una cartella da modificare.

Che cosa serve davvero a Drupal da un hosting? Una versione di PHP pari o superiore al minimo della vostra release, un MySQL, MariaDB o PostgreSQL recente, in pratica 256 MB di memoria PHP, OPcache, accesso shell per Composer e Drush, una vera voce di cron e una cache oggetti esterna appena avete utenti autenticati. L’hosting condiviso economico fallisce su tre o quattro di questi punti insieme.


Cosa richiede davvero Drupal da un server

I requisiti pubblicati sono brevi, specifici e pubblici, e quasi nessuno li legge prima di comprare. Sono anche legati alla versione in un modo che conta proprio adesso, perché due di quei minimi si spostano a dicembre 2026.

La versione minima di PHP non è negoziabile

Drupal 11 richiede almeno PHP 8.3 e supporta 8.3, 8.4 e 8.5. Drupal 10 richiede 8.1 e arriva fino a 8.4, mentre Drupal 12 alza di nuovo il minimo a PHP 8.5. Quei numeri vengono dalla documentazione Drupal sui requisiti PHP, l’unica versione di quell’elenco di cui valga la pena fidarsi.

Conta più di quanto sembri, perché i rami di PHP stessi scadono. La pagina delle versioni supportate su php.net fissa la fine del supporto di sicurezza di PHP 8.2 al 31 dicembre 2026, quella di 8.3 al 31 dicembre 2027 e quella di 8.4 al 31 dicembre 2028. PHP 8.1 è già oltre. Un hoster che pubblicizza “PHP 8.1 e 8.2 disponibili” offre uno stack che è già senza patch o lo sarà nel giro di mesi.

Le due date si scontrano. Drupal 10 arriva a fine vita il 9 dicembre 2026 e Drupal 12 esce nella stessa settimana, secondo il calendario delle release del core. Se il vostro hoster non può servire PHP 8.3 o successivo, dopo quella data non potete far girare un Drupal supportato. La nostra guida a costi, opzioni e scadenze della migrazione Drupal spiega cosa significa se siete ancora sulla 10.

I motori di database e i loro minimi reali

Drupal 11 vuole MariaDB 10.6 o successivo, MySQL 8.0 o successivo, PostgreSQL 16 o successivo, oppure SQLite 3.45 o successivo, secondo i requisiti del server di database. Drupal 10 è più permissivo con MariaDB 10.3.7, MySQL 5.7.8, PostgreSQL 12 e SQLite 3.26, ed è esattamente per questo che a volte un upgrade impone un aggiornamento del database che il cliente non si aspettava.

Due dettagli vengono saltati. InnoDB deve essere il motore di storage su MySQL e MariaDB, perché Drupal si appoggia alle transazioni e al blocco a livello di riga. Su PostgreSQL l’estensione pg_trgm va creata sul database Drupal prima dell’installazione, e un servizio di database gestito che non consente CREATE EXTENSION non è utilizzabile.

SQLite è davvero supportato e va bene per lo sviluppo locale, ma non è una risposta in produzione appena più redattori salvano contenuti, perché la concorrenza in scrittura diventa il primo tetto.

Memoria, estensioni e web server

Il minimo documentato da Drupal è 64 MB di memoria PHP, e sotto quella soglia mostra avvisi. La stessa pagina nota che in produzione sono tipici 128 MB o 256 MB e che le installazioni ricche di media ne chiedono di più. In pratica trattate 256 MB come il valore di lavoro e aspettatevi di alzarlo per la riga di comando, perché a consumare memoria sono Composer e le migrazioni grandi, non la consegna delle pagine.

L’elenco delle estensioni non ha nulla di sorprendente e vale comunque la pena controllarlo: PDO con un driver di database, XML, JSON, mbstring, cURL, OpenSSL per l’HTTPS in uscita e GD oppure ImageMagick per le derivate delle immagini. Drupal 12 aggiunge Argon2 per l’hashing delle password, una cosa in più che una build molto vecchia di PHP non avrà.

Sul web server Drupal supporta Apache 2.4.7 o successivo e Nginx 1.1 o successivo, e non supporta Microsoft IIS a partire da Drupal 11.0.0. Apache ha bisogno di mod_rewrite per gli URL puliti e di AllowOverride All perché il .htaccess fornito abbia effetto. Quest’ultimo punto frega parecchi: alcune regole di protezione di Drupal esistono solo nel .htaccess, quindi un deploy su Nginx deve riprodurle a mano nella configurazione del server. È un passaggio di routine che viene saltato di routine, ed è una delle prime cose che cerchiamo in un audit di sicurezza del server.

Perché l’hosting condiviso fallisce con Drupal

L’hosting condiviso non è cattivo hosting. È hosting ottimizzato per una forma di applicazione diversa, e Drupal si rompe contro i suoi vincoli in quattro punti prevedibili.

Senza shell niente Composer e niente Drush

Il Drupal moderno è un progetto Composer. Core, moduli contribuiti e le loro dipendenze PHP vengono risolti tutti da Composer, e appena Composer gestisce un modulo deve gestire anche il core. Mescolare Composer con aggiornamenti manuali dei file è il modo in cui un sito finisce per non potersi aggiornare affatto.

Un pannello di controllo con un file manager non può farlo. Nemmeno un client FTP. Senza SSH perdete anche Drush, con cui si eseguono davvero le ricostruzioni della cache, gli import di configurazione, gli aggiornamenti del database e i reset delle password. Un sito su cui non potete lanciare drush cr è un sito dove ogni passo di ripristino diventa un ticket di assistenza.

I limiti che non vedete, figuriamoci cambiare

Un account condiviso vi dà un memory_limit deciso da qualcun altro, di solito 128 MB e a volte meno, senza alcuna via per alzarlo per quell’unica migrazione che ne richiede 512 MB.

OPcache è il problema più grosso. Conserva in memoria condivisa il bytecode precompilato degli script perché PHP non rianalizzi i file a ogni richiesta, e su un host condiviso quel pool di memoria è diviso fra centinaia di account. Drupal ha migliaia di file PHP, quindi è un inquilino pesante di un pool per cui compete, e finisce sfrattato. Il sintomo è un sito veloce per un minuto dopo una visita e di nuovo lento un’ora dopo.

Poi c’è quello che manca del tutto: niente Redis, niente Memcached, nessun controllo sul process manager di PHP e nessun modo di far girare un worker di coda a lunga durata.

Il cron che non gira mai davvero

Il modulo Automated Cron di Drupal gira ogni tre ore per impostazione predefinita ed è innescato dai visitatori del sito. Su un sito trafficato significa che ogni tanto un visitatore paga l’indicizzazione della ricerca con il proprio tempo di caricamento. Su un sito tranquillo significa che il cron di fatto non gira, quindi l’indice di ricerca invecchia, le tabelle di log non vengono mai sfoltite e gli aggiornamenti di sicurezza disponibili non vengono mai controllati.

La documentazione consiglia invece di innescare il cron dall’esterno, perché così gira sempre a orario e consuma meno risorse. Serve una vera voce di crontab, che il piano più economico non offre.

I livelli di cache e quello che colpisce il vostro visitatore

Drupal mette in cache più di quanto la maggior parte delle persone immagini, e i livelli non sono alternativi. Si impilano, e ognuno raccoglie ciò che il livello sopra non ha potuto.

OPcache sta interamente sotto Drupal

OPcache non è una funzione di Drupal. Mette in cache il bytecode PHP compilato a livello di interprete, quindi vale per ogni richiesta, che una cache di Drupal risponda oppure no. Sbagliatelo e niente al di sopra potrà compensare, perché ogni richiesta paga la ricompilazione del framework prima di arrivare al router. Dimensionate la memoria condivisa con generosità e disattivate la validazione dei timestamp in produzione, dove l’insieme dei file cambia solo al deploy.

Internal Page Cache e Dynamic Page Cache

Internal Page Cache è un modulo del core, attivo per impostazione predefinita, e serve soltanto gli utenti anonimi. Presume che ogni visitatore anonimo veda la stessa pagina, memorizza l’intera risposta alla prima richiesta e la riusa. Per un sito di marketing senza personalizzazione è questo il livello che fa quasi tutto il lavoro.

Anche Dynamic Page Cache è nel core e anch’esso è attivo per impostazione predefinita, e mette in cache per chiunque, utenti autenticati compresi. Funziona facendo trasformare al sistema di rendering le parti davvero personali di una pagina in segnaposto, e mettendo in cache tutto ciò che sta intorno. È per questo che una pagina Drupal vista da autenticati può restare in gran parte in cache: solo il menu utente e pochi blocchi sono davvero dinamici.

BigPipe e la cache di rendering

Sotto entrambi sta la cache di rendering, che mette in cache singoli blocchi, campi, risultati di view e rendering di entità. Una pagina che manca la page cache di solito viene assemblata in larga parte da hit della cache di rendering invece che ricostruita dal database.

BigPipe si occupa di ciò che resta. È nel core da Drupal 8.1, stabile dalla 8.3 e nel profilo di installazione standard dalla 8.5. Invece di aspettare che ogni segnaposto si risolva, invia subito la pagina cacheabile e trasmette dopo i frammenti personalizzati. Non richiede configurazione e aiuta gli utenti autenticati molto più di quelli anonimi.

Quindi su un sito ben configurato il visitatore anonimo colpisce l’Internal Page Cache, o la CDN davanti, e non tocca quasi nulla del resto. Il redattore autenticato colpisce a ogni richiesta Dynamic Page Cache, cache di rendering e BigPipe, ed è per questo che il traffico autenticato costa molto di più.

La cache oggetti esterna

Ogni livello di cui sopra ha bisogno di un posto dove tenere le proprie voci. Per impostazione predefinita è il database, in tabelle di cache, il che significa che le vostre letture di cache competono con le vostre query sui contenuti sullo stesso server.

Il modulo Redis sposta i backend di cache, lock, flood e code su Redis o su uno store compatibile come Valkey, usando l’estensione PhpRedis, l’estensione Relay o la libreria Predis in PHP puro. Memcached è l’alternativa equivalente. Per un piccolo sito anonimo cambia poco. Per un sito con utenti autenticati è di solito il miglioramento singolo più grande disponibile, perché toglie dal database il carico di scrittura più rumoroso e rende economico il locking.

Reverse proxy e CDN davanti a Drupal

Un reverse proxy come Varnish o Nginx, oppure una CDN, risponde alle richieste prima ancora che PHP sia coinvolto. Per il traffico anonimo è la differenza fra servire una pagina in millisecondi a una cifra e servirla in qualche centinaio. È anche il livello che spaventa di più, perché una cache stantia su un sito di notizie o su un negozio è un guasto visibile.

I cache tag sono ciò che rende sicura una CDN

La risposta di Drupal sono i cache tag. I cache tag descrivono le dipendenze dei dati e si scrivono come stringhe tipo node:5, user:3 o node_list. Ogni elemento in cache registra da quali tag dipende, così modificare il nodo 5 invalida ogni frammento, pagina e view in cache che lo referenziava, ovunque comparisse.

La parte importante è che Drupal può pubblicare quei tag verso l’esterno. Moduli contribuiti li emettono come header Surrogate-Key per Fastly o Cache-Tag per Cloudflare, e la CDN poi svuota per tag quando lo dice Drupal. Questo trasforma una CDN da scommessa basata sul tempo a cache guidata dagli eventi: potete impostare un tempo di vita lungo, perché una modifica svuota esattamente gli URL interessati nel giro di secondi.

Attenzione al budget degli header. La documentazione Cloudflare sullo svuotamento per cache tag limita l’header Cache-Tag aggregato a 16 KB dopo il nome del campo, all’incirca 1.000 tag unici, con un massimo di 1.024 caratteri per tag in una chiamata API e 100 tag per svuotamento dalla dashboard. Una view Drupal che elenca molte entità può generare molti più tag di così, quindi una pagina che elenca tutto farà tracimare l’header in silenzio, a meno che il modulo non sia configurato per accorciarli o per farne l’hash.

Scegliere l’hosting Drupal: quattro livelli, onestamente

Le opzioni reali sono quattro, e quella giusta si decide in base al fatto che abbiate traffico autenticato e che abbiate qualcuno che gestisca il server. Le fasce qui sotto sono ciò che i clienti britannici pagano tipicamente secondo la nostra esperienza, IVA esclusa, e sono indicative più che quotazioni di un fornitore.

LivelloCosto mensile tipicoCosa comprate
CondivisoGBP 3 a GBP 15Niente di ciò che serve a Drupal
VPS o cloud non gestitoGBP 20 a GBP 120Controllo totale, nessun gestore
Piattaforma Drupal gestitaGBP 40 a GBP 800 e oltreStack e flusso di lavoro imposti
Infrastruttura su misuraGBP 400 in suTutto, più l’onere che comporta

Hosting condiviso

Non va bene per nessuno che porti Drupal in produzione. Fallisce insieme su accesso shell, memoria, cache di opcode, cache oggetti e cron. Se il budget si ferma davvero qui, una piccola istanza non gestita a prezzo simile è un uso migliore del denaro.

VPS o istanza cloud non gestita

Grosso modo GBP 20 a GBP 120 al mese comprano una macchina con root completo, il che va bene per la grande maggioranza dei siti Drupal. Scegliete voi la versione di PHP, dimensionate OPcache, installate Redis, impostate una crontab e configurate Nginx come si deve. Quello che non ottenete è qualcuno che lo faccia, che applichi le patch, che monitori o che ripristini alle due di notte. Questo livello è quello giusto quando avete uno sviluppatore o un’agenzia a contratto, e il contratto è il costo vero, non l’istanza.

Piattaforme specializzate Drupal gestite

L’hosting Drupal gestito parte da circa GBP 40 al mese per un sito piccolo e sale in fretta con traffico, ambienti e livello di assistenza. Quello che comprate è uno stack imposto già corretto, più deploy basato su Git, ambienti di staging, backup e qualcuno che capisce Drupal al telefono. È un buon affare quando l’alternativa è nessuno, ed è un cattivo affare quando pagate prezzi da piattaforma per un sito vetrina che riceve 4.000 visite al mese.

Infrastruttura completamente su misura

Database separato, nodi di cache dedicati, server applicativi dietro un bilanciatore di carico, storage a oggetti per i file. Comincia ad avere senso sopra i GBP 400 al mese circa, e solo quando traffico autenticato, integrazioni o requisiti di conformità rendono scomodi i livelli gestiti. È il livello più capace e il più esigente, perché ora patching, monitoraggio e ripristino di emergenza sono vostri. La nostra guida allo sviluppo web con Drupal spiega da dove arriva quella complessità sul lato applicativo.

Deploy: i file non si modificano sul server

Poiché Composer risolve l’intero albero delle dipendenze, la codebase sul server è un output, non uno spazio di lavoro. Modificare sul posto il file di un modulo significa che il prossimo composer update lo sovrascriverà, e significa che il vostro codice in produzione non corrisponde più a nulla che stia in Git.

Un processo di rilascio sensato costruisce l’artefatto altrove. Lanciate composer install dal composer.lock committato dentro la CI, così la build è riproducibile e l’host di produzione non ha mai bisogno di Composer, di memoria PHP per risolvere le dipendenze o di accesso in scrittura a vendor. Spedite il risultato, eseguite gli aggiornamenti del database, importate la configurazione, ricostruite le cache. Il rollback consiste nel puntare all’artefatto precedente.

Questo risolve in silenzio anche la questione dell’hosting. Un hoster che si aspetta che modifichiate i file via FTP è incompatibile con il modo in cui Drupal viene mantenuto, qualunque cosa dica la sua scheda tecnica.

Dove si colloca la sincronizzazione della configurazione

Drupal tiene la configurazione attiva nel database e la esporta in file YAML, ed è così che tipi di contenuto, campi, view e impostazioni si spostano fra ambienti. La documentazione sulla gestione della configurazione spiega che l’UUID del sito deve coincidere fra origine e destinazione, che è il motivo abituale per cui un primo import fallisce.

In pratica questo significa che la configurazione è codice. Viene committata, revisionata e rilasciata insieme al resto, e il passo di import gira come parte del rilascio invece di essere cliccato dopo nell’interfaccia di amministrazione. L’hosting deve reggerlo: vi serve un posto dove eseguire l’import e un ambiente in cui un import fallito possa essere annullato invece che applicato a metà in produzione.

File, media e backup

Drupal ha due file system e la differenza pesa. Quello pubblico sta sotto la web root ed è servito direttamente dal web server. Quello privato sta fuori dalla web root, e ogni richiesta di un file privato passa da Drupal perché i permessi vengano verificati.

I file privati sono quindi molto più costosi di quelli pubblici, perché ogni download avvia PHP, e un sito che serve documenti privati grandi ha bisogno di un margine che un file server statico non richiederebbe.

Spostare i media su storage a oggetti

Appena i file vivono sul server applicativo, la scalabilità orizzontale e le ricostruzioni diventano dolorose, e ogni backup si porta dietro l’intera libreria di media. Spostare il file system pubblico su storage a oggetti compatibile S3 separa le due cose, lascia che sia la CDN a servire i media e rende un server applicativo davvero sacrificabile.

Un test di ripristino dimostra ciò che un backup non può

Un backup dimostra che un file esiste. Un test di ripristino dimostra che il file è completo, che database e file provengono dallo stesso istante, che le vostre credenziali funzionano ancora e che sapete quanto tempo ci vuole. Sono quattro modalità di guasto distinte e nessuna è visibile da una spunta verde in un pannello di controllo.

Provatelo con un cronometro vero almeno due volte l’anno e annotate il numero. Se il ripristino richiede sei ore e la vostra tolleranza è di una, il problema è l’architettura, non il backup. Il tempo di ripristino è un requisito di hosting e va nel capitolato, non in un incidente.

Dimensionare bene un hosting Drupal

Le pagine viste sono l’unità sbagliata. Un sito con 200.000 pagine viste anonime al mese dietro una CDN può stare comodo su una piccola istanza, mentre un sito con 8.000 pagine viste può faticare se la maggior parte è vista da utenti autenticati.

Il traffico autenticato è il vero fattore

Le richieste anonime possono essere servite dalla page cache o dalla CDN senza toccare PHP. Quelle autenticate no. Ognuna percorre la pipeline di rendering, verifica i permessi su ogni entità, risolve i segnaposto e scrive dati di sessione. La domanda pratica non è quante visite ricevete, è quanti utenti autenticati simultanei avete e che cosa quegli utenti possono vedere.

I redattori sono il caso estremo. Le schermate di amministrazione dei contenuti sono fra le pagine più pesanti di Drupal e sono non cacheabili per definizione, quindi un sito con dodici redattori che lavorano insieme ha un vero requisito di concorrenza che il suo traffico pubblico non lascia mai intuire.

View, tassonomia e lavoro di coda

Oltre al traffico autenticato, i centri di costo affidabili sono le view grandi con molti filtri e relazioni, che generano join costosi, gli alberi di tassonomia profondi, dove le gerarchie di termini vengono percorse a ogni rendering, e il lavoro di cron o di coda come l’indicizzazione della ricerca, gli import di feed e la generazione delle derivate dei media.

I worker di coda non dovrebbero condividere le risorse del web server con i visitatori, se potete evitarlo. Su un sito più grande stanno in un processo o in un’istanza separati, così un arretrato di import non può rallentare il front end. È una decisione di architettura presa al momento dell’acquisto, ed è il punto in cui i livelli gestiti smettono di andare bene e comincia ad andare bene l’infrastruttura su misura.

Prendere bene la decisione

Lo schema è costante. L’hosting non è sottodimensionato, ha la forma sbagliata: niente shell, niente cache oggetti, una cache di opcode controllata da qualcun altro e una versione di PHP prossima a uscire dal supporto. Spostare lo stesso sito su un’istanza specificata correttamente a prezzo simile di solito batte qualsiasi quantità di ottimizzazione front end.

Mecanik specifica, costruisce e mantiene infrastrutture Drupal come parte del nostro lavoro di sviluppo di siti web, e rivede gli stack esistenti con un audit di sicurezza del server quando la preoccupazione è l’esposizione più che la velocità. Se vi servono persone e non una piattaforma, la nostra guida su come assumere uno sviluppatore Drupal spiega cosa cercare.



Domande frequenti

Quali sono i requisiti minimi di server per Drupal 11? PHP 8.3 o successivo, e come database MariaDB 10.6, MySQL 8.0, PostgreSQL 16 oppure SQLite 3.45. Sul lato web server Apache 2.4.7 o Nginx 1.1 e successivi, con Microsoft IIS non supportato a partire da Drupal 11.0.0. Drupal avvisa sotto i 64 MB di memoria PHP, ma 256 MB è la cifra realistica in produzione.

Drupal può girare su hosting condiviso? Si installa e serve pagine, ma l’hosting condiviso di solito fallisce su tre o quattro requisiti insieme: niente accesso shell per Composer o Drush, un limite di memoria PHP che non potete alzare, niente Redis o Memcached e un cron che scatta solo quando capita che un visitatore carichi una pagina. Sono queste condizioni a produrre la fama di lentezza di Drupal.

Quanto dovrebbe costare l’hosting Drupal? Un piccolo sito Drupal su un’istanza non gestita configurata bene sta tipicamente fra GBP 20 e GBP 120 al mese prima che qualcuno la gestisca. Le piattaforme Drupal gestite partono di solito vicino a GBP 40 e salgono nelle centinaia con traffico e ambienti. L’infrastruttura su misura comincia ad avere senso sopra i GBP 400 circa. Il livello più economico è raramente il risultato più economico.

Drupal ha bisogno di Redis? Non per un piccolo sito anonimo, dove la page cache interna e il database bastano. Appena avete utenti autenticati, redattori o un’area riservata, una cache oggetti esterna come Redis o Memcached sposta letture di cache, lock e code fuori dal database, ed è di solito il miglioramento singolo più grande ottenibile per quella spesa.

Una CDN è sicura davanti a un sito Drupal dinamico? Sì, purché invalidiate per cache tag invece che per tempo. Drupal registra tag come node:5 per tutto ciò da cui una risposta dipende, e i moduli li traducono in header Cache-Tag o Surrogate-Key perché la CDN svuoti esattamente le pagine che una modifica ha toccato. Senza invalidazione per tag scegliete fra pagine stantie e una cache che non aiuta mai.