AWS Three-Tier Web & Caching Architecture — Overview
The three-tier web architecture (presentation → application → data) is the foundational pattern on SAP-C02 and SAA-C03. Every scaling, high-availability, and performance question builds on this base. This post covers the full pattern including caching strategies (ElastiCache, DAX, CloudFront), session management, and database scaling decisions.
Path-based routing
Health checks
Sticky sessions
SQL injection
Rate limiting
Bot control
Multi-AZ
Target tracking scaling
Predictive scaling
Session store
Query cache
Leaderboards
Multi-AZ (HA)
Read Replicas (scale reads)
Proxy (connection pooling)
Microsecond reads (DAX cache)
Auto-scaling capacity
Global Tables
Caching Architecture — Decision Guide
| Cache Layer | Service | What It Caches | Best For |
|---|---|---|---|
| Edge (CDN) | CloudFront | Static assets, API responses, dynamic content | Global users, reduce origin load, lower latency |
| Application | ElastiCache Redis/Memcached | DB query results, session data, computed values | Reduce DB load, sub-millisecond access, session store |
| Database | DAX (DynamoDB only) | DynamoDB items and queries | Microsecond reads, no code change (drop-in) |
| API | API Gateway caching | API responses per stage | Reduce Lambda invocations, cacheable GET endpoints |
ElastiCache — Redis vs Memcached
| Feature | Redis | Memcached |
|---|---|---|
| Data structures | Strings, hashes, lists, sets, sorted sets, streams | Simple key-value only |
| Persistence | Yes (AOF, RDB snapshots) | No (pure cache, data lost on restart) |
| Replication | Yes (Multi-AZ with auto-failover) | No replication |
| Clustering | Yes (up to 500 nodes, sharding) | Yes (multi-threaded, horizontal scale) |
| Pub/Sub | Yes | No |
| Use case | Sessions, leaderboards, queues, real-time analytics | Simple caching, multi-threaded workloads |
Exam rule: If the question mentions persistence, replication, Multi-AZ, complex data types, or pub/sub → Redis. If it mentions simplest cache with multi-threading → Memcached.
Session Management Patterns
| Pattern | How | Pros/Cons |
|---|---|---|
| Sticky sessions (ALB) | ALB routes user to same instance (cookie-based) | Simple, but instance failure loses session. Uneven load distribution. |
| ElastiCache Redis | Store session in Redis, any instance reads it | Stateless instances (scale freely). Sub-ms reads. Multi-AZ HA. |
| DynamoDB | Store session in DynamoDB with TTL for expiration | Serverless, auto-scaling. Good for Lambda-based apps. |
| Cognito tokens | JWT tokens (client-side, stateless) | No server-side session storage. Cannot revoke individual tokens easily. |
Exam answer: “Make application stateless for auto-scaling” → move sessions to ElastiCache or DynamoDB. Never store sessions on local disk.
Database Tier — Scaling Patterns
| Problem | Solution | Details |
|---|---|---|
| High read load | Read Replicas (up to 15 for Aurora) | Route reads to replicas. Reader endpoint auto-balances. |
| Connection exhaustion | RDS Proxy | Connection pooling. Essential for Lambda (prevents connection storms). |
| Read latency | ElastiCache (query cache) or DAX | Cache frequent queries. DAX for DynamoDB (microsecond). |
| Write scaling | Aurora Multi-Master or DynamoDB | Aurora: multi-write nodes. DynamoDB: unlimited write throughput. |
| Global users | Aurora Global Database / DynamoDB Global Tables | Cross-region replication. <1s lag (Aurora) or eventual (DynamoDB). |
High Availability Design
- ALB: Automatically multi-AZ. Health checks remove unhealthy targets.
- ASG: Spread across 2+ AZs. Min capacity ensures instances always running.
- RDS Multi-AZ: Synchronous standby in different AZ. Automatic failover (60-120s).
- ElastiCache Redis: Multi-AZ with auto-failover. Replica promotes automatically.
- NAT Gateway: Deploy one per AZ (AZ-independent). Avoids cross-AZ single point of failure.
Exam Tips
| Exam | Key Points |
|---|---|
| SAP-C02 | “Stateless for scaling” → sessions in ElastiCache/DynamoDB. “Reduce DB read load” → ElastiCache or Read Replicas. “Lambda + RDS connection issues” → RDS Proxy. “DynamoDB read latency” → DAX. “Global low latency” → CloudFront + Aurora Global/DynamoDB Global Tables. “Sticky sessions + HA” = contradiction → move to external session store. “Cache invalidation” → TTL + CloudFront invalidation API. |
AWS Certification Exam Practice Questions
Question 1:
A web application uses sticky sessions on the ALB to maintain user sessions. When an instance fails, users lose their sessions and must re-login. The application needs to maintain sessions across instance failures without changing the application code significantly. Which solution provides this?
- Increase the ASG minimum to prevent instance failures
- Store sessions in ElastiCache Redis with Multi-AZ, remove sticky sessions from ALB
- Store sessions in S3 with server-side encryption
- Enable cross-zone load balancing on the ALB
Show Answer
Answer: B — ElastiCache Redis provides sub-millisecond session retrieval, Multi-AZ ensures sessions survive failures, and removing sticky sessions allows any instance to serve any request (true statelessness). S3 (C) has higher latency and is not designed for frequent reads/writes like session data. Cross-zone load balancing (D) doesn’t solve session persistence.
Question 2:
A DynamoDB-backed application has read latency of 5-10ms. The business requires read latency under 1ms for a leaderboard feature. The application code should require minimal changes. Which caching solution achieves this?
- ElastiCache Redis with application-level caching logic
- DAX (DynamoDB Accelerator) — drop-in cache requiring only endpoint change
- CloudFront caching of API responses
- DynamoDB Strongly Consistent reads
Show Answer
Answer: B — DAX provides microsecond latency for DynamoDB reads and is a drop-in replacement (same API, just change the endpoint). Minimal code changes. ElastiCache (A) works but requires writing cache logic (check cache → miss → read DB → populate cache). CloudFront (C) caches at the API level, not DB level. Strongly consistent reads (D) are actually slower, not faster.
Question 3:
A Lambda function connects to an RDS Aurora database. During traffic spikes, the database hits its max connections limit (200) and Lambda functions fail with “too many connections” errors. Which solution resolves this without changing database instance size?
- Increase Lambda reserved concurrency to match database connections
- Add RDS Proxy between Lambda and Aurora for connection pooling and multiplexing
- Add Read Replicas to distribute connections
- Switch to DynamoDB which has no connection limits
Show Answer
Answer: B — RDS Proxy pools and shares database connections across Lambda invocations. Instead of each Lambda creating its own connection (1000 Lambdas = 1000 connections), Proxy multiplexes them through a smaller pool (e.g., 50 connections). This is the standard pattern for Lambda + RDS. Increasing concurrency (A) makes the problem worse. Read Replicas (C) help read scaling but each still has connection limits.
Question 4:
A company’s application serves 80% static content (images, CSS, JS) and 20% dynamic API responses. They want to reduce latency globally and decrease origin server load. The static content changes weekly; dynamic responses change per-user. Which architecture provides optimal caching?
- CloudFront with single default cache behavior (cache everything for 24 hours)
- CloudFront with two behaviors: static (TTL 7 days, high cache hit) and dynamic (TTL 0, all headers forwarded)
- ElastiCache Redis for both static and dynamic content
- S3 static hosting without CloudFront
Show Answer
Answer: B — Multiple cache behaviors allow different caching strategies per path. Static content (/static/*) gets long TTL (high cache hit ratio, dramatically reduces origin load). Dynamic content (/api/*) forwards headers for personalization but still benefits from CloudFront’s optimized TCP connections to origin. Caching everything (A) would serve stale dynamic content. ElastiCache (C) doesn’t help with global edge latency.
Question 5:
A three-tier application has an ASG with 4 instances across 2 AZs. One AZ has a failure, taking down 2 instances. The application needs to maintain 4 healthy instances at all times. How should the ASG be configured?
- Min: 4, Max: 4, Desired: 4 across 2 AZs
- Min: 4, Max: 8, Desired: 4 across 3 AZs
- Min: 2, Max: 6, Desired: 4 across 2 AZs with AZ rebalancing
- Min: 6, Max: 6, Desired: 6 across 3 AZs (N+1 per AZ)
Show Answer
Answer: D — To maintain 4 instances after losing an entire AZ, you need 6 instances across 3 AZs (2 per AZ). If one AZ fails (loses 2), you still have 4 running. Option A with 2 AZs: if one AZ fails, only 2 remain and ASG can’t launch more (it’s at max=4 and the remaining AZ has 2). Option B allows scaling up but starts with only 4. The N+1 pattern across 3 AZs is the standard HA approach.
Related Posts
- Serverless API Architecture
- Disaster Recovery Architecture
- Cost Optimization Architecture
- Global Traffic Management
References
- Web Application Hosting Best Practices — AWS Whitepaper
- Caching Strategies — ElastiCache Docs
- RDS Proxy with Lambda — AWS Blog
Frequently Asked Questions
ElastiCache vs DAX — when to use which?
DAX is exclusively for DynamoDB — it’s a drop-in cache (same API, change endpoint). Provides microsecond reads. ElastiCache works with any database or data source. Use DAX when your database is DynamoDB and you want minimal code changes. Use ElastiCache when you have RDS/Aurora, need complex data structures (sorted sets for leaderboards), or need a general-purpose cache for multiple data sources.
When should I use sticky sessions vs external session store?
Use external session store (ElastiCache/DynamoDB) almost always — it makes instances truly stateless, allows free scaling, and survives instance failures. Sticky sessions are only acceptable for legacy applications that cannot be modified. Even then, plan to migrate away. Sticky sessions cause uneven load distribution and session loss on failure.
How many AZs should a three-tier architecture use?
Minimum 2 AZs for basic HA, but 3 AZs is recommended for production. With 3 AZs, losing one AZ still leaves 2/3 capacity (67%). With 2 AZs, losing one leaves 50% and ASG may not scale fast enough. Most regions have 3+ AZs. Cost difference is minimal (no cross-AZ charge within the same service, only data transfer between instances).