
Marketing data pipeline: end-to-end architecture
Designing end-to-end data architecture for marketing: sources, modeling, and activation.
What you will learn
- Disegnare i cinque strati della pipeline, dall'ingestione grezza ai marts di economia e coorte
- Normalizzare la spesa unificata con valute al cambio del giorno e quadratura entro tolleranza
- Calcolare il CAC payback corretto per margine e riconciliare spesa, eventi e ordini con contratti di freschezza
Marketing data pipeline: end-to-end architecture
Questa lezione appartiene al binario tabellare: il lavoro si svolge tra tabelle di staging, marts e controlli di quadratura, più che tra modelli statistici. Il lunedì mattina il responsabile performance apre tre dashboard e trova tre verità diverse: Meta dichiara 412 conversioni, GA4 ne attribuisce 289 allo stesso periodo, il backend ne fattura 247. Nessuno ha sbagliato a leggere. Hanno solo letto tre stadi diversi della stessa storia, con finestre, definizioni e ritardi diversi. Una marketing data pipeline serve a questo: rende esplicito ogni passaggio tra click e incasso, così la discussione passa da quale sia il numero giusto a quale decisione prendere con incertezza dichiarata.
Il sistema che dichiara ogni numero
La marketing data pipeline è il sistema versionato che porta spesa, eventi e ordini dalle sorgenti ai marts decisionali dichiarando per ogni numero freschezza, definizioni e limiti di confronto.
Sei passi per costruire la pipeline
- Inventaria le sorgenti con orologio, granularità e definizioni native, e fissa il dizionario condiviso di ogni metrica esposta.
- Ingerisci i payload grezzi nel warehouse con metadati di caricamento, senza buttare mai il dato originale.
- Normalizza nomi, valute al cambio del giorno di spesa, fusi orari e granularità nella tabella di spesa unificata con quadratura contro i totali nativi.
- Risolvi l’identità con regole di precedenza documentate e dichiara il tasso di matching per segmento.
- Modella gli ordini attribuiti e i marts di economia e coorte con colonne di freschezza obbligatorie su ogni tabella finale.
- Esponi dashboard e audience con SLA distinti e blocca la pubblicazione quando un controllo esce dalla tolleranza.
Perché i numeri del marketing non tornano mai al primo colpo
Chi viene dal prodotto o dalla finanza resta spiazzato dalle versioni concorrenti dello stesso KPI. Nel marketing è la norma, non l’eccezione, e ha quattro cause strutturali da conoscere prima di disegnare qualsiasi architettura.
La prima è la frammentazione delle sorgenti. Un e-commerce medio usa Google Ads, Meta, TikTok, GA4, CRM, ESP e Stripe. Ognuna ha il suo orologio: l’API of Meta storna conversioni fino a 28 giorni dopo, GA4 consolida con ore di ritardo, Stripe regola rimborsi giorni dopo. Confrontare il report delle 9:00 con quello delle 18:00 e trovare scostamenti del 5-10% non indica un bug: indica latenze diverse.
La seconda causa è la divergenza semantica. “Conversione” su Google Ads include per default azioni miste nella colonna conversioni, spesso acquisti e lead pesati allo stesso modo. Su GA4 indica un evento chiave con logica di conteggio diversa. Sul backend indica un ordine pagato, al netto di cancellazioni e IVA. Tre definizioni legittime, tre totali diversi. Senza un dizionario condiviso, ogni riunione riparte da zero.
La terza causa è l’identità frammentata. Lo stesso utente clicca da mobile su Instagram, torna da desktop via ricerca brand e compra dall’app dopo un’email. Senza risoluzione dell’identità, quel percorso conta come tre persone diverse in tre sistemi diversi.
La quarta è il cambiamento silenzioso degli schemi. Le piattaforme rinominano campi, deprecanano metriche, cambiano la granularità dell’API senza preavviso operativo. Un campo spend che diventa ad_spend o una dimensione campaign_name che da un giorno all’altro include un suffisso rompe il join e gonfia o dimezza i totali.
L’architettura in cinque strati: dalle sorgenti all’attivazione
Una pipeline matura si legge in cinque strati, ciascuno con responsabilità precisa e contratto verificabile. Saltarne uno sposta il problema più avanti, dove costa di più.
Lo strato di ingestione estrae i dati e li deposita grezzi nel warehouse. Lo standard è ELT con connettori gestiti come Fivetran o Airbyte verso Snowflake o BigQuery: prima carichi tutto così com’è, poi trasformi dentro il warehouse. La regola d’oro è non buttare mai il grezzo. Le tabelle di staging conservano il payload originale con metadati di caricamento. Quando Meta storna una conversione di tre settimane fa, solo il grezzo ricostruisce cosa sapevi e quando.
Lo strato di normalizzazione uniforma nomi, valute, fusi orari e granularità. Qui nascono le tabelle int_* costruite con dbt: ogni piattaforma ha il suo dialetto, in uscita si parla una sola lingua. La granularità di riferimento è giornaliera per campagna, gruppo e creatività, con fuso fissato una volta per tutte. Le valute usano un tasso datato e versionato, mai il cambio del giorno del report.
Lo strato di identità risolve chi ha fatto cosa. Cucire click_id, cookie, device_id ed email richiede una tabella di mapping che distingue identità osservata e autenticata, con precedenza documentata: dove c’è login vince lo user_id, dove manca si usa l’anonimo con lookback dichiarato, ad esempio 90 giorni.
Lo strato di modellazione produce le tabelle finali, i cosiddetti marts: spesa unificata, ordini attribuiti, coorti, unit economics. Sono tabelle larghe, denormalizzate, pensate per rispondere in secondi alle domande ricorrenti del team senza richiedere join complessi a chi apre Looker o Tableau.
Lo strato di serving espone i dati dove servono: dashboard BI per gli umani, reverse ETL verso Meta, Google o Braze per riattivare i segmenti calcolati, esportazioni verso i fogli di pianificazione del budget. Ogni destinazione ha il suo SLA: la dashboard può tollerare sei ore di ritardo, un pubblico di retargeting da un milione di euro al mese no.
| Strato | Domanda a cui risponde | Esempio di tabella | Errore se manca |
|---|---|---|---|
| Ingestione | Cosa sapeva la sorgente e quando? | stg_meta_ads__insights | Storni inspiegabili |
| Normalization | Come confronto mele con mele? | int_marketing_spend_daily | CPA non confrontabili |
| Identità | Quante persone reali dietro gli eventi? | int_identity_map | Utenti triplicati |
| Modellazione | Quale numero uso per decidere? | mart_channel_economics | Ogni analisi riparte da zero |
| Serving | Dove arriva il dato e quanto è fresco? | Dashboard, audience sync | Decisioni su dati scaduti |
Verdetto: nessun report merita fiducia finché non dichiara freschezza, definizioni e limiti, perché senza contratto di qualità la pipeline sposta righe ma non riduce incertezza.
Unificare la spesa quando ogni piattaforma parla un dialetto diverso
Il cuore della pipeline è la tabella di spesa unificata, in genere int_marketing_spend_daily. Sembra un esercizio di ridenominazione colonne. In realtà qui si gioca la credibilità del confronto tra canali.
Il primo problema è il vocabolario. Google chiama cost ciò che Meta chiama spend e TikTok chiama stat_cost. La normalizzazione impone un dizionario unico: documenta per ogni sorgente quale campo nativo alimenta quale colonna, con eccezioni scritte nel modello dbt.
Il secondo problema è la valuta. Un account in euro, dollari e sterline non può sommare importi nativi. Converti ogni riga al tasso del giorno di spesa con una tabella seed di cambi versionata, conservando importo originale e convertito. Così un audit di sei mesi fa usa i cambi di sei mesi fa, non quelli di oggi.
Il terzo è la granularità temporale. Le API restituiscono dati a livelli diversi e le ore sono espresse nel fuso dell’account pubblicitario. La normalizzazione fissa il giorno in UTC e deriva il giorno locale solo come colonna aggiuntiva, evitando che una campagna USA conti le spese di mezzanotte su due giorni diversi a seconda del report.
-- Normalizzazione giornaliera della spesa Meta in euro
-- Ogni riga: un giorno, una campagna, importi confrontabili
SELECT
DATE(DATE_TRUNC(CAST(date_start AS DATE), DAY)) AS date_day, -- giorno in UTC
campaign_id, -- chiave stabile della campagna
campaign_name, -- nome originale per riconciliazione
SUM(CAST(spend AS NUMERIC)) * fx.rate_to_eur AS spend_eur, -- conversione al cambio del giorno
SUM(CAST(impressions AS INT64)) AS impressions, -- metrica rinominata allo standard
SUM(CAST(inline_link_clicks AS INT64)) AS clicks, -- click confrontabili con Google
'meta' AS platform, -- sorgente dichiarata
CURRENT_TIMESTAMP() AS modelled_at -- tracciabilità del calcolo
FROM stg_meta_ads__insights AS raw
LEFT JOIN seed_fx_rates AS fx -- tabella cambi versionata per data
ON fx.date_day = CAST(raw.date_start AS DATE)
AND fx.currency = 'USD'
GROUP BY date_day, campaign_id, campaign_name, fx.rate_to_eur;
Il test che chiude il cerchio è la quadratura: la somma della tabella unificata per piattaforma e giorno deve coincidere con il totale nativo entro una tolleranza dichiarata, tipicamente l’1-2% per assorbire arrotondamenti e storni. Quando la differenza supera la soglia, il modello fallisce in modo visibile invece di pubblicare un numero silenziosamente sbagliato.
Identità e attribuzione: cucire click, cookie e scontrini
Una volta unificata la spesa resta il nodo più spinoso: collegare soldi spesi e incassati quando il percorso attraversa dispositivi e settimane. Qui convivono due meccanismi distinti: risoluzione dell’identità e attribuzione del merito.
La risoluzione risponde a quante persone reali. Il pattern robusto è deterministico dove possibile, probabilistico solo dove serve. Il segnale forte è il login: quando l’utente si autentica, ogni anonimo precedente si lega allo user_id nel mapping. Senza login si lavora con finestre di osservazione: stesso cookie attivo negli ultimi 90 giorni conta come stessa persona ai fini di reach, con l’avvertenza che la cancellazione dei cookie gonfia il conteggio. Il parametro chiave è il tasso di matching, cioè la quota di conversioni backend collegabile a un click noto. Un e-commerce autenticato supera il 70%, un sito senza login può fermarsi al 30%. Entrambi i valori vanno bene, purché dichiarati.
L’attribuzione risponde a quale tocco dare il merito. Last click, first click, lineare, data-driven: ogni modello è una convenzione contabile, non una verità causale. La pipeline sana ne calcola almeno due in parallelo e mostra lo scostamento. Quando Meta si auto-attribuisce 412 conversioni in vista e GA4 in last click ne vede 289, la differenza è l’informazione più utile: misura quanto il canale vive di view-through e domanda esistente.
-- Mapping identità: lega ogni evento anonimo allo user autenticato
-- Precedenza: il login vince sempre sul cookie
SELECT
e.event_id, -- chiave dell'evento web o app
e.anonymous_id, -- cookie o device prima del login
COALESCE(l.user_id, e.user_id) AS resolved_user_id, -- identità riconciliata
CASE
WHEN l.user_id IS NOT NULL THEN 'authenticated' -- segnale forte
ELSE 'anonymous' -- segnale debole, con lookback
END AS identity_type
FROM stg_events AS e
LEFT JOIN int_login_map AS l
ON l.anonymous_id = e.anonymous_id -- cucitura sul periodo di osservazione
AND l.login_at >= e.event_at - INTERVAL 90 DAY;
Il limite va detto con chiarezza: con i cookie di terze parti in dismissione e i consensi privacy che riducono la tracciabilità, la quota di percorsi osservabili cala ogni anno. Per questo lo strato di modellazione affianca all’attribuzione osservata gli esperimenti di incrementalità, che misurano il lift causale anche dove il cookie non arriva.
Verdetto: identità deterministica dove c’è login e doppia attribuzione in parallelo, perché un solo modello contabile racconta sempre la storia che fa comodo a chi lo ha scelto.
Freschezza, latenza e riconciliazione: il contratto con chi legge i report
Ogni sorgente ha il suo orologio e la pipeline deve mostrarlo a chi legge. GA4 consolida con poche ore di ritardo, Google Ads storna click non validi entro 24-48 ore, Meta assesta conversioni fino a 28 giorni, Stripe regola rimborsi giorni dopo. Un ROAS su costi di oggi e ricavi di ieri confronta due foto scattate in momenti diversi.
La soluzione è un contratto di freschezza per ogni tabella finale: tre colonne per dire quando la sorgente ha spedito il dato, quando dbt l’ha trasformato e fino a che giorno il dato è completo. La dashboard mostra queste date accanto a ogni KPI. Le soglie sono esplicite: il giorno corrente è sempre parziale, ieri si consolida alle 08:00, il confronto settimana su settimana parte solo da dati con almeno 72 ore di anzianità.
La riconciliazione è il rituale che tiene insieme costi, eventi e incassi. Ogni mattina un job confronta tre totali: la spesa unificata contro le API native per piattaforma, gli eventi web contro gli ordini backend per tasso di tracking, gli ordini backend contro Stripe per incassato netto. Quello che esce dalla tolleranza blocca la pubblicazione del mart e alza un avviso, non un numero silenzioso.
La formula sembra ovvia, ma è il punto dove la maggior parte dei team sbaglia: il numeratore e il denominatore devono riferirsi alla stessa data di competenza, non alla stessa data di estrazione. Un ordine del 3 marzo attribuito il 5 marzo appartiene al 3 marzo.
Qualità e osservabilità: accorgersi del guasto prima della riunione
Le pipeline si rompono in modo silenzioso: un token OAuth scaduto congela la spesa Meta a tre giorni fa, un rename di campagna spacca la serie storica, una doppia inizializzazione del tag GA4 raddoppia gli acquisti nel weekend del Black Friday. L’osservabilità serve a scoprirlo dal monitoraggio, non dalla domanda imbarazzata in riunione.
Il primo livello è il test sul dato in dbt. Ogni modello critico dichiara vincoli a ogni esecuzione: unicità della chiave, completezza referenziale, intervalli ammessi come un CTR tra zero e uno. Strumenti come dbt Elementary o Monte Carlo aggiungono il monitoraggio statistico: volumi dimezzati, distribuzioni mutate, colonne diventate nulle. Un ritardo di due ore sulla spesa è un warning. Un raddoppio delle conversioni al lancio blocca la pubblicazione.
-- Controllo di quadratura: spesa unificata contro totale nativo
-- Fallisce in modo visibile oltre la tolleranza del 2%
SELECT
date_day, -- giorno di competenza
platform, -- sorgente sotto esame
SUM(spend_eur) AS unified_spend, -- totale dopo normalizzazione
MAX(native_spend_eur) AS native_spend, -- totale dichiarato dall'API
ABS(SUM(spend_eur) - MAX(native_spend_eur))
/ NULLIF(MAX(native_spend_eur), 0) AS gap_ratio -- scostamento relativo
FROM int_marketing_spend_daily
GROUP BY date_day, platform
HAVING gap_ratio > 0.02; -- sopra soglia: indaga prima di pubblicare
Il secondo livello è il catalogo delle cause note, che trasforma ogni incidente in prevenzione. UTM riscritti dal redirect del sito, fusi orari mescolati tra account USA ed Europa, IVA inclusa in una sorgente ed esclusa nell’altra, eventi di test lasciati attivi in produzione, consenso privacy che taglia il 20% degli eventi su Safari: ciascuno di questi ha un check dedicato e una voce nel manuale operativo.
Il terzo livello è la disciplina sugli schemi: ogni sorgente ha un contratto versionato con le colonne attese e i tipi ammessi, e un campo nuovo o rinominato manda il modello in quarantena invece di propagare nulli a valle. Meglio una dashboard che dichiara il dato in attesa di mappatura che una che mostra zero spese e un ROAS infinito.
Modellare per decidere: marts, CAC payback e marginalità
I marts sono dove la pipeline smette di descrivere il passato e orienta il budget. Tre tabelle coprono il novanta per cento delle domande.
Il mart di economia per canale unisce spesa unificata, ordini attribuiti e costi variabili per giorno e canale, ed espone per riga CAC, ROAS e margine di contribuzione. Il mart di coorte segue i clienti acquisiti nello stesso periodo: quanto spendono a mese 1, 3 e 12, e come cambia il payback tra ricerca brand e paid social. Il mart degli esperimenti conserva holdout, lift e intervallo per ogni test, così la lezione di un geo-test di sei mesi fa resta interrogabile.
La metrica che lega tutto è il CAC payback corretto per margine, non il CPA grezzo di piattaforma:
Un canale con CPA a 25 euro e uno a 40 sembrano ordinati per efficienza. Poi scopri che il primo porta clienti con ARPU mensile da 8 euro e margine al 60%, il secondo da 20 euro con margine al 70%. Il payback reale è 5,2 mesi contro 2,9: il canale caro restituisce il budget quasi due volte più in fretta. Senza il mart che unisce spesa, ricavo backend e costi variabili, questo confronto resta un’opinione.
-- Economia per canale e mese: il numero su cui si discute il budget
SELECT
date_trunc(date_day, MONTH) AS mese, -- granularità decisionale
platform, -- canale a confronto
SUM(spend_eur) AS spesa, -- investimento consolidato
COUNT(DISTINCT order_id) AS ordini, -- ordini attribuiti netti
SUM(net_revenue_eur) AS ricavo_netto, -- al netto di rimborsi e IVA
SUM(spend_eur)
/ NULLIF(COUNT(DISTINCT order_id), 0) AS cac_eur, -- costo per cliente acquisito
SUM(net_revenue_eur)
/ NULLIF(SUM(spend_eur), 0) AS roas_netto -- ritorno su spesa reale
FROM mart_channel_economics
GROUP BY mese, platform
ORDER BY mese, roas_netto DESC;
Il punto delicato è quando questo impianto non basta. Finché il budget si sposta tra canali esistenti, l’attribuzione osservata più il payback guidano bene. Quando si apre un canale nuovo, si cambia drasticamente il mix o la stagionalità domina, serve l’incrementalità misurata con holdout o geo-esperimenti. La pipeline onesta mostra entrambi i numeri e dichiara quale usare per quale decisione.
Verdetto: il payback corretto per margine e coorte decide il budget mentre il CPA di piattaforma descrive solo l’asta, quindi chi scala sul CPA compra clienti che non ripagano mai.
Cosa automatizzare e cosa tenere umano
Da automatizzare senza esitazione: ingestione, normalizzazione, test di qualità, riconciliazioni quotidiane e dashboard consolidate. Sono compiti ripetitivi dove la macchina batte l’analista più attento, e ogni passaggio manuale è un copia-incolla sbagliato alle 23:00 prima del board. Anche il sync inverso dei segmenti rende meglio come job schedulato con monitoraggio che come export manuale.
Da tenere umano: scelta del modello di attribuzione ufficiale, soglia di payback sotto cui ridimensionare un canale, decisione di scalare su un test di incrementalità. Qui servono giudizio, contesto e responsabilità. I numeri non sanno che il mese prossimo cambia il listino o che le creatività sono appena state sostituite. La pipeline presenta opzioni con intervalli e presupposti. La persona firma.
Per chi parte da zero, l’ordine di costruzione conta più della scelta dello strumento. Prima la spesa unificata con quadratura, poi il mapping delle identità con tasso di matching dichiarato, poi gli ordini attribuiti con doppia versione di modello, poi i marts di economia e coorte. Solo alla fine il reverse ETL e l’ottimizzazione automatica dei budget. Ogni strato rende il successivo possibile, e saltare la fila produce dashboard veloci che nessuno crede abbastanza da usarle per spostare soldi veri.
Un caso reale: la riconciliazione su scala Amazon
Amazon chiude il 2023 con ricavi pubblicitari pari a 46,9 miliardi di dollari, comunicati a febbraio 2024, e pubblica i risultati mentre inserzionisti e analisti confrontano i suoi numeri con quelli di Google e Meta. A questa scala la riconciliazione non è un dettaglio: finestre di attribuzione diverse, storni tardivi e rimborsi spostano i totali di milioni tra un report e l’altro. Il caso mostra perché servono spesa unificata con quadratura, date di competenza separate dalle date di estrazione e contratti di freschezza esposti accanto a ogni KPI.
Domande di autoverifica
- Quale tabella conserva il payload originale quando una piattaforma storna una conversione vecchia di settimane?
- Perché un ordine del 3 marzo attribuito il 5 marzo appartiene al 3 marzo nei tuoi confronti?
- Cosa indica un tasso di matching al 30% sulla quota di revenue attribuibile senza estrapolare?
- Quando la quadratura supera la tolleranza, pubblichi il mart o blocchi tutto?
Bloccato su questo argomento o vuoi applicarlo al tuo caso? Prenota una call di 15 minuti con un analista esperto.
Related Path
Lessons to read together
Questi collegamenti portano la lezione dentro il resto del corso: basi da riprendere, passaggi successivi e connessioni tematiche tra moduli.