Journal-IndexDockup / Feldnotiz
Note / unexpected-egress-charges

Unerwartete Egress-Kosten: Woher Bandbreitenrechnungen kommen

Unerwartete Egress-Kosten lassen sich meist auf vier Gewohnheiten zurückführen: Medien aus der App ausliefern, fehlende Cache-Header, geschwätzige APIs und regionsübergreifenden Traffic. Finden Sie die Ursache und senken Sie die Rechnung, ohne den Anbieter zu wechseln.

Die Rechnung kommt und ist viermal so hoch wie erwartet. Die Compute-Position entspricht ungefähr dem eingeplanten Budget. Die Abweichung steckt bei Egress – den Bytes, die Ihre Infrastruktur verlassen – und es ist gut möglich, dass Sie darüber bisher noch kein einziges Mal nachgedacht haben.

Unerwartete Egress-Kosten sind die häufigste Überraschung bei der Abrechnung von Application Hosting. Der Grund ist strukturell: In Ihrem Development-Workflow misst nichts die übertragenen Bytes. Ihr Laptop berechnet Ihnen dafür nichts. In der Staging-Umgebung gibt es keine Nutzer. Sichtbar wird die Bandbreite zum ersten Mal auf der Rechnung – und dann haben Sie die Gewohnheit, die das verursacht, längst ausgeliefert.

Hier entsteht der Traffic tatsächlich – in der Reihenfolge, in der dies am häufigsten die Ursache ist.

1. Medien aus der Anwendung ausliefern

Dieser Punkt übertrifft die anderen deutlich und geschieht fast immer unbeabsichtigt.

Sie legen ein Video zum Demonstrieren in /public. Es funktioniert, also bleibt es dort. Jetzt streamt jeder Seitenaufruf diese Datei aus Ihrem Container. Ein 40-MB-Video auf einer Seite mit tausend Besuchern pro Monat verursacht 40 GB – durch eine Datei, die Sie für einen Platzhalter hielten.

Das gleiche Muster gilt für Produktbilder, PDFs, Benutzer-Uploads und Font-Dateien. Wenn Sie sie hinzufügen, wirken sie nicht wie Infrastrukturentscheidungen.

Die Lösung ist nicht kompliziert: Statische Medien gehören in Object Storage hinter ein CDN, nicht in das Dateisystem Ihrer Anwendung. Ihre App sollte HTML und JSON ausliefern. Sobald sie jedem Besucher ein 4-MB-Hero-Bild liefert, übernimmt sie die Aufgabe eines CDNs – ohne dessen wirtschaftliche Vorteile.

2. Keine Cache-Header

Wenn Ihre Responses keine Cache-Header enthalten, lädt jeder Besucher bei jedem Seitenaufruf jedes Asset herunter. Wiederkehrende Besucher laden alles erneut. Ein Crawler lädt die Dateien dutzende Male am Tag herunter.

# 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

Das ist eine Änderung von einer Zeile pro Response-Klasse, die einen Großteil einer Bandbreitenrechnung entfernt, weil der eingesparte Traffic reine Wiederholung ist.

3. APIs, die mehr zurückgeben als der Client verwendet

Ein Listen-Endpoint, der vollständige Objekte zurückgibt, obwohl die UI drei Felder rendert, sendet die Differenz bei jeder Anfrage – für immer. Beim Profiling fällt das nie auf, weil es schnell ist – nur eben umfangreich.

Bei Ihren meistgenutzten Endpoints sollten Sie zwei Dinge prüfen:

  • Ist die Komprimierung aktiviert? Content-Encoding: gzip oder br bei JSON reduziert die Größe typischerweise um 70–80 %. Das ist eine Zeile in der Middleware und fehlt erstaunlich häufig.
  • Senden Sie Felder, die niemand liest? Die gesamte Zeile zu serialisieren, weil das ORM es einfach macht, ist das Standardverhalten der meisten Codebases.

Ein Client mit Polling verschärft beides um den Faktor, wie oft pro Minute er abfragt.

4. Regions- und serviceübergreifender Traffic

Wenn sich Ihre App in einer Region und Ihre Datenbank in einer anderen befindet, überschreitet jedes Abfrageergebnis eine kostenpflichtige Grenze. Das passiert leicht versehentlich: Sie erstellen zuerst die Datenbank, wählen gedankenlos eine Region und platzieren die App Wochen später an einem anderen Ort.

Auch der Traffic zwischen Ihren eigenen Services kann als Egress berechnet werden, wenn er das private Netzwerk verlässt und über einen öffentlichen Hostnamen zurückkommt. Zwei Services im selben Workspace, die über ihre öffentlichen URLs miteinander kommunizieren, zahlen doppelt für eine Kommunikation, die das Netzwerk nie hätte verlassen müssen.

