Mo Sharif
← ~/blog

AWS Cost Estimator: See the Bill Before You Build

I've had this conversation with at least fifty engineers:

"We designed the architecture. Built it. Deployed it. Got the first AWS bill. It was three times what anyone expected."

Every. Single. Time.

Design-time cost estimation

is the practice of attaching a monthly price to every component on an architecture diagram, so the bill shows up while the design is still editable rather than on the first invoice.

The problem isn't that AWS is expensive. It's that engineers have zero intuition for what things cost until the invoice arrives. A PostgreSQL RDS instance sounds reasonable until you realize multi-AZ with provisioned IOPS and automated backups is $800/month. An ElastiCache cluster sounds cheap until inter-AZ data transfer adds $200/month on top.

Architecture decisions are cost decisions. You should see the price tag while you're still drawing boxes and arrows, not after you've committed to a design and deployed to production.

So I built the cost estimator into Codelit. Every node on your architecture diagram gets a cost badge. Every architecture gets a total estimate. And it updates in real-time as you modify the design.

The Codelit estimator infers configuration from three signals — the node's label, how many services connect to it, and the overall architecture pattern — then prices the result. A node labeled "PostgreSQL" becomes db.t3.medium with 20GB gp3 storage until you say otherwise.

A "PostgreSQL" node on the canvas tells me you want a relational database. It doesn't tell me the instance type, storage configuration, multi-AZ preference, or backup retention. And those details are where the cost lives.

I can't ask users to specify all of this. Most people designing an architecture don't know these details yet, and forcing them to pick instance types defeats the purpose of high-level design.

The Terraform and Kubernetes export hits the same wall from the other side: a manifest needs a concrete resource, an estimate needs a concrete price, and a diagram hands you neither. So I built a defaults system that makes reasonable assumptions:

Node labels matter. "PostgreSQL" gets mapped to db.t3.medium with 20GB gp3 storage. "PostgreSQL (Production)" gets db.r6g.large with multi-AZ and 100GB.

Connection density matters. A database with six services connecting to it is handling more load than one with a single connection. The estimator bumps instance size for high-connectivity nodes.

Architecture pattern matters. Microservices with a message broker? The estimator assumes production-grade sizing. Simple three-tier app? Development defaults.

Every assumption is visible and editable. Click any cost badge and you'll see exactly what was assumed. Change the instance type, storage size, or traffic tier, and the estimate updates instantly.

Every Codelit estimate shows three numbers rather than one, because the variable half of an AWS bill — data transfer, API Gateway invocations, Lambda executions, S3 requests — depends on traffic that nobody has yet when they're drawing the diagram.

Cost estimation without traffic data is like estimating a phone bill without knowing how many calls you'll make. Some AWS costs are fixed: a running RDS instance costs the same at 1 request/sec or 10,000. Many aren't.

And even the teams who do know their current traffic are usually designing for growth. So rather than ask, the estimator assumes three:

  • Low traffic: ~1,000 DAU, ~10 req/sec
  • Medium traffic: ~10,000 DAU, ~100 req/sec
  • High traffic: ~100,000 DAU, ~1,000 req/sec

These ranges affect everything variable: data transfer, request-based pricing, auto-scaling group sizes, DynamoDB throughput.

Here's what that looks like in practice for a 5-service e-commerce architecture:

ComponentLow trafficMedium trafficHigh traffic
API Gateway (ALB)$22$45$120
Product Service$35$70$280
Payment Service$35$70$280
PostgreSQL (RDS)$140$340$680
Redis Cache$50$50$150
S3 Storage$5$25$95
Data Transfer$10$45$180
Total$297$645$1,785

That range, $297 to $1,785, tells you something critical: how costs scale with traffic. If your architecture jumps from $500 to $5,000 between medium and high traffic, that non-linear scaling is something you want to know about before you commit to the design.

That is the whole point of showing a range instead of one confident number.

Codelit's estimates are directional, not to-the-penny. The pricing table refreshes weekly from AWS's bulk pricing API across four regions, so a price change on Tuesday can leave a number slightly stale until the next sync.

AWS has 300+ services, each with their own pricing model. Prices vary by region. On-demand, reserved, spot. Free tiers. Volume discounts.

I don't try to model everything. I focus on the ~20 services that actually appear in architecture diagrams: EC2, RDS, ElastiCache, S3, CloudFront, ALB, API Gateway, Lambda, SQS, SNS, DynamoDB, ECS, EKS, and a few others.

For each one I maintain pricing for the most common configurations in us-east-1, us-west-2, eu-west-1, and ap-southeast-1. That covers the vast majority of Codelit users. A weekly transformation pipeline pulls the bulk pricing feed and extracts the configurations I need.

Typescript
// Simplified pricing fetch (runs weekly via cron)
interface ServicePricing {
  service: string;
  region: string;
  configurations: {
    instanceType: string;
    onDemandHourly: number;
    reserved1yrHourly: number;
    reserved3yrHourly: number;
  }[];
}

