We start from the e-commerce architecture: EC2 for the site, RDS for the database, S3 + CloudFront for images. To scale, you don’t grow one machine forever — you put several behind a load balancer, and offload the database.
If you haven’t read the foundation, start with why AWS for an e-commerce — this article is its direct sequel.
The key to controlled cost is elasticity: add instances when traffic rises, remove them when it falls. You only pay for peak capacity during the peak.
An ALB spreads traffic over N instances and automatically drops those failing the health check.
Rules on CPU (or request queue) add/remove instances. Min 2 for resilience, max capped for budget.
Reads (catalog, product pages) go to RDS replicas; the primary keeps writes (orders).
ElastiCache/Redis absorbs what’s read on repeat. The cheapest query is the one you don’t run.
The database is almost always the first bottleneck. Before adding web servers, cache what’s read on repeat — often 80% of queries hit 20% of the data.
The trap: over-provisioning “just in case” and leaving it running. Set a reasonable auto-scaling max and monitor — otherwise a looping bug can explode the bill overnight.
Scaling and cost are two sides of the same coin. The playbook to deflate what has drifted: cut an AWS bill in half.
“Auto-scaling” isn't one button. There are several ways to trigger adding instances, and the choice changes behavior during a spike. On my e-commerce architecture I almost always start from target tracking: I set a target — say 50% average CPU, or a request count per instance — and EC2 Auto Scaling creates and manages the CloudWatch alarms itself to hold that target. AWS explicitly recommends it for scaling on average CPU or request count per target.
My default
Fine control
A detail that trips many people up: cooldown only applies to simple scaling policies. Target tracking and step scaling can start a scale-out immediately — it's the instance warmup (the time for a new machine to become healthy) that paces things, not a fixed cooldown. AWS now steers away from simple scaling policies in favor of target tracking.
Target tracking is reactive: it waits for CPU to climb before acting, and a fresh instance takes a minute or two to boot. For a spike I can see coming — Monday-morning sale, a 6pm campaign — I add predictive scaling. It analyzes up to 14 days of history, derives an hourly 48-hour forecast, and provisions before the load lands. Two things to remember: it starts in “forecast only” mode (it forecasts without scaling, so you can validate first), and it only scales out — to come back down you keep your dynamic policies. Predictive handles the predictable, target tracking absorbs the unexpected on top.
For read replicas there's no equivalent magic: RDS does not autoscale replicas. You add and remove them by hand, and each replica is billed as an instance of its class. That's exactly why cache comes first: adding a replica is a fixed cost that won't quietly fall back at night.
A cache is only worth its hit ratio: the share of requests served from cache instead of from the origin. That number isn't cosmetic — it drives the bill directly. At 80% hit, only one request in five reaches the database or EC2; at 95%, it's one in twenty. Going from 80% to 95% isn't “15% better”: it quarters the load that lands behind — potentially one fewer read replica, or two fewer EC2 instances during the peak.
In practice there are two caches to watch. On ElastiCache/Redis, the AWS guide on which metrics to monitor recommends alarming on evictions and memory: when Redis evicts keys for lack of room, your hit ratio drops and the database eats it all again. In front of static assets, CloudFront has its own lever: increase the cache hit ratio by lengthening max-age, trimming the query strings and cookies pulled into the cache key, and enabling Origin Shield as an extra layer in front of the origin.
The right loop: measure the hit ratio first, then decide. Often, gaining 10 points of hit costs nothing (just config) and spares you from adding hardware that bills 24/7.
Ground on real data, function calling, guardrails: escape the believable fiction.
When the agent should ask vs decide alone, and how to interrupt then resume a durable run.