# Syncing inventory: where the time goes

Diffing 50,000 SKUs with a Map takes 14.94 ms, with linear search 11.87 s: the time goes into the 3.88 MB payload and the single source of truth, not the compare.

> Page: https://ui.eneawork.it/blog/ecommerce-magazzino-sync
> Markdown: https://ui.eneawork.it/blog/ecommerce-magazzino-sync.md

*2026-11-01*

Sincronizzare il magazzino costa poco se confronti due elenchi con la struttura giusta: 50.000 SKU in 14,94 ms con una Map, contro 11,87 secondi con una ricerca lineare. Il tempo che perdi davvero sta altrove: nel payload da 3,88 MB, nei webhook persi e nel decidere quale sistema ha ragione.

Node 24.15.0, 1 novembre 2026, misurato su due elenchi identici in memoria, con il 5% delle quantità modificate nel magazzino: 10.000 SKU confrontati in 3,72 ms con una Map e in 395,5 ms con find, 50.000 SKU in 14,94 ms e 11.868,2 ms, con le stesse 500 e 2.500 differenze rilevate. Il feed completo di 50.000 SKU, con SKU, quantità, prezzo e data di aggiornamento, pesa 3.877.891 byte in JSON e 248.356 byte in gzip. Il catalogo EneUI conta 111.985 componenti, 1.556 blocchi e 12.808 icone da 1.472 librerie, letti da /api/stats lo stesso giorno.

## Il confronto non è il collo di bottiglia

La differenza fra 14,94 ms e 11,87 s è enorme e insegna una cosa sola: non confrontare due elenchi con due cicli annidati. Con una Map costruita una volta sola il confronto è lineare, e a 50.000 SKU resta sotto i 15 ms. Se il tuo import richiede minuti, il problema non è il numero di prodotti: è il database interrogato una volta per riga, o il file parsato a ogni giro.

## Dove finisce il tempo: nel payload

3.877.891 byte per 50.000 SKU sono 77 byte per prodotto, e 248.356 byte compressi sono 5 byte per prodotto: gzip toglie il 94% perché i campi si ripetono. Se sincronizzi ogni cinque minuti, sono 288 trasferimenti al giorno, 1,1 GB di JSON o 71 MB compressi. La stessa informazione come lista di differenze, solo SKU e quantità cambiati, pesa 5.000 righe, non 50.000: la prima ottimizzazione è non spedire ciò che non è cambiato.

## Una sola sorgente di verità

Il negozio e il gestionale non possono avere entrambi ragione. Scegli il sistema che possiede la quantità fisica, di solito il gestionale o l'ERP, e tratta la disponibilità mostrata come una copia con data. Se il negozio vende e il gestionale non lo sa, l'ordine verrà rifiutato: è overselling, e costa due volte, perché il cliente ha già pagato. Se il gestionale scala e il negozio non lo sa, mostri prodotti esauriti e perdi vendite. La prima è un rischio legale, la seconda un costo commerciale, e la scelta va scritta nel progetto.

## Il diff in una riga

La funzione qui sotto prende l'elenco del magazzino e quello del negozio e restituisce solo le differenze, in una passata. È la versione minima di quello che serve: nella pratica aggiungi la gestione delle righe nuove e di quelle sparite, e il timestamp dell'ultimo aggiornamento per prodotto, che è l'informazione più utile in caso di contestazione.

node -e "const a=[{sku:'A',q:1},{sku:'B',q:2}],b=[{sku:'A',q:1},{sku:'B',q:0}];const m=new Map(a.map(p=>[p.sku,p.q]));console.log(b.filter(p=>m.get(p.sku)!==p.q).map(p=>p.sku+' '+m.get(p.sku)+'->'+p.q).join(', '))"

## Webhook, polling e ordine degli eventi

