# Factura AWS a unui startup de trei oameni, linie cu linie

Toată lumea publică diagrame de arhitectură. Nimeni nu publică factura. Păcat, pentru că factura e locul unde arhitectura devine sinceră: serviciul de care erai mândru se dovedește o eroare de rotunjire, iar lucrul la care nu te-ai gândit niciodată e a treia linie ca mărime.

Nici noi nu putem publica factura clientului. Ce putem face e următorul cel mai bun lucru. Mai jos e arhitectura pe care o rulăm pentru o platformă a unui client din SUA, calculată linie cu linie la preț de listă în us-east-1 pentru o lună obișnuită, fără angajamente și fără credite. Factura reală are aceeași ordine și aceleași surprize. Ia cifrele ca formă, nu ca bon fiscal.

## Ce rulează

Trei ingineri, trei conturi AWS (dev, staging, prod), toate desfășurate dintr-un singur cod CDK. În fiecare cont: trei aplicații Next.js pe App Runner, un cluster Aurora Serverless v2 PostgreSQL, câteva tabele DynamoDB, vreo duzină de funcții Lambda (unele în VPC ca să ajungă la Aurora), bucket-uri S3 în spatele CloudFront, un WAF în fața aplicației publice, CodeBuild pentru imagini, Secrets Manager și KMS pentru tot ce e sensibil, CloudWatch pentru loguri și alarme. Producția rulează două instanțe App Runner calde pentru aplicația publică; dev și staging rulează totul la dimensiunea minimă.

## Factura

| Linie | Lunar (listă) | Pondere | Ce o determină |
|---|---|---|---|
| App Runner (9 servicii în 3 conturi) | ~$190 | 25 % | 2 instanțe calde de 2 vCPU / 4 GB în prod; restul stă la dimensiunea minimă |
| Aurora Serverless v2 (3 clustere) | ~$130 | 17 % | pragul de 0,5 ACU în prod non-stop; dev și staging se pun singure pe pauză |
| NAT Gateway (3, câte unul per cont) | ~$100 | 13 % | $0,045 pe oră fiecare, înainte de a procesa un singur octet |
| CloudWatch (loguri, metrici, alarme) | ~$95 | 13 % | ~5 GB de loguri pe zi la $0,50 per GB ingerat |
| CloudFront + S3 | ~$55 | 7 % | ~500 GB ieșiți, 200 GB stocați |
| DynamoDB (on-demand, PITR pornit) | ~$35 | 5 % | ~10 M scrieri, 50 M citiri |
| Secrets Manager (3 conturi) | ~$33 | 4 % | $0,40 per secret pe lună, cam 25 de secrete per cont |
| KMS (chei gestionate de client) | ~$33 | 4 % | $1 per cheie pe lună, cam 10 chei per cont |
| Transfer de date, inter-AZ | ~$20 | 3 % | Lambda ↔ Aurora între zone, plus egress ocazional |
| Lambda | ~$15 | 2 % | ~20 M invocări |
| CodeBuild | ~$15 | 2 % | ~200 build-uri pe lună, 8 minute fiecare |
| WAF | ~$16 | 2 % | Web ACL + 5 grupuri de reguli managed + 10 M cereri |
| Route 53, ECR, SES, SQS, SNS | ~$15 | 2 % | Coada lungă |
| **Total** | **~$750** | | |

Undeva între $700 și $850 într-o lună normală, pentru o platformă cu utilizatori reali, bani reali care trec prin ea și trei medii izolate. E mai puțin decât o zi de inginer la tarife de consultanță. Ține minte asta când cineva propune o săptămână de optimizare de costuri.

