The $250 WordPress Mistake: A Postmortem on a Slow AWS Architecture
Read Here For Free
The $250 WordPress Mistake: A Postmortem on a Slow AWS Architecture
I’m an architect. I design resilient, secure, and scalable systems on AWS. It’s what I do. So, when a client needed a new WordPress site, I built them the “right” solution.
It was a text-book, best-practice architecture. Secure, redundant, and built to scale. It also cost around $300 a month.
And it was slow. Humiliatingly slow.
The developer deployed the site, and the Time to First Byte (TTFB) was agonizing. We threw a caching plugin at it (WP Super Cache), and it was still sluggish.
Frustrated, the client moved the exact same site to a “managed WordPress host (Kinsta)” as a test. It took the developer 15 minutes. The site was instantly, blazingly fast. And the plan cost $50.
I was baffled. And humbled. How did a “proper” $300 stack get so thoroughly beaten by a standard subscription plan?
This post is the autopsy of that $300 architecture and the blueprint for how to actually build a high-performance WordPress stack on AWS.
It’s a lesson in caching, instance types, and the massive, invisible cost of expert labor.
The “Perfect” $300 AWS Stack That Failed
First, let’s look at what I built. If you’re an AWS pro, this will look familiar.
- Compute: An Auto Scaling Group (ASG) with a minimum of two
t3a.mediumEC2 instances. This ensures high availability. - Database: An RDS instance, specifically a
db.t4g.small, in a separate private subnet. - Networking: An Application Load Balancer (ALB) to distribute traffic.
- Security: A NAT Gateway, allowing the private EC2 instances to fetch updates (like WordPress plugin downloads) without being exposed to the internet.
- Caching: The developer added the “WP Super Cache” plugin inside WordPress.

