---
title: "Subentro su Laravel 10 con Horizon fermo e scheduler silente: come ho recuperato un SaaS torinese di fleet management nei primi cinque giorni dopo la chiusura improvvisa del team di sviluppo esterno"
description: "Cliente torinese 2025, Laravel 10 su Hetzner AX52, Horizon fermo da 3 settimane, scheduler silente, 47 tenant e 13.000 clienti finali impattati. Il recupero reale in cinque giorni."
canonical: "https://www.mauriziofonte.it/blog/post/subentro-progetto-laravel-unmanaged-senza-sviluppatore.html"
author: "Maurizio Fonte"
date: "2025-06-18T08:47:12+02:00"
modified: "2026-04-14T17:48:55+02:00"
section: "Incident Response"
tags: ["Incident Response", "VPS & Hosting"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[Incident Response](https://www.mauriziofonte.it/blog/cat/incident_response.html) [VPS & Hosting](https://www.mauriziofonte.it/blog/cat/vps.html)

# [Subentro su Laravel 10 con Horizon fermo e scheduler silente: come ho recuperato un SaaS torinese di fleet management nei primi cinque giorni dopo la chiusura improvvisa del team di sviluppo esterno](https://www.mauriziofonte.it/blog/post/subentro-progetto-laravel-unmanaged-senza-sviluppatore.html)

Mercoledì 18 Giugno 2025, alle 08:47 ![Subentro su Laravel 10 con Horizon fermo e scheduler silente: come ho recuperato un SaaS torinese di fleet management nei primi cinque giorni dopo la chiusura improvvisa del team di sviluppo esterno](https://www.mauriziofonte.it/image/001810200-subentro-progetto-laravel-unmanaged-senza-sviluppatore.jpg)

## Perché un Laravel "che gira" può essere in realtà già morto dentro da tre settimane?

Il 3 giugno 2025 mi ha contattato il CTO (ex-sviluppatore senior, promosso sei mesi prima) di una società torinese che sviluppa e commercializza un SaaS B2B di fleet management per aziende di trasporto merci: 47 tenant attivi nel nord Italia, circa 13.000 autisti tra tutti i tenant, una media di 260.000 posizioni GPS raccolte ogni giorno e poi processate in batch per reportistica e fatturazione al tenant. L'applicazione era su un Hetzner AX52 nel datacenter di Falkenstein (Ryzen 7 7700, 64 GB RAM, RAID 1 NVMe) con un secondo nodo Hetzner Cloud CX42 dedicato a Redis e al worker Horizon, tutto orchestrato via un unico `docker-compose` in produzione - scelta discutibile ma funzionante. Lo stack applicativo era Laravel 10.48, PHP 8.2, MySQL 8.0, Redis 7, [Laravel Horizon](https://laravel.com/docs/10.x/horizon) per la gestione delle queue, [Spatie Multi-Tenancy](https://spatie.be/docs/laravel-multitenancy) per isolare i database dei singoli tenant.

Il team di sviluppo era un vendor esterno - una società di Bangalore con cinque sviluppatori dedicati al progetto - che a fine maggio 2025 aveva improvvisamente smesso di rispondere alle email. Il CTO aveva scoperto dopo quattro giorni di silenzio che la società stava attraversando una ristrutturazione interna e non avrebbe più lavorato su progetti esteri con contratti in corso, senza avvisare i clienti. La parte grave non era la chiusura del rapporto in sé - fastidiosa ma gestibile - ma la scoperta, avvenuta il 1° giugno quando i primi tenant hanno iniziato a lamentarsi, che il SaaS stava girando solo apparentemente: il frontend rispondeva normalmente, gli autisti potevano loggarsi e vedere i loro turni, ma nessuna notifica transazionale partiva più da settimane, nessun report giornaliero veniva generato, nessuna fattura mensile era stata emessa per il mese di maggio, e l'export contabile verso i gestionali dei tenant era fermo. Il sistema era clinicamente morto da circa tre settimane, ma nessuno se n'era accorto perché la parte visibile continuava a funzionare.

In cinque giorni ho riportato tutto a regime: audit completo del codice, identificazione del perché Horizon fosse fermo, riparazione dello stato Redis, ripristino del cron dello scheduler, rotazione dei segreti e documentazione operativa consegnata al CTO. Il costo in termini di ore dirette è stato contenuto, ma ciò che conta è che nessun tenant ha chiesto il recesso e le fatture di maggio sono state emesse con un ritardo di quindici giorni invece che di due mesi. In questo articolo racconto esattamente come, perché lo scenario "il SaaS sembra funzionare ma non sta facendo metà del suo lavoro" è molto più comune di quanto ci si immagini, e la diagnosi richiede un approccio specifico che non è quello dell'infrastruttura classica.

> Stai cercando un **Consulente Laravel** esperto per gestire un subentro su un progetto abbandonato dal team originario? Nel mio [profilo professionale](https://www.mauriziofonte.it/pages/about) trovi l'esperienza concreta in recupero di progetti Laravel in produzione, hardening e gestione di crisi tecniche in ambienti multi-tenant. [Contattami per una consulenza diretta](https://www.mauriziofonte.it/pages/contattami).

## I primi trenta minuti: accertarsi che qualcosa stia girando davvero

La prima cosa che ho fatto, dopo essermi loggato come utente sudo sul server (il CTO aveva le credenziali, il team indiano non le aveva ruotate al momento della chiusura - un regalo non voluto), è stata non toccare niente. Letteralmente niente. L'istinto in questi casi è far partire `php artisan horizon` e sperare per il meglio, ma farlo significa perdere la possibilità di diagnosticare lo stato reale del sistema e capire cosa si è rotto quando. In Laravel 10 con Horizon e uno scheduler attivo, la prima batteria di comandi che lancio è questa, tutti in sola lettura:

```bash
cd /var/www/app
php artisan --version
php artisan about
php artisan horizon:status
php artisan queue:monitor default,notifications,reports,exports
php artisan schedule:list
php artisan schedule:test
grep -r "->cron\|->daily\|->hourly" app/Console/Kernel.php
ls -la storage/logs/ | tail -20
tail -200 storage/logs/laravel.log
tail -200 storage/logs/horizon.log
```

I risultati erano molto chiari e molto preoccupanti. `horizon:status` restituiva "inactive". `schedule:list` mostrava 34 task pianificati (generazione report giornalieri, batch di fatturazione, sync con GPS provider, cleanup sessioni, backup tenant) ma nessun task era stato eseguito dopo il 14 maggio. `queue:monitor` mostrava code con migliaia di job in waiting state e nessun worker attivo. L'ultimo log in `laravel.log` era datato 14 maggio 2025 alle 17:42 - e il file era piccolissimo, appena 2 MB. Questo è stato il primo segnale che mi ha fatto rizzare i capelli, perché un SaaS con 47 tenant attivi genera facilmente centinaia di MB di log al giorno in un'applicazione Laravel normale.

Il secondo passo è stato controllare il cron del sistema operativo, perché lo scheduler Laravel non può funzionare senza un `* * * * *` che chiami `php artisan schedule:run` ogni minuto. Il `crontab -l` dell'utente `www-data` era vuoto. Il `crontab -l` di root pure. Il `/etc/cron.d/` conteneva solo file standard Debian. Qualcuno - o qualcosa - aveva disattivato il cron dello scheduler, ma non era chiaro quando né chi. Ho cercato nei file di sistema e ho trovato un file `/etc/cron.d/laravel-schedule.disabled` con timestamp 14 maggio 2025, ore 17:38 - esattamente quattro minuti prima dell'ultimo log di `laravel.log`. Qualcuno aveva rinominato quel file intenzionalmente, quel giorno, in quel preciso momento.

## Ricostruire la sequenza: cosa è successo il 14 maggio alle 17:38?

A questo punto ero chiaramente in territorio forensics. Ho dedicato le ore successive a ricostruire la sequenza degli eventi con gli strumenti standard Linux: `last` per gli ultimi login, `/var/log/auth.log` per i tentativi SSH, `/var/log/syslog` per i comandi sudo eseguiti, storia bash di ogni utente con shell (`cat /home/*/.bash_history 2>/dev/null`), audit di `/root/.bash_history`. La ricostruzione è stata semplice perché il team indiano aveva un paio di utenti SSH shared (pessima pratica, ma questo è un altro discorso) e dalle bash history ho visto esattamente i comandi eseguiti il 14 maggio pomeriggio.

Quello che era successo era banale quanto catastrofico: uno degli sviluppatori del team indiano aveva eseguito un deploy di una modifica al sistema di generazione report. Durante il deploy, aveva sospeso scheduler e Horizon per evitare conflitti con la migrazione database in corso. Il deploy aveva fallito a metà, probabilmente per un problema di connessione o una disattenzione. Lo sviluppatore aveva lasciato tutto in stato sospeso con l'intenzione di riprendere il giorno dopo. Il giorno dopo, però, la sua società aveva ricevuto la comunicazione interna di ristrutturazione, e nessuno ha mai ripreso quel deploy. Lo scheduler Laravel è rimasto disattivato a livello di cron di sistema, Horizon è rimasto fermo, e il SaaS ha continuato a girare servendo il frontend ma senza processare nulla in background per tre settimane.

Questa ricostruzione non è accademica: è fondamentale perché determina cosa puoi riavviare in sicurezza e cosa invece è rischioso far ripartire. Se lo scheduler è fermo da tre settimane, riavviarlo significa far partire improvvisamente 34 task che devono recuperare tre settimane di lavoro - ci sono batch di fatturazione, di reportistica, di export contabile che potrebbero rieseguirsi e generare duplicati o corrompere stato. L'approccio sbagliato è "riavvio e vediamo cosa succede". L'approccio giusto è censire ogni task dello scheduler, decidere per ciascuno se vada fatto partire subito, posticipato, o saltato del tutto, e solo dopo procedere al ripristino ordinato.

## Audit dei job schedulati: decidere cosa rieseguire e cosa saltare

Il mattino del 4 giugno ho passato tre ore sul `Kernel.php` dello scheduler per capire ogni singolo task. In un SaaS medio come questo ci sono quattro categorie di job schedulati, e per ognuna la decisione è diversa. I job **idempotenti e temporali** (tipo cleanup sessioni scadute, purge cache, sync configurazioni tenant) vanno fatti partire subito senza recupero: saltare tre settimane di cleanup non è un problema, ripartono puliti. I job **transazionali con effetti esterni** (tipo invio email di notifica, generazione fatture, push verso gestionali tenant) vanno analizzati uno per uno: alcuni vanno rieseguiti recuperando il backlog (le fatture di maggio vanno emesse), altri vanno saltati (le notifiche email vecchie di tre settimane non hanno senso recuperarle). I job **di aggregazione dati** (tipo report giornalieri, metriche dashboard) vanno decisi con il cliente perché toccano dati che l'utente finale vede. I job **di integrazione con API esterne** (sync GPS provider, webhook a terze parti) vanno coordinati con i provider esterni per evitare spike di richieste che li facciano sospendere.

Per la fatturazione ho concordato con il CTO di generare manualmente le fatture del mese di maggio con una variante del job di fatturazione che saltasse il controllo idempotente su `billing_period_id` (perché volevamo rieseguirlo forzando il periodo `2025-05`). Per i report giornalieri abbiamo deciso di rigenerarne solo gli ultimi 7 giorni - quelli più probabilmente consultati dai tenant - e pubblicare un avviso nell'area cliente spiegando il disservizio. Per le email transazionali abbiamo saltato completamente tutto il backlog. Per la sync GPS abbiamo fatto un reset dello stato e lasciato che il giorno successivo ripartisse normalmente. Questa pianificazione è stata scritta in un foglio condiviso e approvata dal CTO prima di qualsiasi esecuzione.

## Ripristino ordinato: cron, Horizon, supervisor, lock Redis

Il ripristino operativo è stato l'operazione meno interessante di tutto l'intervento, proprio perché ben pianificato. In ordine: prima ho ripristinato il cron dello scheduler con la riga standard Laravel (`* * * * * cd /var/www/app && php artisan schedule:run >> /dev/null 2>&1`), ma ho commentato tutti i task nello scheduler Laravel lasciando attivi solo quelli idempotenti e sicuri. Questo mi permetteva di avere lo scheduler "vivo" senza far partire nulla di pericoloso. Poi ho fatto partire Horizon, controllando lo stato delle code Redis. Horizon era gestito da Supervisor via un file di configurazione in `/etc/supervisor/conf.d/horizon.conf` che era ancora presente ma disabilitato (il team indiano aveva fatto `supervisorctl stop horizon` il 14 maggio e non l'aveva più riavviato). La configurazione era standard:

```ini
[program:horizon]
process_name=%(program_name)s
command=php /var/www/app/artisan horizon
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/supervisor/horizon.log
stopwaitsecs=3600
```

Prima di riavviare Horizon ho fatto un audit manuale dello stato Redis per capire cosa ci fosse nelle code, usando `redis-cli` direttamente sul nodo CX42. Le code `default` e `notifications` avevano migliaia di job in attesa, la maggior parte dei quali erano email transazionali vecchie di settimane che il CTO aveva deciso di non rieseguire. Ho svuotato quelle due code con `redis-cli FLUSHDB` mirato (dopo aver fatto backup dello stato completo con `redis-cli --rdb /root/redis-backup-pre-cleanup.rdb`), ho lasciato intatte le code `reports` e `exports` perché contenevano job che volevamo invece rieseguire, e poi ho fatto ripartire Horizon con `supervisorctl start horizon`. Il dashboard Horizon su `/horizon` (protetto dal middleware `Horizon::auth()`) ha mostrato immediatamente i worker attivi e l'inizio del processamento del backlog residuo.

Lo scheduler Laravel l'ho riabilitato task per task nell'arco delle ore successive, controllando a ogni abilitazione che il task non generasse errori e che gli effetti fossero quelli attesi. Nel tardo pomeriggio del 4 giugno lo scheduler era completamente operativo, tutti i task critici erano ripartiti, e i primi tenant hanno iniziato a ricevere i report aggiornati dopo oltre tre settimane di buco. Questo approccio progressivo di riabilitazione è esattamente il motivo per cui in [questo approfondimento sulla modernizzazione dei job in coda Laravel con queue fake e testing](https://www.mauriziofonte.it/blog/post/modernizzare-job-coda-laravel-testing-queue-fake-interactions-l12.html) insisto sull'importanza del testing strutturato delle queue anche su progetti ereditati - senza una strategia di testing puoi solo sperare, e sperare non è una strategia.

## Rotazione segreti e chiusura degli accessi al team precedente

Il 5 giugno è stato dedicato alla rotazione integrale dei segreti e all'inventario completo degli accessi. In un progetto Laravel multi-tenant come questo, i segreti sono parecchi e sparsi: `APP_KEY` (critica perché se la ruoti senza attenzione decifri male tutte le colonne encrypted esistenti, come le credenziali dei gestionali dei tenant), `DB_PASSWORD` del database principale e dei database per-tenant, `REDIS_PASSWORD`, chiavi API dei provider GPS esterni, chiavi API di Stripe per i pagamenti ricorrenti, chiavi API del provider email transazionale ([Postmark](https://postmarkapp.com/developer/user-guide/send-email-with-api) nel loro caso), token delle webhook verso i gestionali tenant. L'`APP_KEY` non l'ho toccata perché Laravel la usa per cifrare dati a riposo nel database via il cast `encrypted`, e ruotarla richiede una procedura specifica di re-encryption di tutti i campi cifrati che va pianificata con attenzione (la farò come intervento separato, non in emergenza).

Tutti gli altri segreti li ho ruotati in sequenza, con rollout graduale per evitare di rompere connessioni attive: prima il nuovo segreto è aggiunto in parallelo al vecchio (quando il provider lo supporta), poi l'applicazione viene fatta puntare al nuovo, poi il vecchio viene revocato. Per MySQL e Redis, dove questo pattern non è direttamente supportato, ho fatto le rotazioni durante finestre di basso traffico notturno e ho verificato a ogni step che Horizon e scheduler continuassero a funzionare. Il file `.env` finale l'ho salvato in due copie: una sul server in `/var/www/app/.env` con permessi `640 www-data:www-data`, e una cifrata con `age` nel password manager del CTO come backup. In parallelo, ho rimosso gli utenti SSH del team indiano (`lastlog` ha confermato che non si erano loggati da fine maggio), ruotato la password di root SSH anche se l'accesso root SSH era disabilitato per policy (sempre meglio), e disattivato tutti i token API personali dei loro sviluppatori su GitLab.

## Documentazione operativa e fine dell'intervento

Il sesto e ultimo giorno - il 6 giugno - l'abbiamo dedicato alla documentazione operativa, perché un Laravel multi-tenant recuperato senza un runbook rimane una trappola per il futuro. Il runbook finale conteneva: architettura sintetica del SaaS (tenant, nodi Hetzner, servizi), inventario completo dei job schedulati con descrizione di cosa fanno e dipendenze, inventario delle code Horizon con priorità e worker count, procedura di deploy sicuro (con freeze dello scheduler durante le migration, come avrebbe dovuto fare il team indiano il 14 maggio ma senza lasciare le cose a metà), procedura di [deploy Laravel automatizzato con Deployer](https://www.mauriziofonte.it/blog/post/automatizzare-deploy-laravel-server-linux-hetzner-ovh-con-deployer.html) che ho iniziato a impostare nei giorni successivi per eliminare la fragilità dei deploy manuali, procedura di gestione incidenti per il caso in cui Horizon si fermi di nuovo, contatti e accessi di emergenza.

Il CTO ha ricevuto anche una mappa del [debito tecnico post-subentro da gestire nei 90 giorni successivi](https://www.mauriziofonte.it/blog/post/gestire-debito-tecnico-server-linux-hetzner-ovh-post-subentro.html): quali sono i punti fragili del codice lasciato dal team precedente, quali refactoring sono prioritari, quali componenti rimpiazzare gradualmente (ad esempio il gestore di code personalizzato che il team indiano aveva affiancato a Horizon senza un motivo chiaro). Questo non era parte del recupero in emergenza ma dell'onboarding strategico per il nuovo ruolo di consulente tecnico che il CTO voleva assegnarmi nei mesi successivi. Per il tema più ampio del passaggio di consegne quando il team originario sparisce, ho scritto separatamente un approfondimento sul [subentro senza sviluppatore manutentore su codice PHP legacy](https://www.mauriziofonte.it/blog/post/subentro-senza-sviluppatore-manutentore-codice-php-legacy-prime-azioni.html) che copre anche scenari non Laravel.

## Cosa salvare di questa esperienza per chi gestisce SaaS Laravel su server unmanaged

La lezione principale di questo subentro è che un SaaS Laravel "funzionante" dal punto di vista del frontend può essere in realtà profondamente rotto sul piano dei processi in background, e nessuno se ne accorge finché non arrivano le prime lamentele dei clienti finali. La soluzione non è un monitoring migliore - anche se un dashboard [Horizon con notifiche Slack](https://laravel.com/docs/10.x/horizon#notifications) aiuta - ma una disciplina di deploy che non lasci mai stati intermedi senza un responsabile. Il 14 maggio alle 17:38 c'era uno sviluppatore in Bangalore che aveva lasciato lo scheduler sospeso con l'intenzione di riprendere il giorno dopo. Il giorno dopo quello sviluppatore non lavorava più su quel progetto, e nessuno si è chiesto "chi era incaricato di riavviare lo scheduler?". La mia raccomandazione universale in questi casi è impostare un [piano di disaster recovery operativo](https://www.mauriziofonte.it/blog/post/piano-disaster-recovery-php-continuita-operativa-pmi.html) che contempli esplicitamente lo scenario "il team di sviluppo smette di rispondere", con un runbook che qualsiasi persona tecnicamente competente possa eseguire partendo da zero informazioni.

Se gestisci un progetto Laravel in produzione su server Hetzner, OVH o Aruba, con Horizon, scheduler e code in background, e ti trovi in una situazione in cui il team originario è sparito oppure vuoi prevenire lo scenario costruendo subito le procedure giuste, [contattami direttamente](https://www.mauriziofonte.it/pages/contattami). Posso aiutarti a fare l'audit completo del progetto, identificare i punti fragili del ciclo di processing background, impostare monitoring e alerting su Horizon, e costruire un runbook operativo che permetta alla tua azienda di sopravvivere anche alla scomparsa improvvisa del team tecnico. Nel [mio profilo professionale](https://www.mauriziofonte.it/pages/about) trovi i dettagli dell'esperienza concreta su SaaS Laravel multi-tenant e gestione di crisi in produzione.

Dall'articolo al lavoro vero

Questo problema di sicurezza, sul tuo sistema

Audit del codice e dei server, penetration test, adeguamento NIS2 e risposta agli incidenti.

[Vedi come lavoro sulla sicurezza](https://www.mauriziofonte.it/servizi/consulenza-cybersecurity-nis2.html) Ultima modifica: Martedì 14 Aprile 2026, alle 17:48 [« Articolo precedenteSviluppatore sparito con le credenziali del server: come ho restituito a un cliente genovese il controllo di un Hetzner AX51-NVMe in sei giorni tra trasferimento di proprietà, rescue boot e audit completo17 Giugno 2025](https://www.mauriziofonte.it/blog/post/interventi-emergenza-server-dedicato-unmanaged.html)[Articolo successivo »Laravel in maintenance mode da tre mesi su Contabo VPS L: come ho riportato online un e-commerce HoReCa bolognese in quattro giorni tra migration orfane, storage saturo e code bloccate19 Giugno 2025](https://www.mauriziofonte.it/blog/post/ripresa-operativita-vps-unmanaged-laravel.html)

### Articoli correlati a Subentro su Laravel 10 con Horizon fermo e scheduler silente: come ho recuperato un SaaS torinese di fleet management nei primi cinque giorni dopo la chiusura improvvisa del team di sviluppo esterno

- [Backup Laravel su VPS che falliscono da tre mesi senza che nessuno se ne accorga: diagnosi e strategia di ripristino](https://www.mauriziofonte.it/blog/post/backup-fallito-strategia-urgente-laravel-vps.html)

  Su un VPS Contabo con un gestionale Laravel 10, i backup automatici con spatie/laravel backup fallivano da tre mesi disco pieno sullo storage · 3 Luglio 2025

  ![Backup Laravel su VPS che falliscono da tre mesi senza che nessuno se ne accorga: diagnosi e strategia di ripristino](https://www.mauriziofonte.it/image/001950070-backup-fallito-strategia-urgente-laravel-vps.jpg)
- [Task scheduling robusto in Laravel: horizon, workers e gestione dei fallimenti](https://www.mauriziofonte.it/blog/post/task-scheduling-robusto-laravel-horizon-workers-gestione-fallimenti.html)

  Un batch notturno di fatturazione che falliva silenziosamente una volta ogni tre giorni senza che nessuno lo scoprisse fino ai reclami dei clienti. · 15 Gennaio 2026

  ![Task scheduling robusto in Laravel: horizon, workers e gestione dei fallimenti](https://www.mauriziofonte.it/image/003560070-task-scheduling-robusto-laravel-horizon-workers-gestione-fallimenti.jpg)
- [Multi-tenancy in Laravel: strategie di isolamento dati per SaaS PHP](https://www.mauriziofonte.it/blog/post/multi-tenancy-laravel-strategie-isolamento-dati-saas-php.html)

  Ho costruito tre SaaS multi tenant in Laravel negli ultimi tre anni con approcci diversi: database per tenant massimo isolamento, costo elevato · 6 Febbraio 2026

  ![Multi-tenancy in Laravel: strategie di isolamento dati per SaaS PHP](https://www.mauriziofonte.it/image/002540070-multi-tenancy-laravel-strategie-isolamento-dati-saas-php.jpg)
- [Ottimizzare cron job su VPS unmanaged: tecniche avanzate per prevenire colli di bottiglia e downtime](https://www.mauriziofonte.it/blog/post/ottimizzare-cron-job-vps-unmanaged.html)

  Un VPS Hetzner con Laravel e 23 cron job tutti schedulati alle 02:00: load average a 47, MySQL in lock wait, import listini che si sovrappongono · 10 Luglio 2025

  ![Ottimizzare cron job su VPS unmanaged: tecniche avanzate per prevenire colli di bottiglia e downtime](https://www.mauriziofonte.it/image/002050070-ottimizzare-cron-job-vps-unmanaged.jpg)
- [Laravel Horizon per chiamate LLM asincrone: retry strategy, cost tracking, timeout management in produzione](https://www.mauriziofonte.it/blog/post/laravel-horizon-llm-chiamate-asincrone-retry-cost-tracking-timeout.html)

  Le chiamate LLM sono lente 5 30 secondi , costose € per token , soggette a errori transitori rate limit, 529 overloaded . Farle sincrone nel · 4 Marzo 2026

  ![Laravel Horizon per chiamate LLM asincrone: retry strategy, cost tracking, timeout management in produzione](https://www.mauriziofonte.it/image/003920070-laravel-horizon-llm-chiamate-asincrone-retry-cost-tracking-timeout.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "Subentro su Laravel 10 con Horizon fermo e scheduler silente: come ho recuperato un SaaS torinese di fleet management nei primi cinque giorni dopo la chiusura improvvisa del team di sviluppo esterno", mauriziofonte.it, 2025. https://www.mauriziofonte.it/blog/post/subentro-progetto-laravel-unmanaged-senza-sviluppatore.html

Pubblicato: 2025-06-18 · Aggiornato: 2026-04-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
