Multi-Tier Architecture Patterns
Key concepts
Web tier, application tier, data tier
Stateless application design
Session management strategies
Load balancer placement
Database tier isolation
Overview
Multi-tier architecture (also called n-tier architecture) is a cornerstone pattern for building scalable, maintainable, and resilient applications on AWS. This pattern divides an application into logical layers—typically presentation, application, and data tiers—that can be independently developed, scaled, and managed.
Understanding multi-tier architecture is essential for the SAA-C03 exam because it forms the foundation for designing resilient, high-performing, and cost-optimized solutions. You must know how to properly isolate tiers using VPC subnets, implement load balancing between layers, configure Auto Scaling for each tier, and select appropriate AWS services for each layer.
Tier Isolation
Each tier should be isolated in its own subnet(s) with security groups controlling traffic flow between tiers. The presentation tier is public-facing, while application and database tiers remain in private subnets.
Exam questions frequently test your understanding of which tiers should be public vs private, how load balancers connect tiers, and when to use internal vs internet-facing ALBs.
Key Concepts
Three-Tier Architecture Overview

Three-Tier Architecture
The three-tier architecture divides applications into three distinct layers:
- Presentation Tier: User-facing components (web servers, CDN, static content)
- Application Tier: Business logic and processing (app servers, APIs)
- Data Tier: Persistent storage (databases, caches, file systems)
Each tier can scale independently and be managed by different teams.
Presentation Tier
Presentation Tier
The presentation tier handles all user interactions and serves as the entry point to your application. It typically includes:
- Amazon CloudFront: CDN for caching static content globally
- Application Load Balancer: Distributes traffic to web servers
- Amazon S3: Hosts static assets (HTML, CSS, JS, images)
- Amazon Route 53: DNS routing and health checks
User Request Flow:
├── Route 53 (DNS Resolution)
│ └── Resolves to CloudFront or ALB
│
├── CloudFront (CDN - Optional)
│ ├── Caches static content at edge locations
│ ├── Reduces latency for global users
│ └── Offloads traffic from origin
│
├── Application Load Balancer (Internet-Facing)
│ ├── Deployed in PUBLIC subnets
│ ├── Has public IP addresses
│ ├── SSL/TLS termination
│ └── Routes to web tier instances
│
└── Web Servers (EC2 or Containers)
├── Can be in public OR private subnets
├── Serve dynamic content
└── Forward API calls to app tierApplication Tier
Application Tier
The application tier contains the business logic and processes requests from the presentation tier. It should always be in private subnets with no direct internet access.
Key components:
- Internal Application Load Balancer: Routes traffic from web tier
- EC2 Auto Scaling Groups: Scales based on demand
- Amazon ECS/EKS: Container orchestration options
- AWS Lambda: Serverless compute for specific functions
Application Tier Architecture:
Internal ALB (in Private Subnets)
├── Receives requests from Web Tier only
├── No public IP - not internet accessible
├── Routes based on path or host headers
└── Health checks app server instances
Auto Scaling Group
├── Spans multiple Availability Zones
├── Minimum: 2 instances (high availability)
├── Scaling Policy: CPU > 70% = scale out
├── Scaling Policy: CPU < 30% = scale in
└── Instances in PRIVATE subnets
App Servers (EC2/Containers)
├── Run business logic
├── Connect to data tier
├── Stateless design (session in ElastiCache)
└── Access internet via NAT GatewayData Tier
Data Tier
The data tier stores and manages application data. It must be in private subnets with the most restrictive access controls.
Common AWS services:
- Amazon RDS: Managed relational databases (MySQL, PostgreSQL, etc.)
- Amazon Aurora: High-performance MySQL/PostgreSQL compatible
- Amazon DynamoDB: Serverless NoSQL database
- Amazon ElastiCache: In-memory caching (Redis, Memcached)
Data Tier Service Selection
| Requirement | AWS Service | Key Feature |
|---|---|---|
| Relational data with complex queries | Amazon RDS/Aurora | ACID compliance, Multi-AZ |
| High-throughput key-value access | Amazon DynamoDB | Single-digit ms latency |
| Session state caching | Amazon ElastiCache Redis | In-memory, sub-ms latency |
| Document storage | Amazon DocumentDB | MongoDB compatible |
| Graph relationships | Amazon Neptune | Graph database |
VPC Design for Multi-Tier Architecture