// Example: RDS PostgreSQL pricing for us-east-1
// (AWS Price List API, checked 26 July 2026; reserved = 1yr standard, all upfront)
// db.t3.medium: $0.072/hr on-demand, $0.048/hr 1yr reserved
// db.r6g.large: $0.225/hr on-demand, $0.121/hr 1yr reserved

Two of them: inter-region replication traffic, and same-region cross-AZ transfer. The second is the one people miss entirely — still $0.01/GB in each direction on the July 2026 price list, between app servers and a database in a different AZ, which adds $150-300/month for a chatty application making thousands of queries per second.

Multi-region architectures are where estimates most often miss. Inter-region data transfer is one of the most underestimated costs in AWS, and for architectures that replicate data across regions, it can dominate the bill.

When I detect a multi-region setup (from region annotations on nodes or explicit multi-region patterns), the estimator adds inter-region data transfer. A database replication edge between us-east-1 and eu-west-1 carries continuous replication traffic. I estimate this based on database size and change rate.

The cross-AZ number is sneakier. It's tiny per request and it never reaches anyone's spreadsheet, because nobody thinks of a query to their own database as network egress.

"In each direction" also doesn't mean what most people read it to mean. A gigabyte moving between two of your own instances in different zones is metered twice, once as egress on the sender and once as ingress on the receiver, so it lands as two line items totalling $0.02 for a single gigabyte going one way. A request and its response are four cents, not two. AWS's own guidance on Network Load Balancer costs states it plainly: data transfer between AZs is $0.02 per GB, accounting for both the sending and the receiving side.

Not every zone-crossing edge is billable, though, and an estimator has to know the difference or it will invent costs. AWS zero-rated inter-AZ transfer for PrivateLink interface endpoints, Transit Gateway and Client VPN on 1 April 2022. It has never charged for RDS or Aurora multi-AZ replication, for traffic between an Application Load Balancer and its targets on private IPs, or for anything that stays inside a single zone. Network Load Balancers are the trap here: cross-zone is off by default, and switching it on starts the meter.

The estimator catches it. If your architecture shows a multi-AZ deployment (which it should for production), the cross-AZ transfer cost appears as a line item — money you're spending on a failure you hope never comes, which is the failure chaos mode makes you watch propagate across the diagram.

Reserved instances cut 36-64% off on-demand pricing, depending on the service and whether you commit for one year or three. By default Codelit shows on-demand pricing, but there's a "Show reserved pricing" toggle, and with it on every applicable node shows both prices with the savings percentage.

The savings are usually dramatic enough to change architectural decisions. I re-pulled this table from the AWS Price List API on 26 July 2026 — every row is one node in us-east-1, on-demand list price times 730 hours against a standard all-upfront reservation spread across its term:

ServiceOn-Demand1yr Reserved3yr ReservedSavings
RDS db.r6g.large$164/mo$89/mo$60/mo46-64%
EC2 m5.xlarge$140/mo$82/mo$53/mo41-62%
ElastiCache cache.r6g.large$150/mo$96/mo$68/mo36-55%

Two things moved since February. Graviton RDS got cheaper — db.r6g.large is $0.225/hr now against the $0.260/hr I quoted then — and the three-year discounts deepened, which is what pushes the top of that range from 60% to 64%. The RDS row is also on the same single-node basis as the other two now, which it wasn't before, and that's why it fell so far.

When you can see that reserved instances save about $1,250/year on a single db.r6g.large node, the conversation with finance practically has itself.

Every node on the Codelit canvas carries a cost badge: a pill showing estimated monthly cost, color-coded from green under $50/month to red over $500/month. Numbers in a table are useful but forgettable. A red pill on a database node is not.

PostgreSQL might show "$340/mo". An EC2 auto-scaling group shows "$180-$720/mo", reflecting the scaling range.

The color bands:

  • Green: under $50/month
  • Yellow: $50-$200/month
  • Orange: $200-$500/month
  • Red: over $500/month

This immediately draws your eye to the expensive parts. When that database cluster badge glows red and everything else is green, you naturally start asking: do I really need multi-AZ? Is that read replica necessary for my traffic?

At the bottom of the canvas, a summary bar shows total estimated monthly cost with the traffic breakdown: "$645 - $1,200 - $2,800/mo" with a mini chart showing distribution across compute, database, networking, and storage.

Cost becomes a first-class design constraint. That's the behavioral change I wanted.

Because engineers default to production-grade configs when dev-tier would handle their actual traffic just fine. After watching thousands of architectures run through the estimator, that's the pattern that dominates: most startup architectures cost 60-80% less than expected once they're right-sized.

A team budgets $3,000/month because they spec'd RDS multi-AZ, multiple m5.xlarge instances, and a three-node ElastiCache cluster. Their actual traffic? 500 DAU. A single db.t3.medium, two t3.small instances, and a single-node cache handles it easily. Total: under $400/month.

It's the judgment gap I wrote about in what engineers taught me about learning system design. Everyone can define multi-AZ. Far fewer can say whether their traffic justifies paying for it.

The cost estimator makes this visible instantly. When you see a $3,000/month architecture and the traffic tiers show you'd need 100,000 DAU to justify it, the right-sizing conversation happens naturally.

