SaveMyCert
Log in
5 of 5 free questions left today·for 10 a day
Cost-Optimized Architecture Design

SAP-C03 Storage and Database Cost Optimization: S3 Tiering and Lifecycle, EFS, EBS gp3, DynamoDB, Aurora I/O-Optimized, Database Savings Plans, Backup and Log Costs

24 min readSAP-C03 · Cost-Optimized Architecture DesignUpdated

Storage and database cost optimization on AWS means paying only for the capacity, performance, durability and retention each dataset actually needs, by choosing the right storage class, volume type, capacity mode, commitment and retention policy. For SAP-C03 that covers S3 Intelligent-Tiering, S3 Lifecycle and the Glacier classes, EFS lifecycle policies, EBS gp3 versus gp2, io2 and HDD volumes, DynamoDB capacity modes, reserved capacity and table classes, Aurora I/O-Optimized and Serverless v2, RDS reserved DB instances versus Database Savings Plans, AWS Backup and Data Lifecycle Manager retention, and the cost of logs and metrics. Most scenarios offer several valid designs; this lesson explains the limits, minimums and hidden per-object charges that make only one of them the cheapest.

What you’ll learn
  • Choose between S3 Intelligent-Tiering and S3 Lifecycle transitions, and pick the cheapest storage class for each age band from its retrieval time, read frequency, resilience and minimum storage duration.
  • Identify per-object and per-version charges (transition requests, archive metadata, minimum billable size, noncurrent versions, incomplete multipart uploads) and the Lifecycle actions that control them.
  • Configure EFS lifecycle policies so cold files tier down without penalising files that are read on a schedule.
  • Select EBS volume types and provision gp3 IOPS and throughput to meet a performance target at the lowest cost.
  • Optimize DynamoDB and Aurora costs with capacity modes, reserved capacity, table classes, Aurora I/O-Optimized and Serverless v2 auto-pause, and choose between reserved DB instances and Database Savings Plans.
  • Design cost-optimized backup retention with AWS Backup cold storage and Data Lifecycle Manager snapshot archiving.
  • Reduce observability cost with log retention, log classes, filtering before ingestion and low-cardinality metric aggregation.

How does S3 Intelligent-Tiering cut storage cost when access is unpredictable?

S3 Intelligent-Tiering cuts storage cost by moving each object between access tiers based on that object's own access history, so you do not need to know or analyse the access pattern in advance. It charges no retrieval fees, has no minimum storage duration, and moves an object back to the Frequent Access tier as soon as it is read. In exchange it adds a small monthly monitoring and automation charge per object.

Automatic tiers versus opt-in archive tiers

TierWhen an object moves thereHow it is read
Frequent AccessOn upload, and whenever the object is accessedMilliseconds
Infrequent Access (automatic)After 30 consecutive days without accessMilliseconds, no retrieval fee
Archive Instant Access (automatic)After 90 consecutive days without accessMilliseconds, no retrieval fee
Archive Access (opt-in)After a configured number of days without access (90 days or more), only if you activate itAsynchronous: the object must be restored first (typically hours)
Deep Archive Access (opt-in)After a configured number of days without access (180 days or more), only if you activate itAsynchronous: restore first, up to about 12 hours

The three automatic tiers are always on and every read is synchronous. The two archive tiers are activated with a bucket-level Intelligent-Tiering archive configuration (optionally filtered by prefix or tag). Once an object is in one of them, a GetObject fails with InvalidObjectState until the object is restored with RestoreObject; a restore moves it back to Frequent Access. Deleting the archive configuration stops new archiving, but objects already archived stay there until they are restored.

When it fits and when it does not

  • Fits: data lakes, media libraries and user content whose access is unknown or changes (a dataset that sits idle and then is queried heavily during an audit), when every read must stay synchronous and you want no retrieval fees.
  • Activate the archive tiers only when the application can tolerate asynchronous restores; otherwise rely on Archive Instant Access, which already gives a low price with millisecond reads.
  • Small objects: objects smaller than 128 KB are not monitored or tiered; they always stay in Frequent Access (and do not pay the monitoring charge). For large objects the per-object charge is negligible.
  • Objects read about every month rarely stay idle for 30 days, so most of them sit in Frequent Access at the S3 Standard price and still pay the monitoring charge. When the access pattern is known, a Lifecycle rule to a specific class is usually cheaper.