Subnet Strategy
VPC CIDR: 10.0.0.0/16 (65,536 IPs)
Availability Zone A Availability Zone B
───────────────────── ─────────────────────
Public Subnet A Public Subnet B
10.0.1.0/24 10.0.2.0/24
├── Internet Gateway ├── Internet Gateway
├── NAT Gateway A ├── NAT Gateway B
├── ALB (internet-facing) ├── ALB (internet-facing)
└── Bastion Host (optional) └── Bastion Host (optional)
Private Subnet A (App) Private Subnet B (App)
10.0.11.0/24 10.0.12.0/24
├── Internal ALB ├── Internal ALB
├── App Server EC2 ├── App Server EC2
└── Route: 0.0.0.0/0 → NAT-A └── Route: 0.0.0.0/0 → NAT-B
Private Subnet A (DB) Private Subnet B (DB)
10.0.21.0/24 10.0.22.0/24
├── RDS Primary ├── RDS Standby (Multi-AZ)
├── ElastiCache Primary ├── ElastiCache Replica
└── No internet route needed └── No internet route neededSecurity Group Configuration
Security Group Strategy
Security groups act as virtual firewalls, controlling traffic between tiers. The key principle is to reference security groups (not IP ranges) for tier-to-tier communication.
SG-ALB-Public (Internet-Facing ALB)
├── Inbound: TCP 443 from 0.0.0.0/0 (HTTPS from internet)
├── Inbound: TCP 80 from 0.0.0.0/0 (HTTP - redirect to HTTPS)
└── Outbound: TCP 80 to SG-Web-Tier
SG-Web-Tier (Web Servers)
├── Inbound: TCP 80 from SG-ALB-Public
├── Outbound: TCP 80 to SG-ALB-Internal
└── Outbound: TCP 443 to 0.0.0.0/0 (for external APIs)
SG-ALB-Internal (Internal ALB)
├── Inbound: TCP 80 from SG-Web-Tier
└── Outbound: TCP 8080 to SG-App-Tier
SG-App-Tier (Application Servers)
├── Inbound: TCP 8080 from SG-ALB-Internal
├── Outbound: TCP 3306 to SG-Database (MySQL)
├── Outbound: TCP 6379 to SG-Cache (Redis)
└── Outbound: TCP 443 to 0.0.0.0/0 (via NAT)
SG-Database (RDS)
├── Inbound: TCP 3306 from SG-App-Tier ONLY
└── Outbound: None required
SG-Cache (ElastiCache)
├── Inbound: TCP 6379 from SG-App-Tier ONLY
└── Outbound: None requiredLoad Balancer Selection

