Četiri sloja zaštite od troškova: kako naš Auto-Scaler ne raznese račun
Klijent uploada pokvarenu scenu, orchestrator startuje pod, pod ulazi u beskonačni OOM, pokušava tri retryja, svaki pod nas košta 0,80 US dolara po minuti. Bez zaštite to za sat vremena postaje troznamenkasti račun. Četiri neovisna sloja moraju zakazati da bismo to doživjeli.
Kod cloud rendering setupa najskuplja pogreška nije spori render — nego render koji beskonačno traje. GPU pod pri US$0,80/minuti na 60 minuta postaje $48, na 12 sati $576, na vikendu $2.300. Ako softver može pasti, a orchestrator radi „samo restart", to nije auto-recovery — to je račun koji klijenta više ne dovodi natrag.
Naš cinema-orch backend ima četiri neovisna sloja zaštite od troškova. Nakon Sprinta 3.5 (2026-06-15) sva četiri su live. Svaki sloj pogrešno radi nešto drugačije od ostalih — tako da moraju zakazati barem dva prije nego što vidimo previsoke račune.
Sloj 1: Ex-ante estimate + Client-Confirm
Prije nego bilo koji pod spawna, orchestrator izračunava procjenu troškova na temelju:
- Sample count × tile count × frame count × procijenjeno vrijeme/frame na odabranom GPU-u
- Baseline iz povijesnih jobova iste scene signature (hash iz Blender verzije + render postavki)
- Puferom od 20 % za nepoznanice
Estimate se prije starta prikazuje klijentu. Klijent mora aktivno kliknuti „Potvrdi". Ako je estimate iznad klijentovog budgeta (svaki user u svom accountu postavlja hard cap), job se automatski odbija — ne queue-a, ne potvrđuje-s-upozorenjem, nego rejectan.
Efekt: ~70 % svih teoretski skupih jobova nikad ne dolazi u orchestrator, jer klijent unaprijed vidi da postaje preskupo i optimizira scenu.
Sloj 2: Per-Job budget cap s live ticker-om
Svaki job ima polje `max_budget_cents`, postavljeno od strane usera (tipično estimate + 20 %). Orchestrator vozi ticker u Postgresu — svake minute računa se trenutno akumulirani trošak i uspoređuje s `max_budget_cents`.
Kada job dostigne cap, pod se tvrdo terminira. User dobiva notifikaciju, može ručno podignuti cap ili preuzeti djelomični output.
Efekt: runaway render može maksimalno završiti ~5–10 % iznad capa (dok ne udari sljedeći ticker tick). Kod $50 joba to je $2,50 overshoot umjesto $2.300.
Sloj 3: Pod-timeout na systemd razini
Svaki GPU pod ima tvrdu vremensku granicu koja se postavlja u pod-initu — analogno Kubernetes ActiveDeadlineu. Kod standardne render sesije: 4 sata. Nakon isteka: pod umire, orchestrator vidi prekid i označava job kao `budget_exceeded`.
Zašto je to nužno iako Sloj 2 postoji: sam orchestrator može pasti (mrežna particija, Postgres ispad, procesni OOM). Pod-timeout je fallback jamstvo — konfiguriran je na samom podu i ne treba eksterni trigger.
Efekt: čak i uz potpuno šutljivi orchestrator, pojedini pod maksimalno košta do 4-satne marke, nakon čega se sam terminira.
Sloj 4: Spending alert sa strane providera
Runpod (naš primarni GPU provider) ima vlastite budget alerte po accountu. Pri $50/dan potrošnje dolazi e-mail na [email protected]; pri $200/dan Slack alert u naš Ops kanal. Oba su konzervativno namještena.
Ako sva tri druga sloja zakažu, ovaj nas alert najkasnije ručno dovede u proces. Do sada (4 tjedna beta) nikad nije okinuo, jer slojevi 1–3 sve hvataju.
Zašto četiri
Jedan zaštitni sloj nije zaštita — to je single point of failure. Ako se oslonimo na „klijent potvrđuje estimate", a UI ima bug koji prikazuje estimate prenisko, gotovi smo. Četiri neovisna sloja znače: bug u nekom softveru (naš UI, naš orchestrator, systemd, Runpodov portal) ne hvata neočekivan račun — nego druga tri to čine.
Trik je u neovisnosti. Sloj 1 živi u frontendu (Next.js). Sloj 2 u orchestratoru (Python/asyncpg). Sloj 3 na podu (systemd). Sloj 4 kod providera (Runpodov API). Ako bi neki softver pao, malo je vjerojatno da druga tri istovremeno zakažu jednako.
Što smo naučili
- Točnost estimatea je najvažnija poluga za Sloj 1. Ako je estimate 30 % pored, cap pufer je iscrpljen prije nego što je job gotov. Puno vremena uložili smo u kalibraciju sample count × vrijeme/frame.
- Interval tickera u Sloju 2 je trade-off između overshoota i opterećenja baze. 60 sekundi je naš kompromis — 30 sekundi smanjuje overshoot, ali udvostručuje DB load po jobu koji trči.
- Pod-timeout u Sloju 3 ne smije biti prekratak. U ranoj verziji imali smo 60 minuta — razbilo je legitiman 4K job koji bi trebao 90 minuta. Sada 4 sata default, konfigurabilno po jobu.
Ako sam gradiš auto-scaling sustav s eksternim GPU billing rizikom: ne kreći s jednim cap-om. Sagradi tri neovisna, plus provider alert. Dodatni napor je malen, delta rizika je enormna.
Ovu arhitekturu dokumentiramo javno jer smatramo da cloud renderiranje mora biti pošteno prema vlastitim rizicima. Ako želiš da ti pogledam obrazac za tvoj vlastiti sustav: [email protected] — ZER0ONE Studio radi ovu vrstu distributed-systems savjetovanja kao engineering service.