Hey everyone! I'm currently overseeing an AWS infrastructure setup that feels a bit overwhelming, and I'm looking for some solid advice on how to improve it for better cost efficiency and performance. Here's a snapshot of my current architecture:
1. I've got a single EC2 instance running an m7a.12xlarge configuration, which includes 48 vCPUs and 192 GB of RAM.
2. My backend is powered by a Flask API managed through Gunicorn, and it's reverse-proxied by Apache.
3. The MySQL database is also running locally on the same EC2 instance.
4. I've got over 10 dynamic client portals (using HTML/PHP) that are hosted under `/var/www/html` with Apache virtual hosts, all of which communicate with the same backend API.
5. There are several cron jobs doing tasks like backups and notifications.
Unfortunately, I'm facing server overload issues quite frequently due to Gunicorn's memory usage. I've tried reducing the number of Gunicorn workers, but that slows down the API. On the other hand, increasing the workers (following the CPU * 2 rule) does improve performance but causes huge memory spikes. We recently upgraded to the large m7a.12xlarge EC2 instance costing around ₹3L/month or $2.8/hour, but the overload is still happening.
The real crux of the matter is that everything is tightly coupled, so any spike in memory or CPU usage from Gunicorn or MySQL affects all components — the API, the portals, and the cron jobs.
I'm keen to make this setup more scalable and cost-effective, and here are a few options I'm considering:
1. Moving the MySQL database to RDS.
2. Splitting the portals and API into separate EC2 instances.
3. Utilizing API Gateway with Lambda and Layers.
4. Exploring Amazon Fargate.
I would greatly appreciate any guidance on the best approach for someone new to all this, including any common pitfalls I should watch out for while transitioning. Thanks a lot for your help!
3 Answers
Definitely consider migrating your MySQL to RDS. Also, transition your Python and Gunicorn setup to Docker and run that on ECS with Fargate. For your other scheduled tasks, look into using Lambdas paired with EventBridge Scheduler or ECS Scheduled tasks if they're more CPU-intensive. You could also move any static HTML front-end content to S3 and then use CloudFront for distribution. Just keep in mind that PHP might give you some trouble, but you could Dockerize that as well. Overall, understanding your application's data flow is essential; focus on decoupling wherever possible to set up for horizontal scaling.
Your initial ideas are on point! As a starting point, you might also look into switching to a different EC2 instance type. For a similar price, you could try an r6a instance, which offers 48 vCPUs and 384 GB of RAM. You'll want to think about the CPU and memory needs for RDS compared to your EC2 instance, and optimize your database calls and consider using read replicas where necessary. APIs are definitely better handled via API Gateway and Lambda; you might want to check how your portal calls function with that setup.
You’ve got a great list going. The first step should definitely be moving to RDS for your MySQL. For the portals and APIs, I suggest using Docker containers on ECS or EKS with a Service Mesh for better management. Don’t forget to set up your front-end with either ALB or consider using Kong API. As for cron jobs and automation tasks, EventBridge with Lambda is a smart choice. And for backups, utilize AWS Backup, and for notifications, you can leverage SNS or SES.
Absolutely! Just keep in mind that using Lambda could slow down if your codebase isn’t optimized. Maybe set up a workflow to kick off jobs on EC2, run through an SSM document, and then shut them down afterwards. Separation really helps in optimizing resource use!
Agreed! If you have a good grasp of your system, it’ll make the decoupling process easier. Start by breaking things down into smaller parts, like moving your front-end to ECS if that's feasible. If not, consider running it on a separate EC2 instance behind an Application Load Balancer (ALB) along with your API with API Gateway. Setting up the database in RDS sounds like a solid plan too.