How do you choose S3 storage classes in a Lifecycle policy?

You choose S3 storage classes in a Lifecycle policy by matching each age band of the data to the cheapest class that still meets that band's retrieval time, read frequency and resilience needs, and by checking that each class's minimum storage duration is met. Lifecycle rules move objects by age (days since creation, or since becoming noncurrent), not by access, so they suit data whose access pattern is known in advance.

ClassAccessFits data readMinimum storage durationNotes
S3 StandardMillisecondsFrequentlyNoneNo retrieval fee
S3 Standard-IAMillisecondsAbout once a month30 daysPer-GB retrieval fee; 128 KB minimum billable object size; multiple AZs
S3 One Zone-IAMillisecondsAbout once a month30 daysCheaper than Standard-IA; one AZ, so data is lost if that AZ is destroyed; for reproducible or secondary copies
S3 Glacier Instant RetrievalMillisecondsAbout once a quarter90 daysLower storage price than Standard-IA but higher retrieval fee; 128 KB minimum billable size
S3 Glacier Flexible RetrievalRestore first: minutes (expedited) to hours (standard, about 3-5 hours; bulk longer)Once or twice a year90 daysArchive class; per-object metadata overhead
S3 Glacier Deep ArchiveRestore first: standard within 12 hours, bulk within 48 hoursRarely (compliance, legal hold)180 daysLowest storage price; per-object metadata overhead

Reading a requirement into a class

  • "Must load within milliseconds" rules out the two archive classes. Between the instant classes, read frequency decides: monthly reads favour the IA classes, quarterly reads favour Glacier Instant Retrieval, because its higher retrieval fee is paid less often.
  • "A few hours is acceptable" points at Glacier Flexible Retrieval; "12 hours is acceptable" points at Deep Archive, the cheapest class whose standard retrieval meets it. Paying for millisecond access a requirement does not ask for is the most common way an otherwise valid design costs more.
  • "Losing the data if an AZ is lost is acceptable" (thumbnails, renditions or anything regenerable from a master copy) is what makes One Zone-IA the cheapest instant-access choice.
  • Minimum storage durations are billed even if an object is deleted or transitioned earlier, so a schedule should keep data in each class at least that long. Lifecycle also does not move objects into Standard-IA or One Zone-IA until they are at least 30 days old.

The transition waterfall

Lifecycle only moves objects "down" towards colder classes: from S3 Standard to any class, from Standard-IA to Intelligent-Tiering, One Zone-IA or the Glacier classes, and so on down to Deep Archive. It never moves objects back up, and it cannot move objects from Intelligent-Tiering to Standard-IA. To bring archived data back to a warmer class you restore it and copy it.

Which per-object and per-version charges make S3 cost more than its per-GB price?

S3 costs more than its per-GB price suggests when a bucket holds billions of tiny objects, keeps every overwritten version, or keeps the parts of abandoned multipart uploads. Lifecycle can both cause and remove these charges, so an architect checks them before trusting a per-GB estimate.

