Indice del diarioDockup / nota dal campo
Note / unexpected-egress-charges

Costi di egress imprevisti: da dove arrivano le fatture per la banda

I costi di egress imprevisti sono solitamente riconducibili a quattro abitudini: servire i media dall'app, non usare gli header di cache, API troppo loquaci e traffico tra regioni. Individua la causa e riduci la fattura senza cambiare provider.

La fattura arriva ed è quattro volte più alta del previsto. La voce del compute è più o meno quella che avevi preventivato. Quella che non torna è l'egress — i byte che escono dalla tua infrastruttura — e c'è una buona probabilità che tu non ci abbia mai pensato.

I costi di egress imprevisti sono la sorpresa più comune nelle fatture dell'application hosting, e il motivo è strutturale: nulla nel tuo ciclo di sviluppo misura i byte. Il tuo laptop non te li fa pagare. Lo staging non ha utenti. La prima volta che la banda diventa visibile è in fattura, e a quel punto hai già distribuito l'abitudine che l'ha causata.

Ecco da dove arriva davvero, in ordine di frequenza.

1. Servire i media dall'applicazione

Questo fattore supera di gran lunga gli altri ed è quasi sempre accidentale.

Metti un video in /public per fare una demo. Funziona, quindi lo lasci lì. Ora ogni visualizzazione della pagina trasmette quel file dal tuo container. Un video da 40 MB su una pagina con mille visitatori al mese equivale a 40 GB — per un file che consideravi un semplice placeholder.

Lo stesso vale per immagini di prodotto, PDF, upload degli utenti e file dei font. Quando li aggiungi, nessuno di questi elementi sembra una decisione infrastrutturale.

La soluzione non è ingegnosa: i media statici devono stare su object storage dietro una CDN, non nel filesystem della tua applicazione. La tua app dovrebbe servire HTML e JSON. Nel momento in cui serve un'immagine hero da 4 MB a ogni visitatore, sta svolgendo il lavoro di una CDN senza beneficiarne dal punto di vista economico.

2. Nessun header di cache

Se le tue risposte non hanno header di cache, ogni visitatore scarica ogni asset a ogni caricamento della pagina. I visitatori abituali li scaricano di nuovo. Un crawler li scarica decine di volte al giorno.

# Fingerprinted build assets never change — cache them for a year
Cache-Control: public, max-age=31536000, immutable

# HTML changes — revalidate but allow a short window
Cache-Control: public, max-age=0, must-revalidate

# Anything user-specific
Cache-Control: private, no-store

È una modifica di una sola riga per ogni classe di risposta che elimina regolarmente gran parte della fattura della banda, perché il traffico eliminato è pura ripetizione.

3. API che restituiscono più dati di quelli usati dal client

Un endpoint di elenco che restituisce oggetti completi quando l'interfaccia mostra tre campi invia la differenza a ogni richiesta, per sempre. Non emerge mai nel profiling perché è veloce — è semplicemente grande.

Controlla due aspetti sui tuoi endpoint più trafficati:

  • La compressione è attiva? Content-Encoding: gzip o br sul JSON riduce in genere le dimensioni del 70–80%. È una riga di middleware e spesso manca.
  • Stai inviando campi che nessuno legge? Serializzare l'intera riga perché l'ORM lo rende semplice è il comportamento predefinito della maggior parte dei codebase.

Un client che esegue polling peggiora entrambi i problemi di un fattore pari al numero di volte al minuto in cui effettua il polling.

4. Traffico tra regioni e tra servizi

Se la tua app si trova in una regione e il database in un'altra, ogni risultato di query attraversa un confine a pagamento. È facile farlo accidentalmente: crei prima il database, scegli una regione senza pensarci e settimane dopo collochi l'app da un'altra parte.

Anche il traffico tra i tuoi servizi può essere egress se lascia la rete privata e torna passando da un hostname pubblico. Due servizi nello stesso workspace che comunicano tramite i rispettivi URL pubblici pagano due volte per una conversazione che non avrebbe mai dovuto uscire dalla rete.