Webhook per gli eventi rari (ordine evaso, rettifica di inventario) e polling per il resto: il webhook arriva subito ma può perdersi, il polling è più lento ma converge sempre.,Idempotenza. Ogni aggiornamento porta un identificativo e un timestamp; applicare due volte lo stesso evento non deve cambiare nulla.,Ultimo evento vince, ma solo se più recente. Senza confronto dei timestamp un evento in ritardo sovrascrive un dato più fresco, e la quantità torna sbagliata per ore.,Coda con retry e scarto per gli eventi che falliscono: senza coda, un errore di rete diventa una giacenza sbagliata che nessuno nota.,Allarme sulla deriva. Se il numero di SKU con quantità diversa fra i due sistemi supera una soglia, avvisa: è il sintomo che la sincronizzazione è ferma da un'ora.

## Cosa mostrare quando il dato è vecchio

Nessuna sincronizzazione è istantanea, quindi la pagina deve dire quando è stata aggiornata: «disponibilità aggiornata alle 14:32» è un'informazione onesta e costa una riga di codice. Quando la quantità non è certa, meglio «ultimi pezzi, spedizione in 2-3 giorni» che «disponibile»: la disponibilità dichiarata e non vera è una pratica ingannevole ai sensi degli artt. 20-23 del Codice del Consumo, e con le vendite a distanza il consumatore può recedere comunque, quindi l'ordine annullato è un danno doppio. Se un prodotto finisce mentre l'ordine è in corso, l'unica strada corretta è avvisare subito e proporre attesa o rimborso.

## Il limite

I numeri misurano il confronto in memoria su elenchi già caricati: in produzione il tempo lo decidono la latenza dell'API del gestionale e le query del database, che su 50.000 righe possono valere secondi. Il test non copre la concorrenza: due processi che scrivono la stessa quantità nello stesso istante richiedono un lock o una scrittura condizionale, e nessun benchmark in un solo processo lo mostra. E il 5% di modifiche è un valore di prova: nel tuo negozio la percentuale reale cambia il costo del payload, non quello del confronto.

## Da dove partire

Dichiara quale sistema possiede la quantità e sincronizza solo le differenze, non il catalogo intero.,Aggiungi timestamp e identificativo a ogni aggiornamento, e applica solo gli eventi più recenti.,Spedisci il feed compresso e solo con i campi che cambiano: 248 KB invece di 3,88 MB su 50.000 SKU.,Mostra in pagina l'ora dell'ultimo aggiornamento e non promettere disponibilità che non hai.,Per la ricerca che legge lo stesso stock leggi ricerca a faccette; per il progetto, creare un sito ecommerce.,Sul database da mettere sotto la sincronizzazione, SQLite o PostgreSQL confronta i due casi.,Per mostrare giacenze e stato servono schede prodotto, tabelle e blocchi dashboard.

## FAQ

### Ogni quanto va sincronizzato il magazzino?

Dipende dalla velocità di vendita: un prodotto che vende dieci pezzi al giorno non ha bisogno di un aggiornamento al minuto, uno che vende dieci pezzi all'ora sì. La regola pratica è sincronizzare a un intervallo più corto del tempo medio fra due vendite dello stesso SKU, e comunque ricevere un evento immediato quando un ordine viene evaso.

### Meglio webhook o polling?

Entrambi, per ragioni diverse: il webhook arriva subito ma può perdersi, il polling converge sempre ma con ritardo. Usa il webhook per gli eventi di magazzino e un polling periodico come rete di sicurezza, con un allarme quando i due sistemi divergono.

### Come evito di vendere prodotti esauriti?

Trattando la quantità mostrata come una copia con data, non come una verità: aggiorna spesso, mostra l'ora dell'ultimo aggiornamento, e verifica la disponibilità al momento dell'ordine prima di incassare. Se il prodotto è finito, avvisa subito e offri attesa o rimborso.

### Quanto pesa un feed di 50.000 SKU?

3.877.891 byte in JSON con SKU, quantità, prezzo e data, e 248.356 byte compresso con gzip, che toglie il 94% perché i campi si ripetono. Spedire solo le differenze riduce il payload di un ordine di grandezza.

### Perché il mio import richiede minuti?

Quasi sempre per una query per riga o per un confronto con due cicli annidati. Con una Map costruita una volta sola, 50.000 SKU si confrontano in 14,94 ms; se il processo dura minuti, il tempo è nel database o nel parsing, non nel confronto.