Small objects

  • Transition requests are billed per object. Moving a billion 8 KB objects costs a billion transition requests, whatever their total size.
  • Archive metadata overhead: every object stored in Glacier Flexible Retrieval or Deep Archive carries about 40 KB of extra billed metadata: 8 KB at the S3 Standard rate (for the object's name and metadata) and 32 KB at the archive class rate. For a 4-16 KB object that overhead is several times the object itself.
  • 128 KB minimum billable size applies to Standard-IA, One Zone-IA and Glacier Instant Retrieval: a smaller object is billed as if it were 128 KB.
  • Default minimum transition size (since September 2024): new Lifecycle configurations do not transition objects smaller than 128 KB to any storage class by default, because the transition can cost more than it saves. Configurations created earlier keep their old default, which let small objects move into the Glacier archive classes. To include or exclude small objects explicitly, add an ObjectSizeGreaterThan / ObjectSizeLessThan filter to the rule or set the x-amz-transition-default-minimum-object-size header on the configuration.

The fix for tiny-object archives is to aggregate small objects into larger ones (for example batching telemetry into compressed files) before they are archived, or to filter them out of the transition by size. A rule that seems to "ignore" small objects in a new bucket is usually the 128 KB default working as designed.

Versioned buckets and multipart uploads

Lifecycle actionWhat it does
Transition / ExpirationAct on current versions. In a versioned bucket, Expiration adds a delete marker; the data stays as a noncurrent version.
NoncurrentVersionTransitionMoves versions to a colder class a set number of days after they become noncurrent; current objects are untouched.
NoncurrentVersionExpirationPermanently deletes noncurrent versions after NoncurrentDays (optionally keeping the newest N with NewerNoncurrentVersions). This sets the recovery window.
AbortIncompleteMultipartUploadAborts uploads not completed within DaysAfterInitiation and deletes their parts, which are otherwise billed as storage indefinitely.
ExpiredObjectDeleteMarkerRemoves delete markers that no longer have any versions behind them; tidies listings but frees almost no storage.

Every overwrite in a versioned bucket keeps the previous object as a full-size noncurrent version, so a frequently overwritten bucket can cost several times its visible size. The cost-optimal pattern keeps current versions where they are, moves noncurrent versions to the cheapest class that meets the restore time, and expires them at the end of the required recovery window. Suspending versioning does not delete existing versions and removes the ability to recover overwrites.

How do Amazon EFS lifecycle policies reduce file storage cost?

Amazon EFS lifecycle policies reduce file storage cost by moving files that have not been accessed for a set period from EFS Standard into the cheaper EFS Infrequent Access (IA) and EFS Archive storage classes of the same file system. Paths, mount targets and applications do not change: a tiered file is read at the same path, with higher first-byte latency and a per-GB data access charge.

PolicyWhat it controls
Transition into IADays without access before a file moves from Standard to IA (or None)
Transition into ArchiveDays without access before a file moves to Archive (must be longer than the IA timer); Archive requires a file system that uses Elastic throughput
Transition into StandardNone (default: a file stays in IA or Archive when it is read) or On first access (the file moves back to Standard when it is read)
  • Set the IA timer longer than the real access interval. A file read every month that tiers after 7 days spends most of its life in IA and pays IA access charges and latency on every read.
  • Use On first access for files that become hot again. With the default (None), files already in IA stay there even if they are read repeatedly; lengthening the IA timer only affects files that have not tiered yet.
  • Files smaller than 128 KiB are not tiered, and metadata always stays in Standard.
  • Throughput mode (Elastic, Provisioned, Bursting) changes performance and how throughput is billed, not the per-GB access charge for files in IA or Archive.

Moving files to S3 or replacing EFS can be cheaper per GB but changes how the application reads its data; backup tiering (AWS Backup cold storage) lowers the cost of backups, not of the live file system.

How do you choose EBS volume types and IOPS for the lowest cost?

You choose EBS volumes for cost by buying exactly the capacity, IOPS and throughput the workload needs, on the cheapest volume type that delivers them. In practice that means gp3 by default, io2 only when the workload needs an io2-only property, and the HDD types for large sequential data.

TypePerformance modelChoose it when
gp3 (SSD)3,000 IOPS and 125 MiB/s included at any size; extra IOPS and throughput provisioned independently of size, up to 80,000 IOPS and 2,000 MiB/s per volume. Limits: 500 IOPS per GiB, and throughput at most 0.25 MiB/s per provisioned IOPSAlmost every boot, application and database volume
gp2 (SSD)Performance tied to size: 3 IOPS per GiB (minimum 100, maximum 16,000); volumes under 1 TiB burst to 3,000 IOPS on creditsLegacy; migrate to gp3, which costs about 20% less per GiB
io2 Block Express (SSD)Provisioned IOPS, very high limits, sub-millisecond latency, 99.999% durability, Multi-Attach; you pay per GiB and per provisioned IOPS at higher ratesThe workload genuinely needs that latency, durability, Multi-Attach or more than gp3's limits
st1 (HDD)Throughput by size: 40 MiB/s per TiB baseline, 250 MiB/s per TiB burst, capped at 500 MiB/s per volumeLarge, sequential, frequently accessed data (logs, ETL, big data)
sc1 (HDD)12 MiB/s per TiB baseline, 80 MiB/s per TiB burst, capped at 250 MiB/s; lowest EBS priceLarge, sequential, infrequently accessed data with a relaxed scan window

Typical cost moves

  • gp2 to gp3 in place: Elastic Volumes changes the volume type, size, IOPS and throughput while the volume stays attached and in use, with no snapshot-and-swap. A gp2 volume that never needs more than 3,000 IOPS and 125 MiB/s gets that performance from the gp3 baseline at a lower price. (After a modification you must wait before modifying the same volume again.)
  • Over-sized gp2 bought for IOPS: a 6 TiB gp2 volume holding 500 GiB of data exists only to buy its 16,000 IOPS (gp2's cap, reached from about 5,334 GiB at 3 IOPS per GiB). A right-sized gp3 volume provisions the same IOPS on far less capacity (16,000 IOPS needs at least 32 GiB at 500 IOPS per GiB).
  • gp3 throughput needs IOPS: because throughput cannot exceed 0.25 MiB/s per provisioned IOPS, a target of T MiB/s needs at least T ÷ 0.25 IOPS. At the 3,000 IOPS baseline the ceiling is 750 MiB/s; 1,200 MiB/s needs at least 4,800 IOPS; 2,000 MiB/s needs 8,000.
  • io2 to gp3: if the workload tolerates single-digit millisecond latency and gp3 durability (99.8-99.9%), does not use Multi-Attach and fits within gp3 limits, one gp3 volume is cheaper and simpler than io2 or a RAID 0 stripe. The gp3 maximums were raised in 2025 (from 16,000 IOPS and 1,000 MiB/s), so striping several gp3 volumes is rarely needed now.
  • HDD for sequential data: st1 and sc1 are much cheaper per GiB but deliver poor random IOPS and cannot be boot volumes. st1 tops out at 500 MiB/s per volume, so a sustained higher sequential rate needs gp3. Check scan windows from the per-TiB numbers: a 12 TiB sc1 volume bursts at its 250 MiB/s cap, so a full sequential read takes about 14 hours (12 × 1,048,576 MiB ÷ 250 MiB/s ÷ 3,600 s); compare that with the scan window before choosing sc1 over st1.

How do you optimize DynamoDB costs with capacity modes, reserved capacity and table classes?

You optimize DynamoDB cost with three independent choices: the capacity mode (how throughput is billed), reserved capacity (a commitment discount on provisioned throughput) and the table class (the trade-off between storage price and request price).

ChoiceOptionBest for
Capacity modeOn-demandUnknown, spiky or new workloads; pay per request, nothing to manage
Capacity modeProvisioned with auto scalingSteady, predictable traffic; cheaper per unit when utilisation is high, and auto scaling follows daily curves instead of paying for peak all day
CommitmentReserved capacity (1-year, or 3-year in select Regions; a one-time partial upfront fee plus a discounted hourly rate)The long-lived baseline of provisioned read and write capacity. Available only for provisioned capacity on tables in the Standard table class; cannot be cancelled
Table classDynamoDB StandardThroughput-dominated tables (the default)
Table classDynamoDB Standard-IAStorage-dominated tables with rare access (order history, logs): much lower storage price, higher read/write price
  • Read the bill first. If storage is the larger part of a table's cost, Standard-IA usually wins; if throughput dominates, it loses.
  • Combine the rules: on-demand tables cannot use reserved capacity, and neither can Standard-IA tables. Moving a table that is still covered by a reservation to Standard-IA means paying the unused reservation plus Standard-IA request prices, so time a class change to the end of the reservation term.
  • Table class and capacity mode can both be changed on a live table without downtime (within service limits on how often), so they are reversible decisions; a reservation is not.
  • Database Savings Plans (below) are an alternative commitment that also covers DynamoDB usage, but a workload is covered by either reserved capacity or the plan, not both.

How do you optimize Aurora costs with I/O-Optimized and Serverless v2?

You optimize Aurora cost by choosing the storage configuration that matches the cluster's I/O share of spend, and the compute model that matches how often the cluster is busy.

Aurora Standard versus Aurora I/O-Optimized

Aurora StandardAurora I/O-Optimized
I/O requestsBilled per requestNo per-request I/O charges
Instance and storage priceLowerHigher
Choose whenI/O is a small part of Aurora spendI/O is about 25% or more of the cluster's Aurora spend, or I/O cost must be predictable
  • The storage configuration is a cluster setting, not a migration: the same cluster volume is billed differently, no data is copied and the application does not change. It works with provisioned instances and Serverless v2, and reserved DB instances keep applying.
  • You can switch from Standard to I/O-Optimized only once every 30 days; you can switch back to Standard at any time. It is a monthly-scale decision, not something to toggle around a weekly batch.
  • On instances without local NVMe storage the switch causes no downtime; on NVMe-based instance classes it restarts the database engine.
  • Aurora Optimized Reads is different: NVMe-based instance classes (such as db.r6gd and db.r6id) use local storage for tiered caching and temporary objects to speed up read-heavy and complex queries. It is a performance feature; it does not remove per-request I/O billing on Aurora Standard.

Aurora Serverless v2 and auto-pause

Aurora Serverless v2 bills compute in Aurora capacity units (ACUs) per second and scales between a minimum and maximum capacity. Setting the minimum capacity to 0 ACUs enables auto-pause: after a configurable period with no user connections, the instance pauses, instance charges stop (storage is still billed) and the next connection resumes it, typically in about 15 seconds and longer after a long pause (more than 24 hours). Any non-zero minimum, such as 0.5 ACU, turns auto-pause off and bills that capacity around the clock.

An instance cannot pause while something keeps it busy. Common blockers:

  • Open connections, including the connections an RDS Proxy keeps to every instance in the cluster.
  • Binary log or logical replication, being the primary cluster of an Aurora global database, and zero-ETL integrations.
  • Being a secondary cluster of an Aurora global database (its instances never auto-pause), or having any provisioned instance in the cluster, which keeps a Serverless v2 writer running.

The auto-pause interval is configurable from 300 seconds (5 minutes, the default) up to 86,400 seconds (24 hours); a shorter interval only shortens the wait after the last connection closes, it never overrides a blocker. Reader placement in failover tiers changes how readers follow the writer, not whether the cluster can pause. For dev and test fleets with ad hoc use, Serverless v2 with a 0 ACU minimum replaces stop/start schedulers (which do not fit unpredictable use) and is cheaper than reserving instances that sit idle.

When should you buy RDS reserved DB instances or a Database Savings Plan?

You buy reserved DB instances when the engine, Region and instance family will stay fixed for the term and you want the deepest discount, and a Database Savings Plan when the database estate will change engine, family, size or Region during the term.

RDS / Aurora reserved DB instancesDatabase Savings Plans
Term and payment1 or 3 years; All, Partial or No Upfront1 year, no upfront; commit to an hourly spend
Bound toOne engine and one Region (and deployment type); size-flexible within an instance family for supported engines (for example MySQL, MariaDB, PostgreSQL, Oracle BYOL, Db2 and Aurora), but not SQL Server or Oracle License IncludedNothing specific: applies across database engines, instance families, sizes, Regions and serverless usage of eligible database services
DiscountDeepest with a 3-year All Upfront termSmaller (up to about 35%), in exchange for flexibility
FitsStable, long-lived clusters that only grow within the same familyEstates planning engine migrations (for example SQL Server to Aurora MySQL), Region moves or generation upgrades
  • Size flexibility means a reservation for one size in a family (for example db.m7g) applies proportionally to other sizes in that family, so growth from db.m7g.large to db.m7g.xlarge is covered by adding reservations, not by a second kind of commitment.
  • Do not stack a Database Savings Plan with reserved DB instances or DynamoDB reserved capacity on the same usage; one of them would go unused.
  • Compute Savings Plans cover EC2, Fargate and Lambda, not RDS or Aurora. EC2 pricing models in general are covered in the pricing-models lesson for Task 3.1.
  • Reservations bought for clusters that do not exist yet pay for nothing until they do; reservations also discount idle hours, so they do not help a mostly idle database.

How do you keep backup and snapshot retention cost-optimized?

You keep backups cost-optimized by keeping each recovery point only as long as policy requires, keeping recent ones in warm storage while they are restored often, and moving long-kept ones to a colder tier only where the resource type supports it and the tier is actually cheaper.

AWS Backup lifecycle and cold storage

  • A backup rule's lifecycle sets when to move to cold storage and when to delete. Cold storage has a 90-day minimum, so retention must be at least the transition day plus 90 (a 200-day transition with 250-day retention is rejected).
  • Transition after the frequent-restore window: moving too early sends routine restores to cold storage, and for incrementally backed-up resources AWS recommends keeping backups warm for at least 8 days so incremental chains are not broken into extra full backups.
  • Only some resource types support cold storage. Amazon EFS (stays incremental in cold), DynamoDB (only with AWS Backup advanced DynamoDB features turned on), and Amazon EBS through EBS Snapshots Archive (which needs a monthly or less frequent schedule and converts snapshots to full copies) are examples. Amazon RDS and Aurora snapshots do not support cold storage: a rule's transition setting has no effect on them, and they stay at warm rates until deletion. Cost estimates that assume a plan-wide transition will undercount.

Amazon Data Lifecycle Manager and EBS Snapshots Archive

  • Data Lifecycle Manager (DLM) automates EBS snapshot and AMI creation by tag, with age-based or count-based retention, optional cross-Region and cross-account copies, and optional archiving.
  • An archive-enabled DLM schedule must create snapshots no more often than every 28 days (for example a monthly cron expression); daily and weekly schedules cannot archive. Archived snapshots have a 90-day minimum retention, and restoring one takes up to 72 hours.
  • An archived snapshot is a full snapshot. Standard-tier snapshots are incremental (only changed blocks), while the archive tier stores every block, at up to about 75% lower price per GB. Archiving therefore pays off when each snapshot is already close to the volume size (most blocks change between snapshots) and is kept for a long time; it costs more for small weekly incrementals of a slowly changing volume.
  • Copies to another Region or account double storage and add transfer cost; add them only when a stated DR or isolation requirement asks for them.

Backup governance (vault locks, cross-account backup policies, recovery objectives) belongs to the resilience domain; this task is about what retention and tiering cost.

How do you design cost-effective observability with log filtering, metric aggregation and retention?

You design cost-effective observability by reducing what is ingested at the source, choosing the right log class and destination, setting retention, and keeping custom-metric cardinality low. Each lever addresses a different line of the bill: filters applied after ingestion never reduce ingestion charges, and retention never reduces them either.

Retention

CloudWatch Logs log groups created with default settings (as Lambda and many services create them) never expire, so storage grows forever. Setting a retention period per log group makes CloudWatch Logs delete older events automatically. Exporting to S3 (CreateExportTask) or streaming with a subscription filter copies events but does not delete them from CloudWatch Logs.

Log classes

ClassPriceWhat it supports
StandardStandard ingestion priceFull feature set: metric filters, subscription filters, embedded metric format (EMF) extraction, Live Tail, Logs Insights
Infrequent AccessLower ingestion price (storage billed the same)Logs Insights queries and core storage features, but no metric filters, subscription filters or EMF extraction
DeliveryLowest; for Lambda logsLambda logs delivered onward to Amazon S3 or Amazon Data Firehose, not queried in CloudWatch Logs

The class is chosen when a log group is created and cannot be changed afterwards. Split by purpose: logs searched only during investigations go to Infrequent Access; logs that drive alarms through metric filters, stream to a SIEM or carry EMF metrics stay in Standard.

Filtering before ingestion

  • Lambda advanced logging controls: set the function's log format to JSON, then set an application log level (for example WARN) per function, and Lambda drops lower-level application lines before they reach CloudWatch Logs. Log-level filtering requires JSON format. The system log level filters Lambda's own platform lines (START, REPORT and similar), not the function's output. Levels are set per function, so development can keep DEBUG with no code change.
  • VPC flow logs: choose the traffic type (ACCEPT, REJECT or ALL) and the destination. A flow log's settings cannot be edited after creation, so changing the traffic type means creating a new flow log and deleting the old one. Delivering to Amazon S3 uses lower vended-log pricing than CloudWatch Logs, S3 Lifecycle can expire the records, and Amazon Athena serves occasional queries.

Metric aggregation and cardinality

CloudWatch bills custom metrics per unique combination of metric name and dimension values, so every new dimension value is a new metric. Collection interval, flush interval and storage resolution change data points and API calls, not the number of metrics.

  • CloudWatch agent: aggregation_dimensions (for example a list containing a dimension set such as InstanceType) publishes roll-ups per dimension set, and drop_original_metrics stops the agent also sending the per-instance originals, which is what keeps metric counts growing on fleets whose instances are replaced often. append_dimensions adds dimensions and therefore more metrics.
  • Embedded metric format: each distinct value set of a declared dimension set becomes a metric. Keep high-cardinality identifiers (customer ID, request ID) out of Dimensions and leave them as plain fields in the log event, where CloudWatch Logs Insights can filter on them when an investigation needs one customer's data.
  • A metric filter that extracts a high-cardinality field as a dimension has the same problem as EMF.

Tip. SAP-C03 tests storage and database cost optimization with scenarios in which several designs work and only one is cheapest while meeting every stated constraint: millisecond versus hours versus 12-hour retrieval, read frequency, acceptance of losing an Availability Zone's copy, no application or mount change, no downtime, a recovery window, or a fixed versus changing database estate. Expect questions that hinge on limits and hidden charges rather than headline prices: minimum storage durations, per-object transition and archive overhead, the 128 KB defaults, gp3's IOPS and throughput ratios, reserved capacity eligibility, the Aurora I/O-Optimized 30-day rule, what blocks Serverless v2 auto-pause, which resource types support cold storage, full-copy snapshot archives, and which log class features or filters act before or after ingestion. Select TWO items often pair two settings that only work together, such as JSON log format with a log level, or aggregation with dropping the originals.

Key takeaways
  • Unknown or changing access with synchronous reads: S3 Intelligent-Tiering's automatic tiers; activate its Archive and Deep Archive Access tiers only if the application can restore asynchronously.
  • Known access pattern: Lifecycle to the cheapest class that meets each band's retrieval time; monthly reads suit the IA classes (One Zone-IA when data is reproducible), quarterly reads Glacier Instant Retrieval, hours Glacier Flexible Retrieval, 12 hours Deep Archive.
  • Tiny objects and archives don't mix: per-object transition requests and 40 KB of archive metadata outweigh the saving; new Lifecycle rules skip objects under 128 KB by default.
  • Versioned buckets: NoncurrentVersionTransition and NoncurrentVersionExpiration for old versions, AbortIncompleteMultipartUpload for orphaned parts; plain Transition and Expiration act on current versions.
  • EFS: set the IA timer longer than the access interval and use Transition into Standard On first access for files that become hot again.
  • EBS: gp3 by default (3,000 IOPS and 125 MiB/s included, IOPS and throughput bought independently, throughput at most 0.25 MiB/s per IOPS); io2 only for io2-only needs; sc1/st1 for sequential data within their per-volume caps.
  • DynamoDB reserved capacity covers only provisioned capacity on Standard-class tables; Standard-IA suits storage-dominated tables.
  • Aurora I/O-Optimized pays off when I/O is about 25% or more of spend and can be entered only once every 30 days; Serverless v2 pauses only with a 0 ACU minimum and no open connections.
  • Reserved DB instances for a fixed engine, Region and family (deepest with 3-year All Upfront); Database Savings Plans for an estate that will change; never both on the same usage.
  • Cold backups: AWS Backup needs 90 days in cold and skips RDS/Aurora; archived EBS snapshots are full copies, so archive only large, long-kept snapshots from schedules of 28 days or more.

Frequently asked questions

When is S3 Intelligent-Tiering cheaper than an S3 Lifecycle rule?

S3 Intelligent-Tiering is usually cheaper when access is unknown or changes over time, because it moves each object to cheaper tiers after 30 and 90 days without access, moves it back when it is read, and charges no retrieval fees. It adds a small per-object monitoring charge and does not tier objects under 128 KB. When the access pattern is known in advance, for example data read about once a month or rarely after a year, an S3 Lifecycle rule to a specific class such as One Zone-IA, Glacier Instant Retrieval or Deep Archive is usually cheaper.

Why does my S3 Lifecycle rule not transition small objects?

Since September 2024, new S3 Lifecycle configurations do not transition objects smaller than 128 KB to any storage class by default, because the per-object transition request and, for the Glacier archive classes, about 40 KB of metadata overhead per object can cost more than the storage saved. To change it, add an ObjectSizeGreaterThan or ObjectSizeLessThan filter to the rule or set the x-amz-transition-default-minimum-object-size header on the configuration. Aggregating small objects into larger ones before archiving is usually the cheaper fix.

Should I move EBS gp2 volumes to gp3?

Usually yes. Amazon EBS gp3 costs about 20% less per GiB than gp2 and includes 3,000 IOPS and 125 MiB/s at any size, with more IOPS and throughput provisioned independently of size. Elastic Volumes changes a gp2 volume to gp3 in place while it stays attached. Volumes that were over-sized on gp2 only to get IOPS can also be right-sized on gp3 with provisioned IOPS, within 500 IOPS per GiB and 0.25 MiB/s of throughput per IOPS.

When should I use Aurora I/O-Optimized?

Use Aurora I/O-Optimized when I/O charges are about 25% or more of an Aurora cluster's spend, or when I/O cost must be predictable. It removes per-request I/O charges in exchange for higher instance and storage prices, is changed on the existing cluster without a migration, and keeps reserved DB instances applying. A cluster can move from Aurora Standard to I/O-Optimized only once every 30 days but can move back at any time; NVMe-based instances restart the engine when the setting changes.

Why does my Aurora Serverless v2 cluster never pause?

Aurora Serverless v2 auto-pause works only when the minimum capacity is 0 ACUs and the instance has had no user connections for the configured auto-pause period. Common blockers are an RDS Proxy, which keeps connections open to every instance, other long-lived client connections, binary log or logical replication, the primary role in an Aurora global database, and zero-ETL integrations. Any minimum above 0, such as 0.5 ACU, disables auto-pause entirely.

What is the difference between RDS reserved instances and Database Savings Plans?

RDS and Aurora reserved DB instances are 1- or 3-year reservations for one engine in one Region, size-flexible within an instance family for supported engines, and give the deepest discount with a 3-year All Upfront term. Database Savings Plans are 1-year, no-upfront commitments to an hourly spend that apply across database engines, instance families, sizes, Regions and serverless usage, with a smaller discount. Use reservations for stable databases and a Database Savings Plan for an estate that will migrate or move, and do not cover the same usage with both.

Do AWS Backup cold storage settings apply to RDS snapshots?

No. Amazon RDS and Aurora snapshots do not support AWS Backup cold storage, so a backup rule's transition setting has no effect on them and they stay at warm storage rates until they are deleted. Resource types that do support cold storage include Amazon EFS, DynamoDB with AWS Backup advanced features turned on, and Amazon EBS through EBS Snapshots Archive. Cold storage requires backups to stay at least 90 days in the cold tier.

How can I reduce Amazon CloudWatch Logs costs?

Reduce CloudWatch Logs costs by setting a retention period on every log group (the default is to keep logs forever), filtering at the source so fewer lines are ingested (for example Lambda JSON log format with an application log level, or a REJECT-only VPC flow log), creating log groups that are only queried occasionally in the Infrequent Access class, and sending rarely queried logs such as flow logs to Amazon S3. Subscription filters and exports act after ingestion, so they do not lower ingestion charges.

Source

This lesson covers the "Cost-Optimized Architecture Design" domain of the official SAP-C03 exam guide. Vendors revise their guides — check the source for the current version.

Test yourself on this topic
Practice now

Sign up free to mark lessons complete, bookmark topics and track your exam readiness.

Spotted a mistake in this lesson?