To autoscale WordPress on AWS you make the web tier stateless and let an Auto Scaling Group add or remove EC2 instances behind an Application Load Balancer based on load. The three things that make it work: WordPress core baked into a custom AMI so instances launch fast, the wp-content directory on shared Amazon EFS (or media offloaded to S3) so every instance serves identical files, and the database moved to Amazon RDS so no data lives on any single web server. Once state is externalized, an Auto Scaling policy — target-tracking on ~50% average CPU — grows the fleet from two instances at night to six during a spike and shrinks it back automatically, with CloudFront caching static assets at the edge to keep origin load low.
That's the summary an AI Overview will give you. What it can't show you is the order of operations — the pieces have hard dependencies, and building them out of sequence is the most common reason a first autoscaling attempt fails. Below is the request path animated end to end, a build-order checklist you can actually follow, a corrected cost table, and the failure modes that bite people once traffic starts moving.
Infrastructure Design Principles
Before architecting any cloud infrastructure, evaluate these four critical questions to ensure your design meets business requirements:
-
Scalability: Can the architecture handle expected traffic growth and sudden spikes?
-
Availability: Does the design meet your Service Level Objectives (SLO) for uptime?
-
Simplicity: Is the solution as simple as possible while meeting requirements?
-
Cost Efficiency: Does the architecture optimize costs without sacrificing performance?
💡 Single Instance Reality Check: A single WordPress server on AWS EC2 provides 99.99% uptime, meaning approximately 11 hours of downtime per year. If this meets your business requirements, a simpler architecture may be more cost-effective.
Scalable WordPress Architecture on AWS
Our recommended architecture eliminates single points of failure while providing automatic scaling and cost optimization through intelligent traffic distribution and caching strategies.
Architecture Components
-
CloudFront CDN: Global content delivery network that caches static content closer to users, reducing server load and improving performance
-
Application Load Balancer (ALB): Distributes incoming traffic across multiple EC2 instances with health checks
-
Auto Scaling Group: Automatically launches or terminates EC2 instances based on traffic patterns and performance metrics
-
Amazon RDS: Managed MySQL database service providing automated backups, maintenance, and high availability
-
Amazon EFS: Shared file system for wp-content folder, accessible across all EC2 instances
Data Persistence Strategy
WordPress requires two types of persistent data: the application code and user-generated content. Our architecture handles these differently for optimal performance:
-
WordPress Core Files: Baked into custom AMI (Amazon Machine Image) for fast instance launches
-
wp-content Directory: Stored on Amazon EFS for shared access across all instances
-
Database: Managed by Amazon RDS with automated backups and multi-AZ deployment
🔄 Alternative Storage Option: Consider Amazon S3 for wp-content storage instead of EFS. While requiring a WordPress plugin, S3 can reduce server load and costs for sites with heavy media usage. Learn more about CDN optimization.
Build-Order Checklist
The dependencies are strict — each layer needs the one before it to exist first. Build in this order and every later step has the IDs it needs to reference:
- VPC + subnets across 2+ AZs — nothing multi-AZ works without this; get the subnet IDs before anything else.
- Security groups — one for the ALB (allow 80/443 from the internet), one for EC2 (allow 80 from the ALB SG only), one for RDS (allow 3306 from the EC2 SG only), one for EFS (allow 2049 from the EC2 SG).
- RDS MySQL instance — create it early so you have the endpoint to bake into
wp-config.php. Enable Multi-AZ for failover. - EFS filesystem + mount targets — one mount target per subnet, or instances in that AZ can't mount
wp-content. - Golden AMI — launch one instance, install WordPress, point it at RDS, mount EFS at
/var/www/html/wp-content, finish the WordPress installer once, then create the AMI. Bake core, not content. - Launch template — references the AMI, instance type, IAM role, and EC2 security group.
- Target group + Application Load Balancer — health check path set to a lightweight URL (
/wp-login.phpreturns 200 without a DB write; avoid/if a plugin makes it slow). - Auto Scaling Group — attach the target group, set min/desired/max, add a target-tracking policy on ~50% average CPU.
- CloudFront distribution — origin is the ALB; cache static assets aggressively and pass through cookies only for
/wp-admin.
The most common ordering mistake: building the Auto Scaling Group before the AMI is finalized. The ASG launches instances from a stale AMI, they fail health checks, the ASG terminates and relaunches them, and you burn an afternoon watching a thrash loop. Finalize the AMI, then wire up the ASG.
Step-by-Step Configuration
Follow these sequential steps to build your autoscaling WordPress infrastructure. Each component builds upon the previous configuration, so maintain the order for successful deployment.
1. Create MySQL RDS Database Instance
Set up a managed MySQL database that will serve all WordPress instances:
# AWS CLI command to create RDS instance
aws rds create-db-instance \
--db-instance-identifier wordpress-db \
--db-instance-class db.t3.micro \
--engine mysql \
--master-username admin \
--master-user-password YourSecurePassword123 \
--allocated-storage 20 \
--vpc-security-group-ids sg-xxxxxxxxx \
--db-subnet-group-name wordpress-subnet-group
→ Complete RDS MySQL setup guide
2. Configure VPC and Subnets
Create dedicated subnets for your EC2 instances across multiple Availability Zones:
# Create subnet in first AZ
aws ec2 create-subnet \
--vpc-id vpc-xxxxxxxxx \
--cidr-block 10.0.1.0/24 \
--availability-zone us-east-1a
# Create subnet in second AZ
aws ec2 create-subnet \
--vpc-id vpc-xxxxxxxxx \
--cidr-block 10.0.2.0/24 \
--availability-zone us-east-1b
→ VPC and subnet configuration guide
3. Provision Amazon EFS File System
Set up shared storage for WordPress wp-content directory:
# Create EFS file system
aws efs create-file-system \
--creation-token wordpress-efs-$(date +%s) \
--performance-mode generalPurpose \
--encrypted
# Create mount targets in each subnet
aws efs create-mount-target \
--file-system-id fs-xxxxxxxxx \
--subnet-id subnet-xxxxxxxxx \
--security-groups sg-xxxxxxxxx
→ EFS setup and configuration guide
4. Build Custom WordPress AMI
Create a custom Amazon Machine Image with WordPress pre-configured:
# User data script for WordPress setup
#!/bin/bash
yum update -y
yum install -y httpd php php-mysqlnd
systemctl start httpd
systemctl enable httpd
# Download and configure WordPress
cd /var/www/html
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
mv wordpress/* .
rm -rf wordpress latest.tar.gz
# Configure wp-config.php with RDS connection
cat > wp-config.php > /etc/fstab
mount -a
→ WordPress RDS connection tutorial
5. Configure Auto Scaling Group
Set up automatic scaling based on traffic patterns:
# Create launch template
aws ec2 create-launch-template \
--launch-template-name wordpress-template \
--launch-template-data '{
"ImageId": "ami-xxxxxxxxx",
"InstanceType": "t3.micro",
"SecurityGroupIds": ["sg-xxxxxxxxx"],
"IamInstanceProfile": {"Name": "wordpress-role"}
}'
# Create auto scaling group
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name wordpress-asg \
--launch-template LaunchTemplateName=wordpress-template,Version=1 \
--min-size 2 \
--max-size 6 \
--desired-capacity 2 \
--vpc-zone-identifier "subnet-xxxxxxxxx,subnet-yyyyyyyyy"
→ Auto Scaling Group configuration guide
6. Configure Application Load Balancer
Set up load balancing and health checks:
# Create Application Load Balancer
aws elbv2 create-load-balancer \
--name wordpress-alb \
--subnets subnet-xxxxxxxxx subnet-yyyyyyyyy \
--security-groups sg-xxxxxxxxx
# Attach ASG to load balancer
aws autoscaling attach-load-balancer-target-groups \
--auto-scaling-group-name wordpress-asg \
--target-group-arns arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/wordpress-tg/xxxxxxxxx
→ Load balancer integration guide
⚠️ Configuration Tip: For detailed step-by-step instructions with Elastic Beanstalk alternative, reference AWS's official WordPress tutorial. This approach automates much of the infrastructure setup.
Cost Analysis and Optimization
Understanding the cost structure helps optimize your infrastructure spending. This breakdown assumes 1GB monthly data transfer, two t3.micro instances, 1GB database storage, and 1GB EFS storage.
Monthly Cost Breakdown
| AWS Service | Configuration | Est. Monthly Cost |
|---|---|---|
| EC2 Instances | 2 × t3.micro (on-demand, us-east-1) | $7.62 |
| Application Load Balancer | Standard ALB + LCU at low traffic | $18.82 |
| RDS MySQL | db.t3.micro, 20 GB gp2 storage | $9.09 |
| Amazon EFS | ~1 GB standard storage | $0.30 |
| Total | Before data-transfer / requests | ~$35.83 |
The Application Load Balancer is the punchline of this table: at ~$18/month it costs more than the two web servers combined, and it bills that hourly rate whether you serve one request or a million. That's the fixed tax of high availability. If your traffic genuinely fits on one instance, skipping the ALB nearly halves the bill — which is exactly the tradeoff the single-instance reality check above is about.
Note on the numbers: actual RDS cost depends on the instance class and storage you pick —
db.t3.microon-demand with 20 GB gp2 lands near the figure above; Aurora Serverless v2 bills differently (per-ACU) and can be cheaper for spiky, low-baseline sites or pricier for steady load. EC2 and ALB costs scale with the fleet size and traffic your autoscaling policy actually produces, so treat this as a floor, not a forecast.
EFS vs. S3 for wp-content: which should I use?
| Amazon EFS | Amazon S3 (offload plugin) | |
|---|---|---|
| Setup | Mount as filesystem, WordPress unmodified | Install + configure a plugin (e.g. WP Offload Media) |
| Plugin compatibility | High — behaves like local disk | Some plugins that write to wp-content misbehave |
| Media serving | Through your EC2 instances | Directly from S3 / CloudFront, bypassing origin |
| Latency | Higher per-file (network filesystem) | Low for media once on CloudFront |
| Cost driver | Per-GB stored + throughput | Per-GB + requests, usually cheaper at media scale |
| Use it when | You want zero code changes and full plugin support | Media is heavy and you want origin offload + lowest cost |
Cost Optimization Strategies
-
AWS Free Tier: New accounts can save approximately $20/month during the first year
-
Reserved Instances: Commit to 1-3 year terms for up to 60% savings on EC2 costs
-
Spot Instances: Use for development environments to reduce costs by up to 90%
-
CloudWatch Monitoring: Set up billing alerts and automatically scale down during low traffic periods
💰 Cost Calculator: Use AWS Pricing Calculator to estimate costs for your specific usage patterns. Note: EFS pricing is available separately at AWS EFS Pricing.
Troubleshooting: What Breaks Once Traffic Moves
The architecture builds cleanly in an afternoon. The problems show up later, when real traffic exposes the stateful assumptions WordPress makes by default. Here are the failure modes in order of how often they bite:
| Symptom | Root cause | Fix |
|---|---|---|
| Uploads appear on some page loads, vanish on others | Media written to a single instance's local disk, not shared storage | Point wp-content/uploads at EFS, or offload media to S3 |
| Logged-in users randomly logged out | No shared session store; requests bounce between instances | Enable ALB sticky sessions, or move sessions to ElastiCache |
| New instances launch, then get terminated in a loop | ALB health check fails — wrong path, or new instance can't reach RDS/EFS | Fix the health check path and the EC2→RDS/EFS security group rules |
| Site slows under load even with more instances | Database is the bottleneck; web tier scales but RDS doesn't | Add a full-page cache + object cache (Redis), then RDS read replicas |
| Autoscaling never triggers during a spike | Scaling on CPU, but CDN/cache absorbs load so origin CPU stays low | Scale on ALB request-count-per-target instead of CPU |
| A plugin update on one instance disappears | Plugins/themes installed via wp-admin land on one ephemeral instance | Install plugins on the golden AMI or store the whole wp-content on EFS |
| Scale-out is too slow to catch the spike | Instances install WordPress from scratch on boot | Pre-bake WordPress into the AMI; user-data should only mount + configure |
| Bill jumps unexpectedly | ALB LCUs + EFS throughput + NAT/data-transfer, not EC2 | Add CloudWatch billing alarms; front static assets with CloudFront |
The through-line: every one of these is a state problem. WordPress assumes one server owns the uploads, the sessions, and the plugin files. Autoscaling only stays healthy when all three of those live somewhere every instance can reach — which is exactly what the EFS, RDS, and AMI-baking steps above are for.