<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PHP-FPM - Web Design | Creazione Siti Internet</title>
	<atom:link href="https://www.mrtux.it/tag/php-fpm/feed" rel="self" type="application/rss+xml" />
	<link>https://www.mrtux.it</link>
	<description>Sviluppo Siti Web - Assistenza WordPress</description>
	<lastBuildDate>Sat, 27 Jun 2026 09:35:11 +0000</lastBuildDate>
	<language>it-IT</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.1</generator>

<image>
	<url>https://www.mrtux.it/wp-content/uploads/2022/06/favicon-150x150.png</url>
	<title>PHP-FPM - Web Design | Creazione Siti Internet</title>
	<link>https://www.mrtux.it</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>WordPress cron 2026: come i task in background bloccano il sito</title>
		<link>https://www.mrtux.it/wordpress-cron-performance-background-tasks-2026</link>
					<comments>https://www.mrtux.it/wordpress-cron-performance-background-tasks-2026#respond</comments>
		
		<dc:creator><![CDATA[Emilio Petrozzi]]></dc:creator>
		<pubDate>Sat, 27 Jun 2026 09:35:08 +0000</pubDate>
				<category><![CDATA[sviluppo-web]]></category>
		<category><![CDATA[background tasks]]></category>
		<category><![CDATA[cron jobs]]></category>
		<category><![CDATA[monitoraggio]]></category>
		<category><![CDATA[performance WordPress]]></category>
		<category><![CDATA[PHP-FPM]]></category>
		<category><![CDATA[WooCommerce import]]></category>
		<category><![CDATA[WP-Cron]]></category>
		<guid isPermaLink="false">https://www.mrtux.it/wordpress-cron-2026-come-i-task-in-background-bloccano-il-sito</guid>

					<description><![CDATA[WP-Cron, import massivi e backup sono operazioni in background che competono per gli stessi PHP thread del traffico utente. Nel 2026 il problema non è configurarli, è dimensionarli perché non degradino le performance del sito live.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Il tuo sito WordPress ha un TTFB di 200 millisecondi alle 10 del mattino, ma alle 14 — quando parte il cron di import prodotti del tuo grossista — schizza a 4-8 secondi per 20 minuti. Il cliente medio non se ne accorge, ma il cliente che in quei 20 minuti tenta il checkout vede una pagina che gira a vuoto e abbandona il carrello. Il cron &quot;invisibile&quot; ti costa conversioni ogni singolo giorno.</p>



<p class="wp-block-paragraph">In <a href="https://www.mrtux.it/wp-cron-background-wordpress-performance-guida-2026" data-wpel-link="internal" target="_self" rel="noopener">WP-Cron WordPress: ottimizzare i task background in produzione</a> abbiamo affrontato il lato &quot;come configurare WP-Cron correttamente in produzione&quot; — disabilitare lo spawn nativo, spostare su cron di sistema, gestire WP-CLI. Ma quel setup da solo non basta. Il 2026 ha reso il problema molto più visibile: import massivi WooCommerce, backup incrementali, e scan di sicurezza AI-assisted competono per risorse condivise con il traffico utente in modo che fino al 2024 era trascurabile. Oggi non lo è più.</p>



<h2 class="wp-block-heading">Il problema invisibile che nessuno misura</h2>



<p class="wp-block-paragraph">Un cron WordPress — qualunque esso sia, sia esso pianificato via WP-Cron sia eseguito da cron di sistema con <code>wp cron event run</code> — fa una cosa semplice dal punto di vista logico: esegue codice PHP. Ma dal punto di vista del sistema operativo quel codice PHP deve passare attraverso lo stesso stack di qualsiasi richiesta web:</p>



<pre class="wp-block-code"><code># catena di esecuzione di un cron job su WordPress
1. PHP binary avviato (o php-fpm worker riservato)
2. WordPress core caricato (~80-150 MB RAM)
3. Plugin attivi caricati (ognuno aggiunge overhead)
4. Connessione database aperta
5. Eventuale cache object (Redis/Memcached) collegata
6. Codice del cron eseguito
7. Risultato persistito (DB/scritture filesystem)</code></pre>



<p class="wp-block-paragraph">Anche un cron leggero come <code>wp cron event run due_action</code> consuma 60-100 MB di RAM per i 200-400 millisecondi che dura. Un cron pesante come un import WooCommerce da CSV di 10.000 prodotti dura 20-45 minuti e consuma costantemente 150-250 MB.</p>



<p class="wp-block-paragraph">Il punto critico non è il consumo di per sé. È che quel PHP-FPM worker — o quel processo PHP-CLI — compete per le stesse risorse del tuo web server:</p>



<ul class="wp-block-list"><li><strong>CPU</strong>: il job usa cicli che potrebbero servire a servire il checkout di un cliente.</li><li><strong>Database connection pool</strong>: MySQL ha un limite di connessioni concorrenti (default 151). Un cron pesante che ne apre 5-10 ruba slot al traffico web.</li><li><strong>I/O disco</strong>: scritture su <code>wp_options</code>, <code>wp_postmeta</code>, file uploads competono con la cache page su disco.</li><li><strong>PHP-FPM pool</strong>: se il cron passa per php-fpm (impostazione sbagliata ma comune), sottrae worker al web server.</li></ul>



<p class="wp-block-paragraph">Su un sito WooCommerce con 50 PHP-FPM worker disponibili, un cron di import che passa per php-fpm e ne occupa 10-15 contemporaneamente riduce il pool effettivo a 35-40 — esattamente il punto in cui, nei momenti di punta, la saturazione ricomincia. È la stessa dinamica dei bot AI che abbiamo analizzato in <a href="https://www.mrtux.it/php-thread-exhaustion-wordpress-bot-ai-2026" data-wpel-link="internal" target="_self" rel="noopener">WordPress PHP thread 2026: come i bot AI li stanno esaurendo</a>, solo che stavolta il &quot;bot&quot; è un tuo job interno.</p>



<h2 class="wp-block-heading">Le 5 metriche che devi monitorare</h2>



<p class="wp-block-paragraph">Il framework operativo si basa su 5 metriche misurabili, tutte ricavabili da strumenti standard di un server WordPress gestito ragionevolmente.</p>



<h3 class="wp-block-heading">Metrica 1: TTFB p95 durante i cron</h3>



<p class="wp-block-paragraph">Il Time To First Byte al 95° percentile è la metrica più diretta: misura il tempo di risposta del web server sotto carico. Quando un cron pesante parte, il TTFB p95 del sito live sale.</p>



<pre class="wp-block-code"><code># script: misura TTFB p95 da log Nginx
# (assumendo log formato combined)
awk '{print $4, $7, $NF}' /var/log/nginx/access.log |   awk '$4 ~ /\[.*:[0-9]+:[0-9]+:[0-9]+\]/ {match($4, /\[([^:]+):([^:]+):([^:]+):([^:]+)/, t);   time_bucket = t[1]" "t[2]":"substr(t[3],1,2);   ttfb = $NF;   if (ttfb ~ /^[0-9.]+$/) print time_bucket, ttfb}' |   sort |   awk '{sum += $2; n++; arr[n]=$2; time=$1} END {print time, arr[int(n*0.95)]}'</code></pre>



<p class="wp-block-paragraph">Salvalo come <code>/usr/local/bin/ttfb-p95-monitor.sh</code> e fanne un cron ogni 5 minuti. Quando il valore sale sopra i 500 ms, hai un cron che sta impattando le performance.</p>



<h3 class="wp-block-heading">Metrica 2: durata effettiva dei cron job</h3>



<p class="wp-block-paragraph">WP-CLI ti dice esattamente quanto dura un evento:</p>



<pre class="wp-block-code"><code># misura durata effettiva di un evento cron
time wp cron event run your_heavy_event --allow-root --path=/var/www/html</code></pre>



<p class="wp-block-paragraph">Output tipo: <code>real    3m42.115s</code> — il tuo import sta durando 3 minuti e 42 secondi. Se lo esegui ogni ora, hai un throughput continuo di background activity che erode la capacità di picco per il traffico live.</p>



<h3 class="wp-block-heading">Metrica 3: lock contention sul database</h3>



<p class="wp-block-paragraph">MySQL ha una metrica interna che ti dice se i tuoi cron stanno litigando con le query live per i lock sulle tabelle:</p>



<pre class="wp-block-code"><code># controlla lock contention
mysql -u root -p -e "SHOW ENGINE INNODB STATUS\G" |   grep -E "LATEST DETECTED DEADLOCK|LOCK WAIT TIMEOUT|Semaphore"</code></pre>



<p class="wp-block-paragraph">Se vedi deadlock o lock wait frequenti sulle tabelle <code>wp_options</code>, <code>wp_postmeta</code>, <code>wp_wc_orders</code>, il colpevole è quasi certamente un cron che scrive molto mentre il sito live sta cercando di leggere.</p>



<h3 class="wp-block-heading">Metrica 4: disk I/O wait</h3>



<p class="wp-block-paragraph">Quando un cron scrive molto (import massivi, backup, rigenerazione miniature), il disco si satura e tutte le altre operazioni rallentano:</p>



<pre class="wp-block-code"><code># controlla I/O wait
iostat -x 1 5 | awk '/^avg-cpu:/ {getline; print "iowait:", $4"%"}'</code></pre>



<p class="wp-block-paragraph"><code>iowait &gt; 20%</code> durante un cron è segnale che il disco sta diventando il collo di bottiglia. Su hosting con storage di rete (EBS, NFS), questo è ancora più marcato.</p>



<h3 class="wp-block-heading">Metrica 5: PHP-FPM queue length</h3>



<p class="wp-block-paragraph">L&#x27;ultima metrica è la lunghezza della coda di processi PHP in attesa. Quando la coda si riempie, i visitatori reali aspettano:</p>



<pre class="wp-block-code"><code># monitor coda php-fpm
curl -s "YOUR_PHP_FPM_STATUS_ENDPOINT" |   python3 -c "import json,sys; d=json.load(sys.stdin);   print(f"listen_queue={d.get('listen queue', 0)} max_listen_queue={d.get('max listen queue', 0)} active={d['active processes']}/{d['max active processes']}")"</code></pre>



<p class="wp-block-paragraph">Se <code>listen_queue &gt; 0</code> per più di 30 secondi consecutivi, hai un problema di capacity che potrebbe essere causato da un cron o da traffico bot AI (o da entrambi, come abbiamo visto nell&#x27;articolo precedente).</p>



<h2 class="wp-block-heading">Il framework: il &quot;background activity budget&quot;</h2>



<p class="wp-block-paragraph">La soluzione non è &quot;vietare i cron pesanti&quot; — i cron sono necessari. La soluzione è dargli un budget operativo misurabile.</p>



<h3 class="wp-block-heading">Passo 1: definisci il tuo budget</h3>



<p class="wp-block-paragraph">Il budget è definito da tre vincoli:</p>



<pre class="wp-block-code"><code>CPU consentita background:    max 30% di 1 core durante i job
RAM consentita background:    max 25% della RAM totale
PHP-FPM workers sottratti:   max 15% del pool
I/O wait aggiuntivo ammesso:  max 10% sopra il baseline live</code></pre>



<p class="wp-block-paragraph">Questi numeri sono conservativi per un sito WooCommerce di medie dimensioni. Su un sito editoriale con traffico di picco notturno puoi permetterti budget più alti nelle ore diurne e più bassi nelle ore di punta.</p>



<h3 class="wp-block-heading">Passo 2: schedula i cron pesanti nelle finestre a basso traffico</h3>



<p class="wp-block-paragraph">L&#x27;errore più comune è eseguire import massivi alle 14:00 perché &quot;il sistema è libero a quell&#x27;ora&quot;. Ma il sistema è libero a quell&#x27;ora solo perché alle 14:00 non c&#x27;è molto traffico, non perché il sistema può permettersi di degradare quello che c&#x27;è.</p>



<pre class="wp-block-code"><code># sposta i cron pesanti in finestre a basso traffico (2-5 del mattino per ecommerce IT)
# /etc/cron.d/wordpress-imports
0 2 * * * www-data cd /var/www/html &amp;&amp; /usr/local/bin/wp cron event run woo_import_daily --allow-root &gt;&gt; /var/log/wp-cron-imports.log 2&gt;&amp;1
0 3 * * * www-data cd /var/www/html &amp;&amp; /usr/local/bin/wp cron event run woo_sync_stock --allow-root &gt;&gt; /var/log/wp-cron-imports.log 2&gt;&amp;1
0 4 * * * www-data cd /var/www/html &amp;&amp; /usr/local/bin/wp cron event run woo_regenerate_thumbs --allow-root &gt;&gt; /var/log/wp-cron-imports.log 2&gt;&amp;1</code></pre>



<p class="wp-block-paragraph">Ma non basta spostarli di notte: devi anche limitare la concorrenza interna al job.</p>



<h3 class="wp-block-heading">Passo 3: limita la concorrenza interna dei cron pesanti</h3>



<p class="wp-block-paragraph">Molti plugin (specialmente quelli di import) permettono di configurare batch size e pausa tra batch. Settare <code>batch_size = 50</code> con <code>pause_between = 2 seconds</code> invece di <code>batch_size = 500</code> con pausa zero riduce il picco di carico del 60-70% allungando la durata del 20%.</p>



<p class="wp-block-paragraph">Per WooCommerce il pattern canonico è:</p>



<pre class="wp-block-code"><code>// imposta batch size conservativo per WooCommerce product import
add_filter('woocommerce_product_import_batch_size', function() {
    return 25; // prodotti per batch
});
add_filter('woocommerce_product_import_pause_between_batches', function() {
    return 2; // secondi tra batch
});</code></pre>



<h3 class="wp-block-heading">Passo 4: isola i cron pesanti dal web server</h3>



<p class="wp-block-paragraph">Se il tuo hosting lo permette, esegui i cron pesanti in un container o in un processo PHP-CLI separato dal web server, con il proprio database connection pool:</p>



<pre class="wp-block-code"><code># esegui cron pesante via PHP-CLI (non via php-fpm)
# questo NON sottrae worker al web server
time php /var/www/html/wp-cron.php your_heavy_event</code></pre>



<p class="wp-block-paragraph">La differenza è enorme: php-fpm è progettato per gestire molte richieste brevi, non per un singolo job che dura 20 minuti. PHP-CLI è progettato per il contrario. Mandare un cron di import via php-fpm è come usare un&#x27;auto da corsa per traslocare — possibile, ma altamente inefficiente.</p>



<h3 class="wp-block-heading">Passo 5: monitora e allerta</h3>



<p class="wp-block-paragraph">Il monitoraggio continuo è l&#x27;unica cosa che impedisce al framework di diventare una configurazione-iniziale-e-poi-si-dimentica. Lo script di monitoraggio che segue controlla le 5 metriche e invia un alert se il budget viene sforato:</p>



<pre class="wp-block-code"><code>#!/bin/bash
# /usr/local/bin/background-budget-watch.sh
# Monitor background activity budget - invia alert se superato

STATE_FILE="/tmp/budget_state"
LOG="/var/log/budget-monitor.log"
WEBHOOK_URL="YOUR_SLACK_OR_TELEGRAM_WEBHOOK"

# Misura I/O wait
IO_WAIT=$(iostat -x 1 2 | tail -1 | awk '{print $4}')

# Misura TTFB p95 ultimi 5 minuti (da log Nginx)
TTFB_P95=$(awk -v cutoff="$(date -d '5 minutes ago' +%H:%M:%S)" '$4 &gt; "["cutoff {print $NF}' /var/log/nginx/access.log |   sort -n | awk 'END{print arr[int(NR*0.95)]}')

# Misura processi cron attivi
CRON_ACTIVE=$(pgrep -fc "wp cron event run")

# Soglie
IO_LIMIT=20
TTFB_LIMIT=1.5
CRON_LIMIT=3

ALERTS=""

if (( $(echo "$IO_WAIT &gt; $IO_LIMIT" | bc -l) )); then
    ALERTS="$ALERTS\n- I/O wait: ${IO_WAIT}% &gt; ${IO_LIMIT}%"
fi

if (( $(echo "$TTFB_P95 &gt; $TTFB_LIMIT" | bc -l) )); then
    ALERTS="$ALERTS\n- TTFB p95: ${TTFB_P95}s &gt; ${TTFB_LIMIT}s"
fi

if [ "$CRON_ACTIVE" -gt "$CRON_LIMIT" ]; then
    ALERTS="$ALERTS\n- Cron job attivi: $CRON_ACTIVE &gt; $CRON_LIMIT"
fi

if [ -n "$ALERTS" ]; then
    MSG="⚠️ Background activity budget superato ($(date))$ALERTS"
    curl -s -X POST "$WEBHOOK_URL" -d "text=$MSG" &gt;/dev/null
    echo "$(date +%s) ALERT: $ALERTS" &gt;&gt; "$LOG"
fi</code></pre>



<p class="wp-block-paragraph">Aggiungi a crontab ogni 5 minuti:</p>



<pre class="wp-block-code"><code># ogni 5 minuti controlla il budget
*/5 * * * * root /usr/local/bin/background-budget-watch.sh</code></pre>



<h2 class="wp-block-heading">Il caso studio WooCommerce da 12.000 SKU</h2>



<p class="wp-block-paragraph">Un cliente tipico — negozio WooCommerce con 12.000 SKU, import giornaliero dal grossista, 2.000 ordini/giorno, hosting managed con 40 PHP-FPM worker — presentava questo quadro a inizio 2026:</p>



<ul class="wp-block-list"><li>TTFB p95 diurno: 180-220 ms (sano).</li><li>TTFB p95 alle 14:00 (orario import): 4.800 ms (catastrofico).</li><li>Tasso di abbandono carrello alle 14:00: 71% (vs 28% medio diurno).</li><li>Stima revenue perso per degrado cron: circa 8.000€/mese.</li></ul>



<p class="wp-block-paragraph">Applicando il framework in 4 settimane:</p>



<ol class="wp-block-list"><li>Spostato l&#x27;import da CSV alle 02:00 (finestra a traffico zero).</li><li>Ridotto batch size da 500 a 25 prodotti con pausa 2 secondi.</li><li>Migrato l&#x27;import da esecuzione via php-fpm a PHP-CLI con <code>wp cron event run</code>.</li><li>Aggiunto monitoring budget con alert Slack quando TTFB p95 &gt; 1.5s.</li></ol>



<p class="wp-block-paragraph">Risultato a 60 giorni:</p>



<ul class="wp-block-list"><li>TTFB p95 alle 14:00: 210 ms (invariato rispetto al baseline).</li><li>Tasso di abbandono carrello: tornato al 28% anche nelle ore post-import.</li><li>Revenue recuperato stimato: ~8.000€/mese.</li></ul>



<p class="wp-block-paragraph">Il costo di queste 4 modifiche è stato di mezza giornata di lavoro di un dev senior. Il ROI è stato inferiore a una settimana.</p>



<h2 class="wp-block-heading">Le 3 trappole che il team WordPress medio non vede</h2>



<h3 class="wp-block-heading">Trappola 1: il cron &quot;importante&quot; che gira 24/7</h3>



<p class="wp-block-paragraph">Plugin come WooCommerce Subscriptions, Yoast SEO, Wordfence oggi eseguono cron continui per aggiornare dati, scansionare minacce, indicizzare contenuti. Molti di questi sono configurati per girare &quot;ogni 5 minuti&quot; o &quot;ogni 15 minuti&quot; — che sembra innocuo ma, sommato, significa attività di background continua per tutta la giornata.</p>



<p class="wp-block-paragraph">Soluzione: audita i tuoi cron attivi con <code>wp cron event list --allow-root</code> e valuta se ognuno è necessario con quella frequenza.</p>



<h3 class="wp-block-heading">Trappola 2: backup che bloccano il database</h3>



<p class="wp-block-paragraph">Plugin di backup come UpdraftPlus o BackupBuddy spesso eseguono dump del database via PHP. Su database grossi (&gt;500 MB) il dump può durare 5-15 minuti e tenere lock su tabelle critiche per l&#x27;intera durata.</p>



<p class="wp-block-paragraph">Soluzione: usa <code>mysqldump</code> via cron di sistema con parametri <code>--single-transaction --quick</code> per minimizzare i lock, oppure sposta il backup su uno strumento esterno (Kinsta backup, BlogVault) che lavora a livello di filesystem snapshot senza lock applicativi.</p>



<h3 class="wp-block-heading">Trappola 3: AI scan di sicurezza in tempo reale</h3>



<p class="wp-block-paragraph">I plugin di sicurezza moderni (Wordfence, MalCare, Solid Security) hanno introdotto scan AI-assisted in tempo reale nel 2025-2026. Questi scan analizzano i file del tema e dei plugin ad ogni modifica — utile per la sicurezza, ma ogni scan attiva PHP execution e I/O disco.</p>



<p class="wp-block-paragraph">Soluzione: configura lo scan AI come evento schedulato (settimanale), non come scan continuo. La sicurezza migliora quando l&#x27;analisi è completa e ragionata, non quando frammenta la CPU in mini-scan continui.</p>



<h2 class="wp-block-heading">Come questo si collega agli articoli precedenti della serie</h2>



<p class="wp-block-paragraph">Il framework background activity budget è complementare a tre articoli della serie:</p>



<p class="wp-block-paragraph">In <a href="https://www.mrtux.it/wp-cron-background-wordpress-performance-guida-2026" data-wpel-link="internal" target="_self" rel="noopener">WP-Cron WordPress: ottimizzare i task background in produzione</a> abbiamo visto il setup tecnico di WP-Cron (disabilitare spawn nativo, cron di sistema, WP-CLI). Questo articolo aggiunge il livello successivo: una volta che i cron funzionano, come farli coesistere con il traffico live.</p>



<p class="wp-block-paragraph">In <a href="https://www.mrtux.it/php-thread-exhaustion-wordpress-bot-ai-2026" data-wpel-link="internal" target="_self" rel="noopener">WordPress PHP thread 2026: come i bot AI li stanno esaurendo</a> abbiamo visto come i bot AI saturano il pool PHP-FPM. I cron pesanti fanno la stessa cosa dall&#x27;interno: sottraggono worker al web server.</p>



<p class="wp-block-paragraph">In <a href="https://www.mrtux.it/wp-cli-2026-guida-completa-ai" data-wpel-link="internal" target="_self" rel="noopener">WP-CLI 2026 guida completa AI</a> abbiamo visto come WP-CLI può essere usato come orchestratore di operazioni complesse. La regola &quot;esegui i cron pesanti via PHP-CLI, non via php-fpm&quot; è il complemento operativo di quel setup.</p>



<p class="wp-block-paragraph">In <a href="https://www.mrtux.it/toolchain-agenzia-wordpress-moderna-2026" data-wpel-link="internal" target="_self" rel="noopener">Toolchain agenzia WordPress moderna 2026: guida pratica completa</a> abbiamo visto come un toolchain moderno (Bedrock + Sage + Kinsta APM + AI assistant) misura e gestisce queste metriche. Il budget monitoring è esattamente ciò che Kinsta APM fa automaticamente — e che devi replicare manualmente su stack self-hosted.</p>



<h2 class="wp-block-heading">Domande frequenti</h2>



<h3 class="wp-block-heading">È possibile eliminare del tutto i cron WordPress?</h3>



<p class="wp-block-paragraph">No, non del tutto. Alcune funzionalità essenziali di WordPress (publish scheduled post, transient cleanup, WooCommerce subscription renewal) richiedono cron. Puoi spostarli da WP-Cron a cron di sistema (più affidabile, più controllabile), ma non eliminarli.</p>



<h3 class="wp-block-heading">Come faccio a sapere se un cron specifico sta degradando le performance?</h3>



<p class="wp-block-paragraph">Il metodo più diretto è il grafico TTFB p95 diurno sovrapposto agli orari dei tuoi cron. Se vedi una &quot;montagna&quot; di TTFB in corrispondenza di un orario specifico ogni giorno, hai identificato il colpevole. In alternativa puoi disabilitare temporaneamente quel cron (con WP-CLI: <code>wp cron event delete your_event</code>) e osservare se il TTFB torna normale.</p>



<h3 class="wp-block-heading">È meglio WP-Cron o cron di sistema?</h3>



<p class="wp-block-paragraph">Cron di sistema. WP-Cron è affidabile solo se il sito riceve traffico (perché lo spawn dei cron avviene on-request). Se il sito è a basso traffico, WP-Cron può saltare eventi per ore. Cron di sistema + <code>wp cron event run</code> è la configurazione professionale raccomandata.</p>



<h3 class="wp-block-heading">I plugin di cache aiutano anche per i cron?</h3>



<p class="wp-block-paragraph">Sì, in modo indiretto. Se il sito live è servito da cache page (Cloudflare, Varnish, LiteSpeed Cache), i PHP-FPM worker non vengono occupati dal traffico normale. Questo libera capacità per i cron. Ma il problema dei cron pesanti resta: anche con cache piena, il cron in background usa risorse.</p>



<h3 class="wp-block-heading">Quando serve un hosting dedicato per i cron pesanti?</h3>



<p class="wp-block-paragraph">Quando il volume degli import/sync supera la capacità del tuo attuale server di gestirli nelle finestre a basso traffico senza degradare il live. Su WooCommerce, tipicamente sopra i 50.000 ordini/giorno o sopra i 100.000 SKU. In quei casi conviene separare il sito &quot;front-end&quot; (ottimizzato per velocità) dal sistema di import (ottimizzato per throughput batch).</p>



<h3 class="wp-block-heading">Lo scan AI di Wordfence rallenta davvero il sito?</h3>



<p class="wp-block-paragraph">Dipende dalla configurazione. Con scan continuo su modifiche frequenti, sì. Con scan schedulato settimanale, l&#x27;impatto è trascurabile (un&#x27;ora di I/O alto a settimana, di solito in finestra a basso traffico). Raccomandazione: scan schedulato, non continuo.</p>



<h2 class="wp-block-heading">Checklist operativa per i prossimi 14 giorni</h2>



<ul class="wp-block-list"><li>Lista completa dei cron attivi (<code>wp cron event list</code>) e frequenza di ognuno</li><li>Identifica i 3 cron più pesanti (per durata media e scritture DB)</li><li>Misura TTFB p95 baseline durante i cron con i 5 strumenti sopra</li><li>Sposta i cron pesanti in finestre a basso traffico (02:00-05:00)</li><li>Riduci batch size dei cron import/export a 25-50 con pause 2-5s</li><li>Migra cron pesanti da esecuzione php-fpm a PHP-CLI</li><li>Configura monitoring budget (script <code>background-budget-watch.sh</code>)</li><li>Aggiungi alert Slack/Telegram al superamento budget</li><li>Audita plugin di sicurezza per scan AI continui e convertili in schedulati</li><li>Verifica impatto post-modifiche con 7 giorni di monitoraggio</li></ul>



<h2 class="wp-block-heading">Riferimenti utili per approfondire</h2>



<ul class="wp-block-list"><li><a href="https://kinsta.com/blog/wordpress-background-tasks-performance/" target="_blank" rel="noopener nofollow external" data-wpel-link="external">Kinsta — WordPress performance during background activity</a> - articolo originale sui task background come fonte di degrado</li><li><a href="https://kinsta.com/blog/php-threads/" target="_blank" rel="noopener nofollow external" data-wpel-link="external">Kinsta — PHP threads explained</a> - reference tecnica PHP-FPM pool e concorrenza</li><li><a href="https://kinsta.com/blog/mysql-slow-query-log/" target="_blank" rel="noopener nofollow external" data-wpel-link="external">Kinsta — MySQL slow query log and performance</a> - come diagnosticare query lente da cron</li><li><a href="https://developer.wordpress.org/plugins/cron/" target="_blank" rel="noopener nofollow external" data-wpel-link="external">WordPress.org — WP-Cron documentation</a> - documentazione ufficiale su hook scheduling</li><li><a href="https://developer.wordpress.org/cli/commands/cron/" target="_blank" rel="noopener nofollow external" data-wpel-link="external">WordPress.org — wp cron command</a> - tutti i comandi WP-CLI per ispezionare/eseguire cron</li><li><a href="https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html" target="_blank" rel="noopener nofollow external" data-wpel-link="external">MySQL — InnoDB Locking and Transaction Model</a> - reference ufficiale lock contention</li><li><a href="https://man7.org/linux/man-pages/man1/iostat.1.html" target="_blank" rel="noopener nofollow external" data-wpel-link="external">Linux — iostat(1) man page</a> - documentazione ufficiale iostat</li><li><a href="https://developer.wordpress.org/cli/commands/cron/event/" target="_blank" rel="noopener nofollow external" data-wpel-link="external">WP-CLI — cron event command</a> - gestione eventi WP-Cron da CLI</li><li><a href="https://www.mrtux.it/wp-cron-background-wordpress-performance-guida-2026" data-wpel-link="internal" target="_self" rel="noopener">WP-Cron WordPress: ottimizzare i task background in produzione</a> - guida mrtux.it al setup corretto</li><li><a href="https://www.mrtux.it/php-thread-exhaustion-wordpress-bot-ai-2026" data-wpel-link="internal" target="_self" rel="noopener">WordPress PHP thread 2026: come i bot AI li stanno esaurendo</a> - capacity planning PHP-FPM sotto carico</li><li><a href="https://www.mrtux.it/wp-cli-2026-guida-completa-ai" data-wpel-link="internal" target="_self" rel="noopener">WP-CLI 2026 guida completa AI</a> - uso di WP-CLI come orchestratore</li><li><a href="https://www.mrtux.it/toolchain-agenzia-wordpress-moderna-2026" data-wpel-link="internal" target="_self" rel="noopener">Toolchain agenzia WordPress moderna 2026: guida pratica completa</a> - toolchain completo agenzia moderna</li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mrtux.it/wordpress-cron-performance-background-tasks-2026/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Container Docker per PHP: setup minimale per sviluppare in locale</title>
		<link>https://www.mrtux.it/container-docker-php-setup-minimale</link>
					<comments>https://www.mrtux.it/container-docker-php-setup-minimale#respond</comments>
		
		<dc:creator><![CDATA[Emilio Petrozzi]]></dc:creator>
		<pubDate>Fri, 22 May 2026 12:39:18 +0000</pubDate>
				<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[docker-compose]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PHP-FPM]]></category>
		<category><![CDATA[sviluppo locale]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.mrtux.it/?p=3384</guid>

					<description><![CDATA[Setup Docker minimale per sviluppare PHP in locale: docker-compose.yml funzionante con PHP-FPM, Nginx, MySQL, gestione permessi, estensioni e comandi essenziali.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Docker ha cambiato il modo in cui sviluppiamo applicazioni PHP. Non devi più installare PHP, MySQL, Nginx o Apache direttamente sulla tua macchina: un container gestisce tutto, e puoi distruggere e ricreare l'ambiente senza lasciare tracce.</p>


<p class="wp-block-paragraph">In questa guida ti mostro un setup minimale, funzionante e replicabile per sviluppare qualsiasi progetto PHP in locale, dal classico WordPress a un'applicazione Laravel moderna.</p>


<h2 class="wp-block-heading">Perché Docker e non XAMPP o MAMP?</h2>


<p class="wp-block-paragraph">XAMPP e MAMP vanno bene per iniziare, ma hanno limiti precisi:</p>


<ul class="wp-block-list">
<li><strong>Conflitti di versione</strong> — PHP 7.4 sulla macchina, il server di produzione usa 8.2, e il bug si vede solo in produzione</li>
<li><strong>Servizi diversi</strong> — Il tuo portatile ha MySQL, il server di produzione usa MariaDB o PostgreSQL</li>
<li><strong>Niente isolamento</strong> — Se rompi qualcosa, rischi di rompere tutto il sistema</li>
</ul>


<p class="wp-block-paragraph">Docker risolve tutto questo: ogni progetto ha il suo ambiente, con le versioni esatte che servono, e puoi condividerlo con il team senza che nessuno debba installare niente di specifico sulla propria macchina.</p>


<h2 class="wp-block-heading">Il file docker-compose.yml minimale</h2>


<p class="wp-block-paragraph">La configurazione base per un progetto PHP con database MySQL e server web Nginx richiede tre servizi: <code>php</code>, <code>mysql</code> e <code>nginx</code>.</p>


<pre class=wp-block-code><code># docker-compose.yml versione minima funzionante
version: '3.8'

services:
  app:
    image: php:8.2-fpm
    volumes:
      - ./app:/var/www/html
    depends_on:
      - db

  web:
    image: nginx:alpine
    ports:
      - '8080:80'
    volumes:
      - ./app:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app
      MYSQL_USER: developer
      MYSQL_PASSWORD: devpass
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:</code></pre>


<p class="wp-block-paragraph">Questo file definisce tre container che comunicano su una rete Docker interna. La porta 8080 sulla tua macchina viene instradata alla porta 80 del container Nginx.</p>


<h2 class="wp-block-heading">La configurazione Nginx</h2>


<p class="wp-block-paragraph">Il container Nginx ha bisogno di un file di configurazione per sapere come parlare con PHP-FPM:</p>


<pre class=wp-block-code><code># nginx.conf
server {
    listen 80;
    index index.php index.html;
    root /var/www/html;

    location / {
        try_files  / /index.php?;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME ;
        include fastcgi_params;
    }
}</code></pre>


<p class="wp-block-paragraph">Il parametro <code>fastcgi_pass app:9000</code> dice a Nginx di inviare i file PHP al container <code>app</code> sulla porta 9000, che è la porta standard di PHP-FPM.</p>


<h2 class="wp-block-heading">Primo avvio e verifica</h2>


<p class="wp-block-paragraph">Crea la struttura delle cartelle e il file <code>index.php</code> di test:</p>


<pre class=wp-block-code><code># Crea la struttura delle cartelle
mkdir -p app nginx

# Crea il file index.php di test
echo '&lt;?php
phpinfo();
' &gt; app/index.php</code></pre>


<p class="wp-block-paragraph">Ora avvia i container:</p>


<pre class=wp-block-code><code># Avvia tutti i servizi in background
docker-compose up -d

# Verifica che tutti i container siano attivi
docker-compose ps</code></pre>


<p class="wp-block-paragraph">Apri il browser e vai su <code>http://localhost:8080</code>. Se tutto funziona, vedrai la pagina <code>phpinfo()</code> con la configurazione di PHP 8.2.</p>


<h2 class="wp-block-heading">Installare le estensioni PHP necessarie</h2>


<p class="wp-block-paragraph">L'immagine ufficiale <code>php:8.2-fpm</code> è minimale. Per WordPress o Laravel servono alcune estensioni. Puoi estendere l'immagine con un <code>Dockerfile</code>:</p>


<pre class=wp-block-code><code># Dockerfile
FROM php:8.2-fpm

# Installa le estensioni necessarie
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd</code></pre>


<p class="wp-block-paragraph">Modifica il <code>docker-compose.yml</code> per usare il <code>Dockerfile</code> invece dell'immagine:</p>


<pre class=wp-block-code><code># Nel docker-compose.yml, sostituisci la riga:
#     image: php:8.2-fpm
# Con:
    build:
      context: .
      dockerfile: Dockerfile</code></pre>


<h2 class="wp-block-heading">Gestire i permessi file</h2>


<p class="wp-block-paragraph">Su Linux e macOS non avrai problemi di permessi. Su Windows con WSL2, potresti trovarti con file creati da root dentro i container. Per evitarlo:</p>


<pre class=wp-block-code><code># Imposta l'utente che matchi il tuo UID locale
services:
  app:
    user: '1003:1000'
    # ... resto della config</code></pre>


<p class="wp-block-paragraph">Oppure, più semplicemente, usa un file <code>.env</code>:</p>


<pre class=wp-block-code><code># .env
UID=1003
GID=1003</code></pre>


<h2 class="wp-block-heading">Accesso al database da fuori Docker</h2>


<p class="wp-block-paragraph">Per collegare un client MySQL esterno (come TablePlus o DBeaver) al container:</p>


<pre class=wp-block-code><code># Aggiungi al servizio db nel docker-compose.yml:
  db:
    image: mysql:8.0
    ports:
      - '3306:3306'
    # ... resto della config</code></pre>


<p class="wp-block-paragraph">Ora puoi collegarti a <code>localhost:3306</code> con le credenziali definite nel file <code>MYSQL_*</code>.</p>


<h2 class="wp-block-heading">Comandi essenziali da ricordare</h2>


<table class=wp-block-table>
<thead>
<tr>
<th>Comando</th>
<th>Funzione</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>docker-compose up -d</code></td>
<td>Avvia tutti i servizi in background</td>
</tr>
<tr>
<td><code>docker-compose down</code></td>
<td>Ferma e rimuove i container</td>
</tr>
<tr>
<td><code>docker-compose down -v</code></td>
<td>Ferma e rimuove anche i volumi (cancella il DB)</td>
</tr>
<tr>
<td><code>docker-compose exec app bash</code></td>
<td>Apre una shell dentro il container PHP</td>
</tr>
<tr>
<td><code>docker-compose logs -f</code></td>
<td>Mostra i log di tutti i container in tempo reale</td>
</tr>
<tr>
<td><code>docker-compose restart</code></td>
<td>Riavvia tutti i servizi</td>
</tr>
</tbody>
</table>


<h2 class="wp-block-heading">WordPress in Docker: la versione completa</h2>


<p class="wp-block-paragraph">Per WordPress il discorso si allunga, perché servono volumi persistenti per <code>wp-content</code>, un container per Redis (utile per la cache), e la gestione dei certificati HTTPS in sviluppo. Il risultato è un setup del genere:</p>


<pre class=wp-block-code><code># Versione WordPress completa
services:
  wordpress:
    image: wordpress:6.4-php8.2
    volumes:
      - wordpress_data:/var/www/html
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    depends_on:
      - db
      - redis

  redis:
    image: redis:7-alpine
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru

  db:
    image: mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

volumes:
  wordpress_data:
  db_data:</code></pre>


<h2 class="wp-block-heading">Conclusione</h2>


<p class="wp-block-paragraph">Docker non è magia: è un modo strutturato di dichiarare il tuo ambiente. Una volta che hai un <code>docker-compose.yml</code> funzionante, puoi distruggere tutto, ricrearlo su un'altra macchina, condividerlo con il team, e siete tutti sulla stessa configurazione. È il minimalismo che scale.</p>


<p class="wp-block-paragraph"><strong>I prossimi passi:</strong></p>


<ul class="wp-block-list">
<li>Prova ad aggiungere <strong>PHPMyAdmin</strong> come container</li>
<li>Configura <strong>MailHog</strong> per intercettare le email in sviluppo</li>
<li>Integra <strong>Blackfire</strong> o <strong>Tideways</strong> per il profiling</li>
</ul>


<h2 class="wp-block-heading">FAQ</h2>


<div class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Docker consuma molte risorse?</strong></summary><p>Dipende da cosa fai girare. Un setup PHP+Nginx+MySQL minimale usa circa 500MB di RAM in idle. In confronto a un server LAMP completo, è molto meno.</p></div>


<div class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Posso usare Docker su Windows Home?</strong></summary><p>Sì, ma devi usare WSL2 backend, non Docker Desktop Toolbox. WSL2 richiede Windows 10 21H2 o successivo, o Windows 11.</p></div>


<div class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Come faccio debug con Xdebug?</strong></summary><p>Con Xdebug attivo nel Dockerfile e una configurazione lato IDE che punta a <code>host.docker.internal:9003</code>, puoi usare breakpoints direttamente nel container. VS Code ha un launch.json già pronto per questo scenario.</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mrtux.it/container-docker-php-setup-minimale/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