<div class="article-figure">
<svg viewBox="0 0 900 330" width="100%" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Grafic cu bare orizontale al facturii lunare AWS pe servicii: App Runner 25 la sută, Aurora Serverless v2 17 la sută, NAT Gateway 13 la sută, CloudWatch 13 la sută, CloudFront și S3 7 la sută, DynamoDB 5 la sută, Secrets Manager 4 la sută, KMS 4 la sută, restul 12 la sută. Cele trei linii pe care nu le-a bugetat nimeni, NAT, CloudWatch și Secrets plus KMS, sunt evidențiate.">
<g font-family="Inter,system-ui,sans-serif" font-size="13">
<text x="20" y="24" fill="#f1f3ff" font-size="14" font-weight="700">Ponderea în factura lunară</text>
<g fill="#9aa3c7">
<text x="20" y="60">App Runner</text><rect x="200" y="48" width="500" height="16" rx="3" fill="#7b8cff"/><text x="710" y="60" fill="#f1f3ff">25 %</text>
<text x="20" y="90">Aurora Serverless v2</text><rect x="200" y="78" width="340" height="16" rx="3" fill="#7b8cff"/><text x="550" y="90" fill="#f1f3ff">17 %</text>
<text x="20" y="120">NAT Gateway</text><rect x="200" y="108" width="260" height="16" rx="3" fill="#ff6b8a"/><text x="470" y="120" fill="#ff6b8a">13 % · nebugetat de nimeni</text>
<text x="20" y="150">CloudWatch</text><rect x="200" y="138" width="260" height="16" rx="3" fill="#ff6b8a"/><text x="470" y="150" fill="#ff6b8a">13 % · crește cu traficul</text>
<text x="20" y="180">CloudFront + S3</text><rect x="200" y="168" width="140" height="16" rx="3" fill="#7b8cff"/><text x="350" y="180" fill="#f1f3ff">7 %</text>
<text x="20" y="210">DynamoDB</text><rect x="200" y="198" width="100" height="16" rx="3" fill="#7b8cff"/><text x="310" y="210" fill="#f1f3ff">5 %</text>
<text x="20" y="240">Secrets Manager + KMS</text><rect x="200" y="228" width="160" height="16" rx="3" fill="#ffd166"/><text x="370" y="240" fill="#ffd166">8 % · prețul celor trei conturi</text>
<text x="20" y="270">Restul</text><rect x="200" y="258" width="240" height="16" rx="3" fill="#2a3150"/><text x="450" y="270" fill="#f1f3ff">12 %</text>
</g>
<text x="20" y="312" fill="#9aa3c7" font-size="12">Compute ales intenționat: 42 %. Instalații primite implicit: 58 %.</text>
</g>
</svg>
</div>

## Cele trei surprize

**NAT Gateway e o taxă fixă pentru faptul că ai un VPC.** Avem Lambda-uri care vorbesc cu Aurora, deci stau în subneturi private, deci au nevoie de un NAT ca să ajungă la orice de pe internet, inclusiv la API-urile AWS. Un NAT per cont e cam $33 pe lună înainte să proceseze un octet. Trei conturi, trei NAT-uri, $100. Mai mult decât Lambda, DynamoDB și WAF la un loc. Soluția e parțială: gateway endpoint-urile pentru S3 și DynamoDB sunt gratuite și elimină mare parte din trafic, interface endpoint-urile pentru Secrets Manager și altele costă $7 fiecare, deci se amortizează doar peste un anumit volum, iar în dev ne gândim serios să nu avem NAT deloc și să lăsăm Lambda-urile care au nevoie de internet să eșueze zgomotos.

**Securitatea are un preț per cont.** Secrets Manager taxează per secret, KMS taxează per cheie, iar CloudTrail vrea propriul bucket. Nimic nu e scump în sine. Înmulțit cu trei conturi, ajunge la 8 % din factură, cam cât costă CloudFront ca să servească fiecare octet al produsului. Am redus grupând valorile înrudite într-un singur secret JSON (un secret, mai multe chei) în loc de un secret per valoare. Nu am redus cheile KMS: câte o cheie per data store per cont e tot rostul [configurației cu trei conturi](/ro/blog/aws-three-accounts-one-cdk-codebase).

**Logurile costă mai mult decât funcțiile care le scriu.** CloudWatch Logs, la $0,50 per GB ingerat, e cea mai scumpă linie care scalează cu traficul, nu cu numărul de oameni. Cinci gigabyți pe zi e nimic pentru trei aplicații care loghează fiecare request în JSON, și e deja $75 pe lună. Am tăiat retenția la 30 de zile, am mutat grupurile de log zgomotoase pe clasa Infrequent Access la jumătate de preț la ingestion și am încetat să logăm corpurile request-urilor. Răspunsul pe termen lung e [să nu lași CloudWatch să dețină deloc logurile aplicației](/ro/blog/your-logs-should-not-know-which-cloud).

## Lucrul care nu e o surpriză, dar ar trebui să te îngrijoreze

Non-producția e cam o treime din factură. Dev și staging sunt „mici” și tot poartă câte un NAT, câte un cluster Aurora, nouă servicii App Runner între ele și propriile copii ale fiecărui secret și ale fiecărei chei. Auto-pause pe Aurora Serverless v2 (0 ACU când e inactiv, de la sfârșitul lui 2024) a dus cele două clustere non-prod de la cam $90 la cam $20. App Runner la dimensiunea minimă e $5 per serviciu, ceea ce e în regulă. NAT-urile rămân problema.

