Rejstřík deníkuDockup / terénní poznámka
Note / unexpected-egress-charges

Nečekané poplatky za egress: Odkud se berou účty za bandwidth

Nečekané poplatky za egress obvykle způsobují čtyři návyky: servírování médií z aplikace, chybějící cache headers, příliš komunikativní API a traffic mezi regiony. Najděte zdroj a snižte účet bez změny poskytovatele.

Přijde účet a je čtyřikrát vyšší, než jste čekali. Položka za compute zhruba odpovídá vašemu rozpočtu. Ta druhá ne — egress, tedy data odcházející z vaší infrastruktury — a je dost možné, že jste o něm dosud ani jednou nepřemýšleli.

Nečekané poplatky za egress jsou nejčastějším billingovým překvapením při hostování aplikací a důvod je systémový: během vývoje nic neměří přenesené bajty. Váš notebook vám za ně nic neúčtuje. Staging nemá uživatele. Bandwidth se poprvé stane viditelným až na faktuře — a tou dobou už máte nasazený návyk, který ho způsobil.

Tady je přehled skutečných příčin seřazený podle toho, jak často bývá která z nich odpovědí.

1. Servírování médií z aplikace

Tento problém výrazně převyšuje ostatní a téměř vždy vznikne omylem.

Vložíte video do /public, abyste něco předvedli. Funguje, takže tam zůstane. Při každém načtení stránky se tento soubor streamuje z vašeho kontejneru. Jedno 40MB video na stránce s tisícovkou návštěvníků měsíčně znamená 40 GB — kvůli souboru, který jste považovali za placeholder.

Stejný princip platí pro obrázky produktů, PDF, uploady uživatelů i font files. Když je přidáváte, žádný z nich nepůsobí jako infrastrukturní rozhodnutí.

Řešení není nijak důmyslné: statická média patří do object storage za CDN, ne do filesystemu vaší aplikace. Aplikace by měla servírovat HTML a JSON. Ve chvíli, kdy servíruje každému návštěvníkovi 4MB hero image, dělá práci CDN, ale bez jakékoli ekonomiky CDN.

2. Chybějící cache headers

Pokud vaše responses nemají cache headers, každý návštěvník stáhne při každém načtení stránky všechny assety. Opakovaní návštěvníci stáhnou všechno znovu. Crawler to stáhne desítkykrát denně.

# 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

Jde o změnu na jednom řádku pro každou třídu responses, která běžně odstraní většinu účtu za bandwidth, protože eliminovaný traffic je čisté opakování.

3. API, která vracejí víc, než klient využije

List endpoint, který vrací celé objekty, i když UI vykresluje tři fields, posílá tento rozdíl s každým requestem — navždy. V profilingu se to nikdy neprojeví, protože je rychlý — jen zkrátka posílá velké objemy dat.

U nejvytíženějších endpointů si ověřte dvě věci:

  • Je zapnutá komprese? Content-Encoding: gzip nebo br u JSON obvykle zmenší objem o 70–80 %. Jde o jeden řádek v middleware a často chybí.
  • Posíláte fields, které nikdo nečte? Serializovat celý row jen proto, že to ORM usnadňuje, je výchozí chování většiny codebasí.

Polling client obojí zhoršuje úměrně tomu, kolikrát za minutu polluje.

4. Traffic mezi regiony a službami

Pokud je vaše aplikace v jednom regionu a databáze v jiném, výsledek každého query překračuje zpoplatněnou hranici. Dá se to snadno udělat omylem — nejdřív vytvoříte databázi, bez přemýšlení vyberete region a o několik týdnů později umístíte aplikaci jinam.

Traffic mezi vlastními službami může být také egress, pokud opustí private network a vrátí se přes public hostname. Dvě služby ve stejném workspace, které spolu komunikují přes své public URLs, platí dvakrát za konverzaci, která nikdy nemusela opustit síť.