No. The EKS control plane costs $0.10 per cluster-hour — $73/month, unchanged on the July 2026 price list — before you've run a single container, ECS charges nothing for its control plane, and two developers running three services get none of the multi-team benefits that would justify the difference.

The biggest over-engineering I see is exactly this: using Kubernetes when ECS would be 60% cheaper. I'm not anti-Kubernetes. It's the right tool for large, complex deployments with multiple teams. But a startup with three services and two developers doesn't need a Kubernetes cluster. ECS is free. You only pay for the underlying compute.

It also isn't where the scaling comes from. Across 55 real-world system architectures, the thing carrying load was almost always caching, not the orchestrator.

I've added a subtle nudge in the estimator: when your architecture uses Kubernetes and the traffic tier suggests ECS would be sufficient, a small note appears: "Consider ECS for this scale, estimated savings of $X/month." It's not pushy. Just informative.

The other choices that quietly inflate a bill:

Over-provisioned choiceWhat it addsCheaper defaultWhen the expensive option earns it
Kubernetes (EKS)$73/month control plane before any computeECS, where the control plane is freeLarge, complex deployments with multiple teams
Multi-AZ in developmentDoubles your database costSingle-AZ dev, multi-AZ productionProduction, where an AZ outage is unacceptable
Provisioned IOPS$200+/monthgp3, which includes 3,000 IOPS freeThroughput that genuinely exceeds the free tier
NAT Gateways for everything$32/month plus data processing feesVPC endpoints for AWS-service trafficInstances that need general outbound internet

I checked those against the AWS Price List API for us-east-1 on 26 July 2026 and none of them had moved: EKS is still $0.10 per cluster-hour, a NAT Gateway is still $0.045/hr plus $0.045/GB processed, and gp3 still includes 3,000 IOPS and 125 MiB/s in the storage price.

Two things: they optimize, and they argue for budget. The most common workflow is build an architecture, check the estimate, realize it's higher than expected, then start experimenting. "What if I use Aurora Serverless v2 instead of provisioned RDS? What if I drop the read replica? What if I use a single AZ for staging?"

Each change updates the estimate in real-time. The canvas becomes a cost optimization playground.

Teams also use it for budget conversations with management. Instead of "we'll need about $2K/month for infrastructure," they show a detailed breakdown with the architecture diagram attached. "Here's what we're building. Here's what each component costs. Here's how it scales." That specificity makes budget approvals faster and builds trust.

The cost estimator isn't replacing the AWS pricing calculator or a proper FinOps practice. It's bringing cost awareness into the earliest stage of design, when changes are cheap and options are open. By the time you're in production, changing your database engine is a project. During design, it's a click.

Try it at codelit.io. Draw an architecture and see what it'll cost before you build anything.

Questions people actually ask

How can I estimate AWS costs before building the architecture?
Price the diagram at design time instead of pricing the deployment. Codelit attaches an estimated monthly cost to every node on an architecture diagram, inferring instance sizing from the node label, the number of connections into it, and the overall pattern, then totals the architecture at three traffic tiers. Every assumption is editable, so you can swap an instance class or drop a read replica and watch the number move before you deploy anything.
Why is my AWS bill higher than the architecture I designed?
Usually configuration rather than service choice. A PostgreSQL RDS instance with multi-AZ, provisioned IOPS, and automated backups reaches 800 dollars a month. Data transfer then adds more on top: traffic between availability zones inside a single region still costs one cent per gigabyte in each direction on the July 2026 AWS price list, which works out to 150 to 300 dollars a month for an application making thousands of database queries per second.
How much cheaper are reserved instances than on-demand?
Between roughly 36 and 64 percent, depending on the service and whether you commit for one year or three. On the July 2026 AWS price list for us-east-1, a single-node RDS db.r6g.large runs about 164 dollars a month on demand, 89 on a one-year all-upfront reservation, and 60 on a three-year term. That is a saving of around 1,250 dollars a year on one database node, which is usually enough to make the finance conversation straightforward.
Is ECS cheaper than EKS for a small team?
Yes, at small service counts. The EKS control plane still costs 10 cents per cluster hour in July 2026, or 73 dollars a month before you run a single container, while ECS charges nothing for its control plane and bills only the underlying compute. Kubernetes earns that overhead on large deployments with several teams. A startup running three services with two developers rarely gets enough from it to cover the difference.
What is cross-AZ data transfer and why does it cost so much?
Cross-AZ data transfer is traffic between resources in different availability zones of the same AWS region, such as an application server querying a database in another zone. AWS still charges one cent per gigabyte in each direction as of July 2026. It is trivial per request, but a chatty application making thousands of queries per second turns it into 150 to 300 dollars a month that almost nobody budgets for.
How accurate are design-time cloud cost estimates?
Directional rather than exact. Codelit refreshes pricing weekly from the AWS bulk pricing API and models around twenty services across four regions, so a mid-week price change can leave a number slightly stale, and default instance sizing is an assumption rather than a measurement. That is accurate enough to compare two designs or spot an over-provisioned component, and not accurate enough to reconcile an invoice.