<div class="article-figure">
<svg viewBox="0 0 900 220" width="100%" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Bară stivuită care arată producția la cam 65 la sută din factură și dev plus staging la cam 35 la sută, cu ponderea non-producției descompusă în NAT gateway-uri, App Runner la dimensiune minimă, clustere Aurora pe pauză și secrete și chei.">
<g font-family="Inter,system-ui,sans-serif" font-size="13">
<text x="20" y="24" fill="#f1f3ff" font-size="14" font-weight="700">Unde se duc banii, pe medii</text>
<rect x="20" y="50" width="553" height="34" rx="4" fill="#7b8cff"/>
<text x="296" y="72" text-anchor="middle" fill="#0d1120" font-weight="700">prod · ~65 %</text>
<rect x="577" y="50" width="298" height="34" rx="4" fill="#ffd166"/>
<text x="726" y="72" text-anchor="middle" fill="#0d1120" font-weight="700">dev + staging · ~35 %</text>
<line x1="577" y1="84" x2="577" y2="110" stroke="#ffd166" stroke-dasharray="4,3"/>
<line x1="875" y1="84" x2="875" y2="110" stroke="#ffd166" stroke-dasharray="4,3"/>
<rect x="577" y="112" width="80" height="26" fill="#ff6b8a"/><text x="617" y="130" text-anchor="middle" fill="#0d1120" font-size="11">2 NAT-uri</text>
<rect x="657" y="112" width="70" height="26" fill="#7b8cff"/><text x="692" y="130" text-anchor="middle" fill="#0d1120" font-size="11">App Runner</text>
<rect x="727" y="112" width="60" height="26" fill="#4fffb0"/><text x="757" y="130" text-anchor="middle" fill="#0d1120" font-size="11">Aurora</text>
<rect x="787" y="112" width="88" height="26" fill="#9aa3c7"/><text x="831" y="130" text-anchor="middle" fill="#0d1120" font-size="11">secrete, chei, loguri</text>
<text x="577" y="170" fill="#9aa3c7" font-size="12">Auto-pause pe Aurora a tăiat deja ~10 puncte din ponderea non-prod.</text>
<text x="577" y="190" fill="#9aa3c7" font-size="12">Cele două NAT-uri sunt următoarea țintă.</text>
</g>
</svg>
</div>

## Ce nu optimizăm în mod deliberat

Plătim on-demand pentru tot. Fără Savings Plans, fără capacitate rezervată, fără instanțe Aurora rezervate. La $750 pe lună, economia maximă dintr-un angajament pe un an e cam $100 pe lună, iar forma platformei încă se schimbă: App Runner poate deveni Fargate, Aurora poate deveni RDS simplu, una dintre Lambda-uri poate deveni container. Un angajament e un pariu că arhitectura nu se va mișca, și nu suntem gata să facem pariul ăsta. Revenim la discuție când factura trece de vreo $3.000, unde conversația merită o după-amiază.

Nici nu alergăm după coada lungă. Route 53, ECR, SES și SQS fac la un loc $15. Orice oră petrecută acolo e o oră pierdută.

## Cum să-ți citești propria factură

Trei obiceiuri care au făcut posibil exercițiul ăsta și pe care le-am recomanda oricărei echipe de mărimea noastră:

- **Pornește Cost Explorer cu granularitate orară și taghează pe mediu din prima zi.** Al nostru e un singur tag CDK, `env`, aplicat la nivel de stack. Fără el, „prod vs non-prod” e o ghicitoare.
- **Uită-te la factură pe tip de utilizare, nu pe serviciu.** „EC2-Other” e locul unde se ascund NAT gateway-urile. „CloudWatch” amestecă ingestion, stocare și apeluri API care au soluții complet diferite.
- **Pune o alertă de buget la 120 % din luna trecută.** Nu ca să economisești, ci ca să afli de o schimbare în ziua trei, nu în ziua treizeci. A noastră a sunat de două ori: o dată pentru un grup de log scăpat de sub control, o dată pentru o Lambda care reîncerca un webhook eșuat în fiecare minut, timp de o săptămână.

Factura nu e o problemă la dimensiunea asta. E o hartă. Ne-a spus că ingineria interesantă nu e în compute-ul pe care l-am ales, ci în instalațiile care au venit odată cu el, și acolo se duc următoarele trei articole: [NAT gateway-urile](/ro/blog/nat-gateway-the-most-expensive-line-you-do-not-see), [logurile](/ro/blog/your-logs-should-not-know-which-cloud) și [angajamentele](/ro/blog/reserved-savings-plans-or-nothing-at-small-scale).

Dacă vrei o a doua pereche de ochi pe propria factură, [hai să vorbim](/contact). Le citim pe bani.