Na Dockup je konkrétně tato chyba obtížně proveditelná, protože služby se navzájem oslovují pomocí interních názvů. Služba se připojí k main-db.internal:5432 a k jiné službě přes její alias <slug>.internal — traffic, který zůstává uvnitř workspace network, se nikdy nedostane k public listeneru. Proto také databáze ve výchozím nastavení nemá public hostname: není tu nic, co byste mohli omylem směrovat ven.

Jak zdroj najít místo hádání

Hádání, která ze čtyř příčin to je, vás stojí celý billing cycle. Místo toho měřte:

Čtěte access log podle počtu bajtů, ne podle počtu requestů. Seřaďte nejčastější responses podle celkového objemu served bytes, ne podle počtu requestů. Endpoint, který posílá nejvíc dat, se jen zřídka volá nejčastěji.

Zkontrolujte největší statické assety. Pokud se z vaší aplikace servíruje cokoli většího než megabyte, je to první věc, kterou byste měli přesunout.

# 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

Sledujte crawlery. Bot, který opakovaně stahuje velké soubory, může na webu s mírným provozem od lidí tvořit většinu měsíčního egress. robots.txt a noindex na preview environments jsou levné řešení.

Prostředí, která nikdo nezapočítává

Dva návyky generují egress, který se neobjevuje v mentálním modelu nikoho z týmu:

Preview environments. Preview pro každý pull request je skutečně užitečné a nenápadně násobí váš footprint. Pět otevřených PR znamená pět kopií stacku, každou s vlastním trafficem — často od stejných crawlerů, protože preview URLs se indexují, pokud tomu nezabráníte.

Dlouho běžící staging. Staging, který běží osm měsíců a nikdo ho nenavštěvuje, stále stahuje images, stále ho procházejí crawlery a stále spouští své cron jobs.

Ani jedno není důvodem přestat je používat. Obojí je ale důvodem nastavit jim limity: preview expirujte po uzavření PR a označte je jako noindex, aby je vyhledávače vaším jménem přestaly stahovat.

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

Jak vypadá dobrý billing

Ještě před příchodem faktury byste měli umět odpovědět na tři otázky:

  1. Co právě běží? Včetně věcí, na které jste zapomněli.
  2. Co která věc spotřebovala? Rozdělené na compute a transfer, ne jako jedno číslo.
  3. Co se stane, když spotřeba vyskočí? Limit, který zastaví služby, je nepříjemný. Limit, který neexistuje, je horší.

Dockup účtuje infrastrukturu odděleně od plánu, takže poplatek za plán neskrývá usage — a kredit 20 USD v plánu Pro se odečítá od této usage, nikoli od poplatku za plán. Smyslem je, abyste viděli, která část je která.

Stručně

Přesuňte média do object storage. Nastavte cache headers. Zapněte kompresi. Udržujte služby a jejich databáze v jednom regionu a nechte je komunikovat přes private network namísto veřejného internetu. Preview environments expirujte a zabraňte jejich zobrazování ve výsledcích vyhledávání.

Těchto pět návyků řeší téměř každý nečekaně vysoký účet za bandwidth a žádný z nich nevyžaduje změnu místa, kde hostujete.

Často kladené otázky

Co je egress? Data odcházející z vaší infrastruktury směrem k internetu. Responses uživatelům, stahované soubory, API payloads. Příchozí traffic bývá zdarma, odchozí obvykle ne.

Proč je můj účet za egress vyšší než účet za compute? Téměř vždy proto, že aplikace servíruje soubory, které patří na CDN. Jeden velký asset na oblíbené stránce převáží týdny zpracovávání requestů.

Opravdu CDN snižuje náklady? Ano, pokud cachuje. Origin servíruje soubor jednou pro každý edge místo jednou každému návštěvníkovi a cena CDN za gigabyte je obvykle zlomkem ceny aplikační platformy.

Stojí preview environments stejně jako produkce? Stojí tolik, kolik spotřebují, což bývá více, než čekáte, protože každé z nich je plná kopie a preview URLs procházejí crawlery, pokud tomu nezabráníte.