Su Dockup questo errore specifico è difficile da commettere, perché i servizi si raggiungono tramite il nome interno. Un servizio raggiunge main-db.internal:5432 e un altro servizio tramite il suo alias <slug>.internal: il traffico che rimane all'interno della rete del workspace non passa mai da un listener pubblico. È anche per questo che il database non ha un hostname pubblico per impostazione predefinita: non c'è nulla che possa essere instradato accidentalmente attraverso l'esterno.

Individuarlo invece di andare a tentativi

Indovinare quale dei quattro problemi stai affrontando fa perdere un ciclo di fatturazione. Misura invece:

Leggi l'access log in base ai byte, non al numero di richieste. Ordina le risposte principali in base al totale dei byte serviti, non al numero di richieste. L'endpoint che invia più dati raramente è quello chiamato più spesso.

Controlla i tuoi asset statici più grandi. Se qualcosa che supera il megabyte viene servito dalla tua app, è la prima cosa da spostare.

# What is the service actually doing right now
dockup metrics my-project/my-api --json

# And what is it logging
dockup logs my-project/my-api -n 1000

Tieni d'occhio i crawler. Un bot che si comporta male e scarica ripetutamente file di grandi dimensioni può rappresentare la maggior parte dell'egress mensile su un sito con un traffico umano moderato. robots.txt e un noindex sugli ambienti di preview sono soluzioni semplici ed economiche.

Gli ambienti che nessuno conta

Due abitudini generano egress che non compare mai nel modello mentale di nessuno:

Ambienti di preview. Un ambiente di preview per ogni pull request è davvero utile e moltiplica silenziosamente il tuo footprint. Cinque PR aperte significano cinque copie dello stack, ciascuna con il proprio traffico — spesso proveniente dagli stessi crawler, perché gli URL di preview vengono indicizzati se non lo impedisci.

Staging di lunga durata. Uno staging attivo da otto mesi, che nessuno visita, continua a scaricare immagini, a essere scansionato e a eseguire i propri cron job.

Nessuno dei due è un motivo per smettere di usarli. Entrambi sono un motivo per porre dei limiti: fai scadere le preview quando la PR viene chiusa e contrassegnale come noindex, così i motori di ricerca smettono di scaricarle al posto tuo.

dockup noindex my-project/my-api --on

Come dovrebbe essere una buona gestione della fatturazione

Dovresti poter rispondere a tre domande prima che arrivi la fattura:

  1. Cosa è attualmente in esecuzione? Compresi gli elementi che hai dimenticato.
  2. Quanto ha consumato ciascun elemento? Separando compute e trasferimento, non usando un unico numero.
  3. Cosa succede se il consumo aumenta improvvisamente? Un limite che arresta i servizi è spiacevole. Un limite che non esiste è peggio.

Dockup misura l'infrastruttura separatamente dal piano, quindi il costo del piano non nasconde l'utilizzo — e il credito di 20 $ del piano Pro viene applicato a tale utilizzo anziché costituire uno sconto sul costo del piano. Il punto è poter vedere chiaramente quale parte è quale.

In breve

Sposta i media su object storage. Imposta gli header di cache. Attiva la compressione. Mantieni servizi e database nella stessa regione e falli comunicare attraverso la rete privata invece che tramite internet. Fai scadere gli ambienti di preview e impedisci che compaiano nei risultati di ricerca.

Queste cinque abitudini risolvono quasi tutte le sorprese legate alle fatture della banda e nessuna richiede di cambiare il luogo in cui fai hosting.

Domande frequenti

Cos'è l'egress? Sono i dati che lasciano la tua infrastruttura verso internet: risposte agli utenti, file scaricati e payload delle API. Il traffico in ingresso è solitamente gratuito; quello in uscita, di norma, no.

Perché la mia fattura dell'egress è più alta di quella del compute? Quasi sempre perché l'applicazione sta servendo file che dovrebbero stare su una CDN. Un singolo asset di grandi dimensioni su una pagina popolare può costare più di settimane di gestione delle richieste.

Una CDN riduce davvero questi costi? Sì, quando esegue il caching. L'origin serve il file una volta per ogni edge invece che una volta per ogni visitatore, e il prezzo per gigabyte della CDN è in genere una frazione di quello di una piattaforma applicativa.

Gli ambienti di preview costano quanto la produzione? Costano in base a ciò che consumano, spesso più del previsto, perché ciascuno è una copia completa e gli URL di preview vengono scansionati dai crawler se non lo impedisci.