Load Balancer Types
| Load Balancer | Layer | Use Case | Tier Placement |
|---|---|---|---|
| Application Load Balancer (ALB) | Layer 7 (HTTP/HTTPS) | Web apps, path-based routing | Presentation → App |
| Network Load Balancer (NLB) | Layer 4 (TCP/UDP) | Ultra-low latency, static IP | High-performance APIs |
| Gateway Load Balancer (GWLB) | Layer 3 (IP) | Network appliances (firewalls) | Security inspection |
Internet-Facing vs Internal ALB
ALB Types
Internet-Facing ALB: Has public IP addresses, deployed in public subnets, receives traffic from the internet. Used for the presentation tier.
Internal ALB: Has private IP addresses only, deployed in private subnets, receives traffic only from within VPC. Used between application tiers.
INTERNET-FACING ALB (for Web Tier)
├── Scheme: internet-facing
├── Subnets: Public subnets (2+ AZs)
├── Security Group: SG-ALB-Public
├── Listeners:
│ ├── HTTPS:443 → Web Target Group
│ └── HTTP:80 → Redirect to HTTPS
└── Target Group:
├── Type: instance
├── Protocol: HTTP
├── Port: 80
└── Health Check: /health
INTERNAL ALB (for App Tier)
├── Scheme: internal
├── Subnets: Private subnets (2+ AZs)
├── Security Group: SG-ALB-Internal
├── Listeners:
│ └── HTTP:80 → App Target Group
└── Target Group:
├── Type: instance
├── Protocol: HTTP
├── Port: 8080
└── Health Check: /api/healthAuto Scaling Configuration
Scaling Strategies by Tier
Auto Scaling by Tier
| Tier | Scaling Trigger | Min/Max | Cooldown |
|---|---|---|---|
| Web Tier | Request Count per Target | 2-10 instances | 300 seconds |
| App Tier | CPU Utilization > 70% | 2-20 instances | 300 seconds |
| Database | Read Replicas (manual) | 1 primary + 0-5 replicas | N/A |
{
"AutoScalingGroupName": "app-tier-asg",
"PolicyName": "cpu-target-tracking",
"PolicyType": "TargetTrackingScaling",
"TargetTrackingConfiguration": {
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetValue": 70.0,
"ScaleInCooldown": 300,
"ScaleOutCooldown": 60
}
}Serverless Multi-Tier Architecture

