Designing Cost-Optimized Architectures
Last verified against its sources on 23 September 2026
Domain 4 of the SAA-C03 exam — Design Cost-Optimized Architectures — is worth 20% of your score, covering storage, compute, database, and network cost decisions. Every lesson in this module applies the same underlying move: match the resource to the workload's actual pattern rather than its peak or its default, since nearly every cost optimization on AWS is really a performance or availability choice viewed through a different lens. Expect scenarios that name a usage pattern and a constraint, then ask which AWS option meets the requirement for the least money.
Cost-Optimized Storage
- Choose the right S3 storage class and lifecycle policy for a given access pattern.
- Choose the right EBS volume type and backup strategy to minimize cost without sacrificing required performance.
Amazon S3 prices storage by how quickly and how often you need the data back. S3 Standard costs the most per GB and has no retrieval fee or minimum duration — the right default for data accessed frequently. S3 Standard-IA and S3 One Zone-IA cost less per GB but add a per-GB retrieval fee, aimed at data you access rarely but need back quickly when you do; One Zone-IA costs less again by dropping to a single Availability Zone, trading some durability for a lower price on data you could recreate or that has another copy elsewhere. S3 Glacier Instant Retrieval, Glacier Flexible Retrieval, and Glacier Deep Archive push the price floor progressively lower for data that's rarely, if ever, read back, at the cost of retrieval taking anywhere from milliseconds to many hours.
A lifecycle policy automates the move down that ladder: transition an object to Standard-IA after 30 days, to Glacier Deep Archive after 90, and expire it entirely after a year, all without a person deciding case by case.
json
{
"Rules": [
{
"ID": "archive-old-logs",
"Filter": {"Prefix": "logs/"},
"Status": "Enabled",
"Transitions": [
{"Days": 30, "StorageClass": "STANDARD_IA"},
{"Days": 90, "StorageClass": "DEEP_ARCHIVE"}
],
"Expiration": {"Days": 365}
}
]
}When you genuinely don't know an object's future access pattern — or it changes over time — S3 Intelligent-Tiering removes the guesswork: it monitors access and moves objects between a frequent-access tier and an infrequent-access tier automatically, with no retrieval fees at all, for a small monthly monitoring fee per object. If you do know the pattern — logs nobody reads after 30 days, backups nobody restores — a manually chosen storage class and lifecycle rule is usually cheaper, since you skip Intelligent-Tiering's monitoring fee entirely.
Every infrequent-access and archive tier carries a minimum storage duration — 30 days for Standard-IA and One Zone-IA, 90 days for Glacier Flexible Retrieval, 180 days for Deep Archive. Delete or transition an object before that minimum elapses, and S3 still bills you for the full minimum period, as if you'd left it there. Moving short-lived data into an archive tier to save money can end up costing more than leaving it in Standard.
EBS cost follows the same logic as compute and file storage: pick the volume type that matches the workload's actual need rather than the highest-performing option by default. A gp3 volume with its free baseline (3,000 IOPS, 125 MiB/s) is enough for most workloads and costs meaningfully less than io2 provisioned to the same numbers — reach for io2 only when the workload's IOPS requirement genuinely exceeds what gp3 can provide.
For backups, EBS snapshots are stored in S3 and are incremental: after the first full snapshot, each later one stores only the blocks that changed, so a nightly snapshot schedule costs far less than repeatedly storing the whole volume. A Data Lifecycle Manager policy automates snapshot creation, retention, and deletion the same way an S3 lifecycle policy automates object transitions.
A team moves log files that get deleted after 20 days into S3 Glacier Deep Archive (180-day minimum) to save money. Does this actually save money?Answer it yourself first, then open this.
No — deleting before the 180-day minimum still bills for the full 180 days, so this likely costs more than just leaving the logs in S3 Standard for their short 20-day life.
Cost-Optimized Compute
- Choose the right EC2 purchasing option for a given workload's flexibility and commitment tolerance.
- Choose the most cost-effective load balancer and compute option for a given workload's traffic pattern.
EC2 pricing gives you a lever for every level of commitment. On-Demand charges by the second with no upfront commitment — the default, and the right starting point for a new or unpredictable workload. Spot Instances request unused EC2 capacity at savings AWS describes as up to 90% off On-Demand, in exchange for the instance being reclaimed on short notice — a fit for fault-tolerant, flexible work like batch processing or stateless workers, never for anything that can't handle an interruption. Reserved Instances commit to a specific instance configuration (type and Region) for a 1- or 3-year term for a significant discount. Savings Plans commit instead to a dollar amount of usage per hour, for the same 1- or 3-year terms, but apply automatically across instance families, sizes, and (for Compute Savings Plans) even AWS Lambda and Fargate — more flexible than a Reserved Instance's fixed configuration, in exchange for committing to spend rather than to a specific instance.
bash
aws ec2 run-instances \
--instance-market-options '{"MarketType":"spot"}' \
--image-id ami-0abcdef1234567890 \
--instance-type c7g.xlargeMatching the purchasing option to the workload is the actual skill being tested. A steady-state production fleet that runs the same instance type around the clock is the textbook case for a Reserved Instance or Savings Plan — the commitment matches reality, so the discount is close to free money. A workload whose instance types or Regions might change over the commitment period fits a Savings Plan better than a Reserved Instance, precisely because it isn't locked to one configuration. A batch job, CI runner, or anything that can checkpoint and resume fits Spot. A brand-new workload with unknown, still-settling usage patterns should start On-Demand and move to a commitment only once the usage is predictable enough to commit to.
Sizing matters as much as purchasing option: an oversized instance running at 10% CPU utilization wastes money no discount fixes. For workloads that run on a predictable schedule — a nightly batch job, a dev environment nobody uses overnight — EC2 hibernation or simply stopping instances outside their working hours avoids paying for idle compute at all, which beats any purchasing discount on the hours you don't need.
Load balancer choice affects cost too, not just capability. An Application Load Balancer and a Network Load Balancer are priced similarly, by the hour plus a usage-based dimension — the cost driver is running more load balancers than needed, not which type you pick for a workload that genuinely needs layer 7 or layer 4 features. A Gateway Load Balancer specifically routes traffic through third-party virtual appliances (like a firewall) and is priced for that use case; reaching for it without an actual appliance to route through adds cost with no benefit.
On the compute side, Fargate Spot extends the same interruption tradeoff to serverless containers: significant savings for fault-tolerant container workloads, without managing EC2 Spot capacity yourself.
A team commits to a 1-year Savings Plan sized for their current usage, then cuts their fleet in half three months later. What happens to the committed spend for the remaining 9 months?Answer it yourself first, then open this.
They still owe it — a Savings Plan commits to a dollar amount per hour regardless of actual usage, so usage dropping below the commitment still bills the committed amount; only usage above the commitment saves nothing extra.
Cost-Optimized Databases
- Choose the right RDS or Aurora purchasing and capacity option for a given database workload's usage pattern.
- Choose between DynamoDB capacity modes and table classes for a given cost tradeoff.
Amazon RDS and Aurora extend the same commitment-for-discount tradeoff covered for EC2: Reserved Instances commit to a specific database instance class and Region for a 1- or 3-year term, in exchange for a significant discount over On-Demand — the right fit for a production database that runs continuously at a known size. For workloads that don't fit that steady-state shape — development and test databases, new applications with unsettled traffic, or workloads with long idle stretches between bursts — Aurora Serverless v2 bills per Aurora Capacity Unit (ACU) actually consumed, scaling automatically within a range you set. As of a 2024 update, Aurora Serverless v2 can now scale all the way down to 0 ACUs, automatically pausing when idle and resuming (in roughly 15 seconds) on the next connection — a genuine scale-to-zero option for workloads that can tolerate that reconnect delay, which earlier versions of Aurora Serverless couldn't offer.
bash
aws rds modify-db-cluster \
--db-cluster-identifier my-dev-cluster \
--serverless-v2-scaling-configuration MinCapacity=0,MaxCapacity=4DynamoDB extends the same idea two ways. Its two capacity modes trade off the same way EC2's purchasing options do: on-demand charges per request with no commitment, ideal for unpredictable traffic; provisioned capacity, sized to a steady, known throughput, costs less per request — and provisioned capacity can itself be purchased as Reserved Capacity for an upfront 1- or 3-year commitment, the same steady-state discount pattern as RDS Reserved Instances.
A second, separate lever is the table class. DynamoDB Standard is the default, tuned for a balance of storage and throughput cost. DynamoDB Standard-IA trades roughly 25% higher throughput cost for roughly 60% lower storage cost — worth switching to specifically when a table's storage is genuinely its dominant cost, such as years of application logs or order history that's rarely read. Neither performance, availability, nor durability changes between the two table classes; it's purely a cost lever, and you can switch between them without touching your application code.
Backup retention has its own cost trap. Deleting an RDS DB instance deletes its automated backups (unless you choose to retain them), but it never deletes manual snapshots — those persist, and keep billing for their storage, until someone explicitly deletes them. A team that deletes a decommissioned database and assumes the cleanup is complete can end up paying for manual snapshots indefinitely.
Caching also has a cost dimension, not just a performance one: an ElastiCache layer that absorbs read traffic (using the lazy loading or write-through strategy from earlier) reduces the read capacity a database needs to be provisioned for, which can lower the database's own cost enough to offset the cache's own cost — especially for a read-heavy, hot-key workload.
A team deletes a decommissioned RDS instance, choosing to skip the final snapshot since they still have several manual snapshots from earlier testing. Are those manual snapshots deleted along with the instance?Answer it yourself first, then open this.
No — deleting a DB instance never deletes manual snapshots. They persist and keep incurring storage charges until someone explicitly deletes them.
Cost-Optimized Networking
- Choose the most cost-effective way to reduce NAT gateway data-processing charges for a given traffic pattern.
- Choose between VPC peering and AWS Transit Gateway for a given number of VPCs and connectivity need.
A NAT gateway bills two ways at once: an hourly charge for every Availability Zone it's provisioned in, plus a per-GB charge for every gigabyte it processes, in both directions — and that data-processing charge applies on top of any standard data transfer charge for traffic leaving to the internet. Traffic to AWS services that support VPC endpoints — Amazon S3 and DynamoDB via a gateway endpoint, dozens of other services via an interface endpoint — can bypass the NAT gateway entirely. A gateway endpoint costs nothing at all: no hourly charge, no per-GB charge, just a route added to the subnet's route table. An interface endpoint isn't free (it has its own small hourly and per-GB charge), but for high-volume traffic to a service like Secrets Manager or CloudWatch Logs, it's usually still cheaper than paying the NAT gateway's processing charge on the same traffic. For a private subnet whose NAT traffic is mostly bound for a small number of AWS services, adding the matching endpoints is close to a free reduction in NAT gateway cost.
bash
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0123456789abcdef0 \
--service-name com.amazonaws.us-east-1.s3 \
--route-table-ids rtb-0123456789abcdef0 \
--vpc-endpoint-type GatewayHow many NAT gateways to run is its own tradeoff. A single shared NAT gateway in one AZ costs the least in baseline hourly charges, but every private subnet in a different AZ routing through it pays cross-AZ data transfer charges on top — acceptable for a development environment with light, non-critical traffic, and also a single point of failure if that AZ has a problem. One NAT gateway per AZ costs more in baseline hourly charges (one gateway-hour per AZ instead of one), but keeps every subnet's NAT traffic inside its own AZ, avoiding the cross-AZ charge and the single point of failure — the standard choice for a production workload with real traffic volume.
Which one is actually cheaper depends on the numbers: above roughly a few terabytes a month of cross-AZ NAT traffic, the extra cross-AZ charges on a shared NAT gateway can exceed the cost of simply running one gateway per AZ, making the "more expensive-looking" option the cheaper one in practice.
Connecting several VPCs together has the same shape of tradeoff. VPC peering has no hourly charge for the connection itself — you pay only standard data transfer rates for the traffic that crosses it — but it isn't transitive: if VPC A peers with B and B peers with C, A still can't reach C without a direct peering connection of its own. Connecting n VPCs this way needs up to n(n-1)/2 peering connections, which gets unwieldy fast. AWS Transit Gateway costs an hourly charge per attachment plus a per-GB charge, but every attached VPC can reach every other one through a single hub, with no mesh of individual connections to manage. For a handful of VPCs, peering is usually cheaper and simpler; past that, Transit Gateway's per-attachment cost is often lower than the operational and cross-AZ cost of maintaining a growing peering mesh.
A company has 8 VPCs that all need to reach each other, and is currently managing this with individual VPC peering connections. How many peering connections does a full mesh of 8 VPCs require?Answer it yourself first, then open this.
28 — n(n-1)/2 with n=8 is 8×7/2=28. This is exactly the kind of growth that makes Transit Gateway's single-hub model worth its per-attachment cost once a VPC count gets this large.
Sources
- Understanding and managing Amazon S3 storage classes
- Amazon EBS snapshots
- Amazon EBS Volume Types
- Amazon EC2 billing and purchasing options
- What are Savings Plans?
- Evaluate your DynamoDB table class selection
- Deleting a DB instance for Amazon RDS
- How Aurora Serverless v2 works
- Pricing for NAT gateways
- What is AWS Transit Gateway for Amazon VPC?