Auf Dockup ist dieser konkrete Fehler schwer zu machen, weil Services einander über interne Namen adressieren. Ein Service erreicht main-db.internal:5432 und einen anderen Service über dessen <slug>.internal-Alias – Traffic, der innerhalb des Workspace-Netzwerks bleibt, erreicht keinen öffentlichen Listener. Deshalb hat die Datenbank standardmäßig auch keinen öffentlichen Hostnamen: Es gibt nichts, das versehentlich darüber geroutet werden könnte.

Finden statt raten

Zu raten, welcher der vier Punkte zutrifft, kostet Sie einen Abrechnungszeitraum. Messen Sie stattdessen:

Lesen Sie das Access-Log nach Bytes, nicht nach Anzahl. Sortieren Sie Ihre wichtigsten Responses nach den insgesamt ausgelieferten Bytes und nicht nach der Anzahl der Requests. Der Endpoint, der die meisten Daten sendet, ist nur selten der am häufigsten aufgerufene.

Prüfen Sie Ihre größten statischen Assets. Wenn etwas mit mehr als einem Megabyte aus Ihrer App ausgeliefert wird, sollte das als Erstes verschoben werden.

# 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

Achten Sie auf Crawler. Ein fehlerhafter Bot, der wiederholt große Dateien abruft, kann bei einer Website mit moderatem menschlichem Traffic den Großteil des monatlichen Egress ausmachen. robots.txt und ein noindex für Preview-Umgebungen sind günstige Maßnahmen.

Die Umgebungen, die niemand mitzählt

Zwei Gewohnheiten erzeugen Egress, der in keinem mentalen Modell auftaucht:

Preview-Umgebungen. Eine Preview pro Pull Request ist wirklich nützlich und vergrößert Ihren Footprint unbemerkt. Fünf offene PRs bedeuten fünf Kopien Ihres Stacks, jeweils mit eigenem Traffic – oft von denselben Crawlern, weil Preview-URLs indexiert werden, wenn Sie das nicht verhindern.

Langlebiges Staging. Eine Staging-Umgebung, die seit acht Monaten läuft und niemand besucht, lädt weiterhin Images, wird weiterhin gecrawlt und führt weiterhin ihre Cron-Jobs aus.

Keines von beidem ist ein Grund, diese Umgebungen nicht zu verwenden. Beides ist ein Grund, ihre Lebensdauer zu begrenzen: Previews schließen, sobald der PR geschlossen wird, und sie mit noindex versehen, damit Suchmaschinen sie nicht mehr in Ihrem Namen herunterladen.

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

Wie eine gute Abrechnung aussieht

Sie sollten drei Fragen beantworten können, bevor die Rechnung eintrifft:

  1. Was läuft derzeit? Einschließlich der Dinge, die Sie vergessen haben.
  2. Was hat jedes davon verbraucht? Aufgeschlüsselt nach Compute und Transfer, nicht als eine einzige Zahl.
  3. Was passiert bei einer Spitze? Ein Limit, das Services stoppt, ist unangenehm. Ein fehlendes Limit ist schlimmer.

Dockup erfasst Infrastruktur getrennt vom Plan, sodass die Plangebühr die Nutzung nicht verschleiert – und das Guthaben von 20 $ im Pro-Plan wird auf diese Nutzung angerechnet, statt die Gebühr zu rabattieren. Entscheidend ist, dass Sie sehen können, welcher Anteil welcher ist.

Kurzfassung

Verschieben Sie Medien in Object Storage. Setzen Sie Cache-Header. Aktivieren Sie die Komprimierung. Halten Sie Services und ihre Datenbanken in einer Region und lassen Sie sie über das private Netzwerk statt über das öffentliche Internet kommunizieren. Lassen Sie Preview-Umgebungen ablaufen und halten Sie sie aus den Suchergebnissen heraus.

Diese fünf Gewohnheiten lösen fast jede unerwartete Bandbreitenrechnung – und keine davon erfordert einen Wechsel des Hosting-Standorts.

Häufig gestellte Fragen

Was ist Egress? Daten, die Ihre Infrastruktur in Richtung Internet verlassen: Responses an Nutzer, heruntergeladene Dateien und API-Payloads. Eingehender Traffic ist normalerweise kostenlos, ausgehender in der Regel nicht.

Warum ist meine Egress-Rechnung höher als meine Compute-Rechnung? Fast immer, weil die Anwendung Dateien ausliefert, die auf ein CDN gehören. Ein einzelnes großes Asset auf einer beliebten Seite verursacht mehr Traffic als wochenlange Request-Verarbeitung.

Reduziert ein CDN die Kosten tatsächlich? Ja, wenn es cached. Der Origin liefert die Datei einmal pro Edge aus statt einmal pro Besucher, und der Preis des CDNs pro Gigabyte beträgt typischerweise nur einen Bruchteil dessen, was eine Application Platform verlangt.

Kosten Preview-Umgebungen genauso viel wie Production? Sie kosten so viel, wie sie verbrauchen. Das ist oft mehr als erwartet, weil jede Umgebung eine vollständige Kopie ist und Preview-URLs gecrawlt werden, wenn Sie das nicht verhindern.