Serverless Three-Tier
AWS enables fully serverless three-tier architectures that eliminate server management:
- Presentation: S3 + CloudFront (static hosting)
- Application: API Gateway + Lambda (compute)
- Data: DynamoDB or Aurora Serverless (database)
Traditional vs Serverless
| Aspect | Traditional (EC2) | Serverless |
|---|---|---|
| Scaling | Auto Scaling Groups | Automatic |
| Cost Model | Per-hour (running) | Per-request |
| Management | Patch, maintain servers | No servers to manage |
| Cold Start | None | Possible (Lambda) |
| Best For | Consistent high traffic | Variable/spiky traffic |
Serverless Three-Tier:
PRESENTATION TIER
├── Amazon S3
│ └── Static website hosting (React/Vue/Angular)
├── Amazon CloudFront
│ └── CDN + HTTPS + caching
└── Amazon Route 53
└── DNS with health checks
APPLICATION TIER
├── Amazon API Gateway
│ ├── REST or HTTP APIs
│ ├── Request validation
│ ├── Rate limiting
│ └── Authorization (Cognito/Lambda)
├── AWS Lambda
│ ├── Business logic functions
│ ├── Auto-scales to demand
│ └── Pay per invocation
└── Amazon Cognito
└── User authentication
DATA TIER
├── Amazon DynamoDB
│ ├── On-demand or provisioned
│ ├── Single-digit ms latency
│ └── Global tables for multi-region
└── Amazon S3
└── Object storage for filesHigh Availability Patterns
Multi-AZ Deployment
Multi-AZ Best Practices
For high availability, deploy all tiers across multiple Availability Zones:
- ALB: Automatically spans multiple AZs
- EC2 ASG: Configure across 2+ AZs minimum
- RDS: Enable Multi-AZ for automatic failover
- ElastiCache: Use cluster mode with replicas
HIGH AVAILABILITY CHECKLIST:
✓ VPC spans 2+ Availability Zones
✓ Each tier has subnets in each AZ
✓ ALB configured for all AZs
✓ Auto Scaling Group spans all AZs
✓ RDS Multi-AZ enabled
✓ ElastiCache with replicas in different AZs
✓ NAT Gateway in each AZ (for resilience)
✓ Route 53 health checks configuredUse Cases
- E-commerce Applications: Web storefront (presentation), order processing (application), product catalog and orders (database)
- SaaS Applications: User dashboard (presentation), API services (application), tenant data (database)
- Content Management: Website frontend (presentation), content APIs (application), content database (data)
- Enterprise Applications: User portals (presentation), business services (application), ERP/CRM data (database)
Best Practices
- Isolate Tiers in Separate Subnets: Never place databases in public subnets
- Use Internal Load Balancers: Connect tiers with internal ALBs, not direct instance IPs
- Reference Security Groups: Use SG references instead of IP ranges for tier-to-tier rules
- Design Stateless App Tier: Store session state in ElastiCache or DynamoDB
- Enable Multi-AZ: Deploy across at least 2 AZs for high availability
- Implement Health Checks: Configure proper health checks on all load balancers
- Use NAT Gateways per AZ: Avoid single point of failure for outbound traffic
- Monitor All Tiers: Use CloudWatch for metrics and alarms at each layer
Common Exam Scenarios
Exam Scenarios
| Scenario | Solution | Why |
|---|---|---|
| Web app with spiky traffic | ALB + Auto Scaling + RDS Multi-AZ | Scales presentation/app, HA for data |
| App tier needs internet access | NAT Gateway in public subnet | Private instances access internet |
| Reduce database load | Add ElastiCache + Read Replicas | Cache reads, distribute queries |
| Secure database access | Private subnet + SG refs | No public IP, tier-to-tier only |
| Global low latency | CloudFront + Multi-Region | Edge caching, regional failover |
| Serverless web app | S3 + API Gateway + Lambda + DynamoDB | No servers, pay per use |
Common Pitfalls
Pitfall 1: Database in Public Subnet
Mistake: Placing RDS or database instances in public subnets.
Why it fails: Exposes database to internet attacks, violates security best practices.
Correct Approach: Always place databases in private subnets; access only from app tier.
Pitfall 2: Single NAT Gateway
Mistake: Using one NAT Gateway for all AZs.
Why it fails: Single point of failure; one AZ outage breaks all private subnet internet access.
Correct Approach: Deploy NAT Gateway in each AZ for high availability.
Pitfall 3: Hardcoded Instance IPs
Mistake: Using specific EC2 instance IPs instead of load balancer DNS.
Why it fails: Instances can be replaced by Auto Scaling; IPs change.
Correct Approach: Use load balancer DNS names; reference security groups.
Pitfall 4: Stateful Application Servers
Mistake: Storing session state locally on EC2 instances.
Why it fails: Sessions lost when instances terminate or scale down.
Correct Approach: Use ElastiCache Redis or DynamoDB for session storage.
Pitfall 5: Internet-Facing Internal Resources
Mistake: Using internet-facing ALB for tier-to-tier communication.
Why it fails: Unnecessary internet exposure, potential security risk.
Correct Approach: Use internal ALB for communication between tiers.
Related Services
Quick Reference
Architecture Decision Matrix
When to Use Which Pattern
| Traffic Pattern | Architecture | Key Services |
|---|---|---|
| Consistent high load | Traditional 3-tier | ALB, EC2 ASG, RDS |
| Variable/spiky traffic | Serverless | API Gateway, Lambda, DynamoDB |
| Mixed workload | Hybrid | EC2 + Lambda, RDS + DynamoDB |
| Global audience | Multi-Region | CloudFront, Global Accelerator, Aurora Global |
Port Reference
PRESENTATION TIER
├── 443 (HTTPS) - ALB listener
├── 80 (HTTP) - Redirect to HTTPS
└── 22 (SSH) - Bastion only
APPLICATION TIER
├── 8080 (HTTP) - App server
├── 8443 (HTTPS) - Secure app
└── Custom API ports
DATA TIER
├── 3306 (MySQL/Aurora)
├── 5432 (PostgreSQL)
├── 6379 (Redis)
├── 11211 (Memcached)
└── 27017 (MongoDB/DocumentDB)Test Your Knowledge
A solutions architect is designing a three-tier web application. The database tier must be highly available with automatic failover. Which configuration meets this requirement?
Which load balancer type should be used to connect the web tier to the application tier in a private subnet?
A web application stores user session data on individual EC2 instances. During scale-in events, users are losing their sessions. What is the recommended solution?
A company wants private EC2 instances in an application tier to download software updates from the internet. What should be configured?