Webhooks vs polling: scegliere l'approccio giusto per l'integrazione
Webhooks vs polling: scopri come influenzano latenza, fallimenti, limiti di quota e i pattern di retry e replay che mantengono i dati sincronizzati.

Quale problema risolviamo quando sincronizziamo i dati?
Sincronizzare sembra voler dire “far apparire gli aggiornamenti velocemente”, ma il lavoro reale è più difficile: far concordare due sistemi su cosa sia vero, anche quando i messaggi arrivano in ritardo, duplicati o mancanti.
Con webhook vs polling, la differenza è come scopri che qualcosa è cambiato.
Un webhook è push. Il sistema A chiama il tuo endpoint quando succede un evento (per esempio, “invoice paid”). Il polling è pull. Il tuo sistema chiede al sistema A a intervalli: “c'è qualcosa di nuovo dall'ultima volta?”
Mantenere i sistemi sincronizzati di solito significa tracciare sia gli eventi sia lo stato. Gli eventi ti dicono cosa è successo. Lo stato ti dice come appare il record adesso. Il tempo conta perché le integrazioni raramente avvengono in ordine perfetto. Un evento “updated” può arrivare prima di “created”, o arrivare due volte, o non arrivare proprio.
L'obiettivo è avere dati corretti, non solo freschi. “Corretto” significa non perdere cambiamenti, non applicare lo stesso cambiamento due volte, poter recuperare dopo un periodo di inattività senza intervento manuale e poter dimostrare cosa è stato processato e quando.
Un esempio pratico: il tuo provider di pagamenti invia un webhook come “payment_succeeded”. La tua app crea un ordine e lo marca come pagato. Se il tuo endpoint webhook è temporaneamente giù, potresti non vedere quell'evento. Un job di polling che chiede i pagamenti aggiornati “da ieri” può colmare il gap e correggere lo stato dell'ordine.
La maggior parte delle integrazioni reali finisce per usare entrambi: webhook per la rapidità, polling per il backfill e la verifica. Il metodo è meno importante delle protezioni intorno ad esso.
Latenza e freschezza: quanto velocemente arrivano davvero gli aggiornamenti
Quando le persone confrontano webhook vs polling, spesso intendono una cosa: quanto velocemente la tua app nota una modifica altrove. Questa freschezza non è solo un vezzo. Influisce sui ticket di supporto, sul lavoro duplicato e sulla fiducia degli utenti in ciò che vedono.
Il polling ha un ritardo intrinseco perché chiedi solo a intervalli. Se fai polling ogni 5 minuti, un aggiornamento può arrivare da pochi secondi fino a quasi 5 minuti di ritardo, più il tempo di risposta dell'API. Pollare più spesso migliora la freschezza, ma aumenta le chiamate API, il costo e le probabilità di colpire i limiti di velocità.
I webhook possono sembrare quasi in tempo reale perché il provider spinge un evento non appena succede qualcosa. Ma non sono istantanei né garantiti. I provider possono raggruppare eventi, ritentare più tardi o sospendere le consegne. Anche il tuo sistema aggiunge ritardo (code in backlog, lock sul DB, deploy). Un'aspettativa più accurata è: veloci quando tutto è sano, eventualmente consistenti quando non lo è.
La forma del traffico conta. Il polling dà un carico costante e prevedibile. I webhook sono a raffica: un'ora intensa può inviare centinaia di eventi in un minuto, poi nulla per un po'. Se accetti webhook, prevedi picchi e progetta code per processare gli eventi a ritmo controllato.
Prima di progettare, scegli una finestra di freschezza target:
- Secondi: notifiche user-facing, chat, stato pagamenti
- Minuti: strumenti di supporto, viste admin, reporting leggero
- Ore: riconciliazione notturna, analytics a bassa priorità
Se il team commerciale ha bisogno che i lead nuovi compaiano entro 1 minuto, i webhook ti ci portano. Un “safety poll” ogni poche ore può comunque intercettare eventi persi e confermare lo stato finale.
Modalità di fallimento che vedrai in produzione
La maggior parte delle integrazioni fallisce in modi noiosi e ripetibili. La sorpresa non è che qualcosa si rompa. È che si rompe silenziosamente. La velocità è facile da dibattere. L'affidabilità è dove risiede il vero lavoro.
I fallimenti del polling spesso appaiono come “non abbiamo visto l'aggiornamento”, anche quando il codice sembra a posto. Timeout possono tagliare una richiesta a metà. Risposte parziali possono passare se controlli solo l'HTTP 200 e non convalidi il body. Cambiamenti nella paginazione sono comuni: un'API cambia l'ordinamento, modifica le regole di pagina o passa da numeri di pagina a cursori, e finisci per saltare o rileggere elementi. Un altro errore classico è filtrare per “updated_since” usando l'orologio locale, mancando aggiornamenti quando gli orologi sfasano o il provider usa un campo timestamp diverso.
I webhook falliscono in modo diverso. La consegna è di solito “at least once”, quindi i provider ritentano sugli errori di rete e vedrai duplicati. Se il tuo endpoint è giù per 10 minuti, potresti ricevere una raffica di eventi vecchi più tardi. Problemi di validazione della firma sono frequenti: una secret ruota, convalidi il payload grezzo sbagliato, o un proxy modifica gli header e all'improvviso eventi validi sembrano invalidi.
La modalità di fallimento condivisa in entrambi gli approcci è duplicati e consegne fuori ordine. Assumi che riceverai lo stesso evento più di una volta, eventi in ritardo, eventi fuori ordine e payload senza i campi che ti aspettavi.
Quasi mai ottieni “exactly once”. Progetta per “at least once” e rendi l'elaborazione sicura. Memorizza una chiave di idempotenza (ID evento o versione dell'oggetto fornita), ignora i duplicati e applica aggiornamenti solo se sono più recenti di quello che hai già salvato. Registra anche ciò che hai ricevuto e cosa ne hai fatto, così puoi riprodurre con fiducia invece di indovinare.
Limiti di velocità e costi: mantenere sotto controllo l'uso delle API
I rate limit sono il punto in cui webhook vs polling smette di essere una questione teorica e diventa un problema di budget e affidabilità. Ogni chiamata extra costa tempo e denaro e può danneggiare la relazione con il provider.
Il polling consuma quote perché paghi per controllare anche quando nulla è cambiato. Peggiora quando i limiti sono per utente o per token: 1.000 clienti che fanno polling ogni minuto possono sembrare un attacco, anche se ogni cliente è “beneducato”. Il polling inoltre moltiplica facilmente le chiamate (endpoint list, poi fetch dettagli per ogni item), ed è così che si raggiunge il tetto inaspettatamente.
I webhook di solito riducono le chiamate API, ma creano pressione a raffica. Un provider può consegnare migliaia di eventi in una volta dopo un outage, un import massivo o un lancio di prodotto. Alcuni ti throttleranno con 429, alcuni ritenteranno aggressivamente e alcuni scarteranno eventi se il tuo endpoint è lento. Dal tuo lato servono meccanismi di backpressure: accetta rapidamente, metti in coda il lavoro e processalo a un ritmo sicuro.
Per ridurre le chiamate senza perdere correttezza, concentra l'attenzione su alcuni pattern che funzionano nella pratica:
- Sync incrementale usando timestamp “updated since” o token di cambiamento
- Filtri lato server (iscriviti solo ai tipi di evento necessari)
- Letture e scritture in batch (recupera dettagli a blocchi, scrivi in blocco)
- Caching dei dati di riferimento stabili (piani, liste di stato, profili utente)
- Separare “real-time” da “reporting” (percorso veloce vs job notturni)
Pianifica i picchi prima che accadano. Tieni una modalità backfill dedicata che gira più lentamente, rispetta le quote e può essere messa in pausa e ripresa.
Scegliere l'approccio giusto: una guida decisionale semplice
La scelta webhook vs polling di solito si riduce a questo: ti serve velocità, o ti serve un modo semplice e prevedibile per ottenere aggiornamenti anche quando il vendor è inaffidabile?
Il polling è spesso la scelta predefinita quando il terzo non offre webhooks, o quando il tuo workflow può tollerare un ritardo. È anche più semplice da ragionare se ti serve solo una sincronizzazione giornaliera o oraria e l'API ha un filtro “updated since” chiaro.
I webhook sono la scelta predefinita quando il tempo è critico: “nuovo ordine ricevuto”, “pagamento fallito”, “ticket assegnato”. Riducendo le chiamate API sprecate possono attivare lavoro immediatamente.
Una regola pratica è usare entrambi quando la correttezza conta. Lascia che i webhook diano velocità e che il polling pulisca ciò che ti sei perso. Per esempio, processa i webhook rapidamente, poi esegui un poll schedulato ogni 15 minuti (o ogni poche ore) per riconciliare i gap causati da eventi scartati o outage temporanei.
Una guida rapida:
- Se minuti di ritardo vanno bene, inizia con il polling.
- Se gli aggiornamenti devono apparire in pochi secondi, inizia con i webhook.
- Se il vendor è instabile o gli eventi sono critici, pianifica webhook + polling.
- Se l'API è molto rate-limited, preferisci webhook più polling leggero.
- Se il volume di dati è alto, evita polling completi frequenti.
Prima di impegnarti, poni al vendor alcune domande e ottieni risposte chiare:
- Quali tipi di evento esistono e sono completi (create, update, delete)?
- Ritentano i webhook, e per quanto tempo?
- È possibile riprodurre eventi o recuperare una storia eventi per intervallo di tempo?
- Firmano le richieste webhook così puoi verificare l'autenticità?
- Supportano query “updated since” per polling efficiente?
Passo dopo passo: progettare una sincronizzazione che resti corretta
Una sincronizzazione “corretta” non è solo “i dati appaiono”. Significa che i record giusti corrispondono, l'ultima modifica vince e puoi dimostrare cosa è successo quando qualcosa va storto.
Inizia con un piano che puoi testare e monitorare:
- Definisci la fonte di verità e le regole. Scegli quale sistema possiede ogni campo. Per esempio, il CRM possiede il nome del cliente, ma il tuo tool di billing possiede lo stato dell'abbonamento. Decidi cosa significa “abbastanza fresco” (per esempio “entro 5 minuti”) e quali errori sono accettabili.
- Scegli identificatori stabili. Salva l'ID univoco del terzo insieme al tuo ID interno. Evita di usare email o nome come chiave (possono cambiare). Se disponibile, salva una versione o un timestamp “updated at” per rilevare dati più recenti.
- Pianifica l'import iniziale, poi gli aggiornamenti incrementali. Tratta il primo import come un job separato con checkpoint così puoi riprendere. Dopo di che, processa solo i cambiamenti (eventi, query “since”, o entrambi) e registra un cursore come “ultimo sync riuscito”.
- Gestisci delete e merge in modo intenzionale. Decidi se i delete rimuovono il record, lo archiviano o lo marcano inattivo. Per i merge, scegli quale ID sopravvive e mantieni una traccia di audit.
- Imposta segnali di monitoraggio. Traccia lag di sincronizzazione, chiamate fallite e code bloccate. Allerta quando il lag supera la soglia, non solo quando qualcosa va in crash.
Quando implementi, rendi visibili le scelte nel modello dati: ID esterni, timestamp, campi di stato e un posto per i checkpoint di sync. Quella struttura è ciò che mantiene la sincronizzazione corretta quando il mondo reale diventa disordinato.
Idempotenza e ordinamento: il cuore delle integrazioni affidabili
Se costruisci integrazioni webhook vs polling a sufficienza, una regola appare sempre: vedrai duplicati, ritentativi e aggiornamenti fuori ordine. Se la tua sincronizzazione non può rielaborare lo stesso messaggio in sicurezza, nel tempo deriverà.
L'idempotenza significa “stesso input, stesso risultato”, anche se arriva due volte. Tratta ogni evento in ingresso come “forse ripetuto” e progetta il tuo handler in modo sicuro. Un pattern comune è: calcola una chiave di dedup, controlla se l'hai già processata, poi applica le modifiche.
Le chiavi di dedup hanno compromessi. Un ID evento è l'ideale quando il provider lo fornisce. In assenza, puoi usare una versione dell'oggetto (per esempio una revisione incrementale). Le finestre di timestamp come “ignora ripetizioni per 10 minuti” sono fragili perché gli arrivi in ritardo succedono.
L'ordinamento è l'altra metà. L'ordinamento globale è raro, quindi punta all'ordinamento per oggetto. Applica aggiornamenti a un singolo ticket, fattura o cliente solo se la versione è più recente di quella salvata. Se non hai una versione, usa last-write-wins con una regola chiara (per esempio, vince il newer updated_at) e accetta che lo sfasamento degli orologi possa ancora creare casi limite.
Conserva abbastanza informazioni per recuperare e riprodurre senza indovinare:
- Una “last seen” per oggetto (version o updated_at)
- Un cursore o checkpoint dell'ultimo processato per i job di polling
- Una tabella di ID evento processati (con regole di retention se cresce velocemente)
- Il payload grezzo per un periodo breve, così puoi rilanciare fix
Esempio: un webhook di pagamento Stripe arriva due volte, poi un aggiornamento “paid” arriva prima dell'evento “created”. Se salvi la versione dello stato della fattura e ignori aggiornamenti più vecchi, arrivi al risultato corretto.
Pattern di retry e replay che prevengono la deriva silenziosa dei dati
La maggior parte delle integrazioni fallisce silenziosamente. Un webhook arriva in ritardo, un job di polling colpisce un limite, o la tua app scade mentre salva. Senza retry e replay, i sistemi lentamente divergono finché un cliente non si lamenta.
Retry webhook: accetta in fretta, processa in sicurezza
I provider di solito ritentano quando non ritorni un codice HTTP di successo abbastanza velocemente. Tratta la richiesta webhook come una notifica di consegna, non come il luogo dove fare lavoro pesante.
Un pattern pratico per i webhook:
- Rispondi rapidamente con un 2xx dopo la validazione di base (firma, schema, timestamp).
- Salva l'evento con un ID unico e marcato come pending.
- Processa in modo asincrono con un worker e traccia i tentativi.
- Sugli errori temporanei, ritenta dopo. Sugli errori permanenti, ferma e allerta.
- Usa 4xx per dati errati e 5xx solo per veri problemi server.
Questo evita un errore comune: pensare che “webhook ricevuto” significhi “dati sincronizzati”.
Retry polling: sii gentile con l'API
Il polling fallisce in modo diverso. Il rischio è una mandria di retry dopo un breve outage, che peggiora i rate limit. Usa exponential backoff con jitter e tieni un cursore “since” così non riesamini tutto.
Quando non puoi processare qualcosa ora, mettila in una dead-letter queue (o tabella) con la ragione. Questo ti dà un posto sicuro per ispezionare, correggere regole di mapping e rieseguire senza indovinare cosa è andato perso.
Il replay è come guarisci dopo eventi persi. Una strategia di replay semplice:
- Scegli una finestra temporale (es. ultime 24 ore) o un set di record interessati.
- Rifetch lo stato corrente dal provider.
- Re-applica gli aggiornamenti in modo idempotente e correggi le discrepanze.
- Registra cosa è cambiato e perché.
Esempio: il tuo provider di billing invia “invoice.paid”, ma il tuo DB era lockato per 30 secondi. Metti l'evento in dead-letter, poi riproduci recuperando la fattura e lo stato di pagamento e aggiornando i tuoi record per farli combaciare.
Errori comuni e come evitarli
La maggior parte dei bug di sincronizzazione non sono “grandi problemi architetturali”. Sono piccole assunzioni che diventano deriva silenziosa, record duplicati o aggiornamenti persi.
Alcuni che ricorrono spesso:
- Fare polling troppo spesso senza filtri incrementali. Traccia un cursore (updated_at, event ID, page token) e chiedi solo i cambiamenti dall'ultimo run riuscito.
- Trattare i webhook come consegna garantita. Mantieni un job di backfill che ricontrolli la storia recente (per esempio ultime 24-72 ore) e riconcilia ciò che hai perso.
- Ignorare i duplicati. Rendi ogni scrittura idempotente. Salva l'ID evento del provider (o un ID esterno stabile) e rifiuta di applicare lo stesso cambiamento due volte.
- Accettare chiamate webhook senza verifica. Verifica il token di firma o il metodo di verifica offerto dal provider.
- Operare alla cieca sulla salute della sync. Traccia lag, dimensione del backlog, ultimo run riuscito e tassi di errore. Allerta quando il lag supera una soglia.
Molti dibattiti “webhook vs polling” mancano il punto: l'affidabilità deriva dalle protezioni intorno a ciascun metodo. Un webhook di pagamento può arrivare due volte o in ritardo. Se il tuo sistema crea record direttamente dal webhook senza idempotenza, puoi inviare messaggi o addebitare un cliente due volte.
Checklist rapida per un'integrazione sana
I controlli quotidiani assomigliano indipendentemente dall'uso di webhook, polling o entrambi. Vuoi sapere se i dati sono freschi, se gli errori si accumulano e se puoi recuperare pulitamente.
Una checklist rapida che puoi eseguire in pochi minuti:
- Freschezza: confronta “ultimo evento ricevuto” o “ultimo poll completato” con il lag atteso.
- Fallimenti: cerca retry in crescita o job che non si muovono più. Associa i conteggi di errore a un timestamp di “ultima riuscita”.
- Quote: controlla quante chiamate API hai usato e quanto resta. Se sei vicino al limite, rallenta il polling e metti le richieste in batch.
- Correttezza: verifica a campione totali tra sistemi (per esempio “ordini di oggi”) e controlla alcuni record recenti.
- Prontezza al recupero: conferma di poter rielaborare una finestra recente senza duplicati o aggiornamenti mancati.
Una buona abitudine è riprodurre periodicamente un periodo noto di traffico intenso in modo controllato e confermare che i risultati corrispondano alla produzione.
Esempio: mescolare webhook e polling in un workflow realistico
Immagina un piccolo team SaaS che deve mantenere sincronizzati tre sistemi: un CRM (contatti e deal), Stripe payments (charge e refund) e uno strumento di supporto (stato ticket).
Usano un setup webhook-first per tutto ciò che richiede reazioni rapide. Gli eventi CRM aggiornano il record cliente e attivano task interni. I webhook di Stripe creano fatture, sbloccano funzionalità dopo il pagamento e marcano account in ritardo sui failed charge. Per lo strumento di supporto usano webhook se disponibili, ma mantengono anche un polling schedulato perché gli stati dei ticket possono cambiare in blocco.
Trattano il polling come una rete di sicurezza, non come il motore principale. Ogni notte, un job di riconciliazione prende le ultime 24 ore di cambiamenti attraverso i sistemi e le confronta con ciò che l'app ha salvato.
Poi succede un outage reale: il loro endpoint webhook è giù per 20 minuti durante un deploy.
- CRM e Stripe ritentano la consegna per un po'.
- Alcuni eventi arrivano in ritardo, alcuni fuori ordine e alcuni possono scadere.
- Il poll di riconciliazione rileva un gap (ID evento mancanti o totali non corrispondenti) e backfilla i cambiamenti mancanti.
Cosa loggano: ID evento in ingresso, timestamp del provider, ID record interno e il risultato finale (created, updated, ignored). Cosa scatena un'alert: ripetuti fallimenti webhook, un picco di retry o la riconciliazione che trova oltre una piccola soglia di aggiornamenti mancanti.
Prossimi passi: implementare, monitorare e iterare
Un default pratico per la maggior parte dei team è semplice: usa webhook per l'immediatezza e tieni un piccolo job di polling per la riconciliazione. I webhook portano i cambiamenti rapidamente. Il polling cattura ciò che ti sei perso a causa di outage, sottoscrizioni mal configurate o provider che occasionalmente scartano eventi.
Rendi prima la sincronizzazione corretta, poi veloce. Tratta ogni cambiamento in ingresso come qualcosa che può essere applicato più di una volta in sicurezza.
Tre azioni da fare subito:
- Mappa eventi e campi del provider al tuo modello interno, inclusi cosa significano per te “delete”, “refund” o “status change”.
- Progetta l'idempotenza fin dal primo giorno: salva un ID evento esterno o una versione e rendi ogni aggiornamento sicuro da replayare senza duplicati.
- Aggiungi il replay intenzionale: tieni un cursore “since last seen” o un poll per finestre temporali e costruisci un'interfaccia admin per rieseguire un intervallo quando qualcosa sembra sbagliato.
Una volta in funzione, il monitoraggio è ciò che lo mantiene in funzione. Traccia il tasso di consegna webhook, i fallimenti per motivo (timeouts, 4xx, 5xx) e quanto è indietro il tuo poll di riconciliazione. Allerta su “nessun evento ricevuto” così come su “troppi eventi ricevuti”.
Se preferisci costruire questo senza scrivere da zero un backend completo, AppMaster (appmaster.io) è un'opzione no-code che ti permette di modellare dati, creare endpoint webhook e progettare flussi di retry/replay con strumenti visuali, generando comunque codice sorgente reale per il deployment.