It was secure, it was redundant, it followed all the AWS Well-Architected guidelines. And it failed. Here’s why:
The Autopsy: Where It All Went Wrong
My architecture was solving for infrastructure resilience, not application performance.
For WordPress, those are two very different things.
1. The “Burstable” T-Series Trap
This was the single biggest flaw. The entire stack, from the t3a.medium web servers to the db.t4g.small database, was built on AWS’s "burstable" T-series instances.
Here’s the rub: T-series instances are cheap because they give you a low “baseline” CPU performance (e.g., 20–40%) and a finite number of “CPU credits” to “burst” above that baseline.
I assumed WordPress was a “low-traffic” workload. I was wrong.
WordPress is constantly busy. Even with no visitors, it’s running background cron jobs, getting pinged by search engine crawlers, and processing admin tasks. These sustained loads exhausted our CPU credits fast.
Once the credits are gone, the instances are “throttled” down to their low baseline performance. That was the source of the terrible slowness.
Worse, the $300/month bill was likely a penalty. By default, T-series instances are in “Unlimited Mode,” which means when you run out of credits, AWS just sells you more at a premium. I was paying a premium price for throttled hardware.
2. The Caching Misunderstanding (PHP vs. Server)
I thought “WP Super Cache” would solve it. But a PHP-based caching plugin is dramatically slower than a true server-level cache.
Why? Because every single request — even for a “cached” page — still has to load the Nginx/Apache web server, which then has to load the entire PHP interpreter, which then loads WordPress, which then loads the caching plugin, just to fetch a static HTML file from the disk.
The managed host, by contrast, uses Nginx fastcgi_cache. This intercepts the request at the webserver before PHP ever loads. It serves the cached file directly from memory/disk, which is orders of magnitude faster.
3. The “Best Practice” Performance Tax
Two of my “best practice” security decisions actively hurt performance:
- NAT Gateway: For security, my instances were in a private subnet. To get out to the internet (for plugin updates, etc.), they had to go through a NAT Gateway. This service costs a fixed ~$33/month plus a per-GB data processing fee. This was pure cost overhead that provided zero performance value.
- RDS Latency: Separating the database to RDS is great for security and management. But for WordPress, which is notoriously “chatty” and can make 100+ database queries on a single uncached page load, I introduced network latency on every single query. The managed host typically runs containerized solutions where the database proximity is highly optimized.
4. The Iceberg: Total Cost of Ownership (TCO)
This was the real “Aha!” moment.
I was comparing a $300 infrastructure bill to a $50 service bill.
The $50/month Kinsta plan wasn’t just for a server. It was for the server plus the 24/7/365 amortized salary of an entire team of expert WordPress sysadmins. Their full-time job is to tune Nginx, optimize databases, manage server-level caching, and secure the platform.
My $300 AWS stack had $0 budgeted for that expert, application-specific labor. I had handed the client a box of high-end car parts, but the $50 host was selling them a fully-tuned “Formula 1” car with a pit crew.
The Right WordPress Deployment for the Right Situation
This experience didn’t mean “AWS is bad.” It meant I used the wrong tool for the job.
Here’s my new playbook.
Profile 1: The 95% of Users (Businesses, Blogs, E-commerce)
Recommendation: A Premium Managed WordPress Host (e.g., Kinsta, WP Engine).
Why: It’s faster, cheaper, and safer for almost everyone. You aren’t just buying a server; you’re buying a fully managed platform. They provide superior, sustained-performance compute (like Google’s C2/C3D VMs), premium networks, and a pre-tuned stack (Nginx fastcgi_cache, Edge Caching, optimized DBs) out of the box. You are outsourcing the expert labor to someone who does it better and cheaper than you ever could.
Profile 2: The Enterprise Integrator or High-Compliance Client
Recommendation: The “DIY” AWS Stack (but built correctly).
Why: Use this only if you have a non-negotiable reason.
- Deep Integration: You need WordPress to live in a private VPC and talk to other AWS services like Lambda, S3, or internal APIs that aren’t public.
- Extreme Compliance: You are in healthcare and need a HIPAA-compliant host that will sign a Business Associate Agreement (BAA), which many managed hosts will not do on standard plans.
But here is the critical part: You must sell this with a mandatory, high-value Managed Services contract. You are now the expert sysadmin, and that labor must be budgeted.
A Note on AWS Lightsail: The Worst of Both Worlds
You might think AWS Lightsail is the happy medium. It’s not. Lightsail is just a “leaky abstraction” over EC2. It still uses burstable T-series instances, so you’ll have the exact same CPU credit/throttling problem. And you are still 100% responsible for all the sysadmin work (security, patches, tuning). It combines the performance limitations of a cheap VPS with the management burden of IaaS.
The Blueprint: A Truly High-Performance WordPress AWS Stack
So, if you must build on AWS for that “Enterprise” client, here is the blueprint that actually works.
1. The Caching Hierarchy (Nginx + Redis)
This is the most important concept. It’s not “Nginx or Redis.” You need both.
- Layer 1: Server-Level Page Cache (Nginx
fastcgi_cache) This is your frontline. It stores the fully-rendered HTML of your pages in memory or on disk. This cache serves 90% of your (anonymous) traffic without ever touching PHP or WordPress, making it incredibly fast. Use theNginx Helperplugin to automatically purge this cache when you update a post. - Layer 2: Object Cache (AWS ElastiCache for Redis) This is for everything that can’t be page-cached:
wp-admin, logged-in users, and e-commerce carts. WordPress is "chatty," constantly asking the database for the same data (like site options). An object cache sits between PHP and your RDS database, storing the results of those queries in high-speed RAM.
2. The Compute Tier (EC2): No More T-Series
- Instance Type: Use a C-Series (Compute Optimized) family, like the
c7g.large(Graviton/ARM). - Why: The web server’s job is running Nginx and PHP. This is a CPU-bound workload. C-series instances give you high, sustained CPU performance. Never use T-series for a production workload you expect to be fast.
3. The Database Tier (RDS): Feed It RAM
- Instance Type: Use an R-Series (Memory Optimized) family, like the
db.r7g.large. - Why: MySQL performance relies on RAM (specifically the
innodb_buffer_pool). An R-series instance gives you a massive amount of RAM, allowing the entire database to live in memory, which all but eliminates disk I/O latency.
4. The Auto-Scaling Problem: Stateless WordPress
- The Challenge: WordPress stores user uploads locally. In an Auto Scaling Group, instances are destroyed and recreated, meaning you lose those files.
- The Solution: Use a plugin like WP Offload Media. This plugin intercepts all media uploads and saves them directly to an S3 bucket. Your EC2 instances are now truly “stateless” (disposable), and your uploads are stored securely and cheaply on S3. Do not try to mount EFS to
/var/www/html; the latency will kill your site speed unless you are an expert at tuning PHP OPcache.
5. The CDN (CloudFront): Caching HTML
Set up CloudFront with two behaviors:
- Static Assets: Pull images/CSS directly from your S3 bucket.
- Dynamic HTML: Configure CloudFront to cache the HTML response from your Load Balancer, but bypass the cache if the user has a
wordpress_logged_incookie. This gives you global "Edge Caching" for anonymous visitors.
6. The Engine Room (PHP-FPM Tuning)
- Setting: In your PHP-FPM pool config, set
pm = static. - Why: The default,
pm = dynamic, tries to save RAM by killing and spawning "worker" processes as needed. This adds latency.pm = staticforces a fixed number of workers (e.g., 30) to be always on and waiting. It provides the absolute lowest latency because there is zero process-management overhead.

The Final Lesson
The $300 vs. $50 debate was never about the price of an instance. It was about the invisible, non-negotiable cost of expert, application-specific labor.
Managed hosts productize this labor. Building on IaaS like AWS means you are now that labor. My initial $300 stack failed because it was just a box of parts with no expert mechanic.
You can absolutely build a world-class WordPress site on AWS, but it requires a different architecture, a different budget, and a deep understanding of what you’re actually optimizing for. Otherwise, just save yourself the headache and pay the $50. Your client (and your ego) will thank you.
메타데이터
- post_id
- 9bc951a26f44
- slug
- the-250-wordpress-mistake-a-postmortem-on-a-slow-aws-architecture-9bc951a26f44
- url
- https://aws.plainenglish.io/the-250-wordpress-mistake-a-postmortem-on-a-slow-aws-architecture-9bc951a26f44
- canonical_url
- https://aws.plainenglish.io/the-250-wordpress-mistake-a-postmortem-on-a-slow-aws-architecture-9bc951a26f44
- author_url
- https://medium.com/@devopsulting.com
- status
- ok
- fetched_at
- 2026-07-15 06:19:17