The context
The client had a production application with a growing user base and an architecture that had evolved faster than the operating model around it.
The codebase was functional, but performance became inconsistent as traffic increased. Pages and APIs slowed under load, infrastructure had limited headroom, and the team had little visibility into which layer was becoming the bottleneck.
The problem
The first instinct was to optimise application code. Our assessment showed that the larger constraint was architectural.
Requests were reaching the application with too little caching, compute capacity could not respond cleanly to changing load, and database pressure increased as traffic rose. Rewriting the product would have been expensive and would not have addressed the underlying production model.
Scale the architecture before rewriting working product code.
Move repeatable load away from the application and database.
Make capacity and failure visible before users feel it.
Reworking the request path
We redesigned how traffic moved through the AWS environment so each layer handled the work it was best suited for.
Amazon CloudFront
CloudFront was introduced and tuned at the edge to cache suitable static and repeatable content closer to users, reducing avoidable round trips into the application stack.
Application Load Balancer
An Application Load Balancer distributed incoming traffic across application capacity and created a cleaner boundary for health checks and horizontal scaling.
Amazon ECS on AWS Fargate
Application services were structured around ECS tasks on AWS Fargate so compute could scale without the team managing individual servers. Service capacity could respond to demand while preserving consistent deployment units.
Amazon RDS Multi-AZ
The database layer was moved toward a production configuration using Amazon RDS Multi-AZ, giving the application a managed relational database foundation with stronger availability characteristics and clearer operational controls.
Reducing pressure on the database
Not every request needed to reach the primary database. We introduced Amazon ElastiCache for Redis for appropriate hot reads and transient application state, reducing repeated database work on paths that were sensitive to latency.
This changed the performance profile without forcing a risky rewrite of core business logic. The application remained familiar to the product team while the infrastructure underneath it handled load more intelligently.
Scaling around demand
ECS service scaling policies were configured around application demand so capacity could increase when the workload required it and contract when it did not.
AWS Auto Scaling, Application Load Balancer health checks and containerised deployment patterns gave the environment a clearer response to traffic changes than the previous static capacity model.
Making production observable
Scaling without observability simply makes failure more expensive. We used Amazon CloudWatch metrics, logs and alarms to expose the behaviour of the infrastructure and application under load.
The team gained visibility into service health, resource utilisation, request behaviour and operational events so performance discussions could be based on evidence rather than user reports alone.
Before
- Static infrastructure capacity
- Application and database absorbing avoidable load
- Limited production visibility
- Performance degraded as traffic increased
After
- Elastic application capacity
- CloudFront edge caching
- Redis-backed hot data paths
- CloudWatch-driven operational visibility
The outcome
The application achieved a stronger performance profile by changing the architecture rather than rebuilding the product.
Traffic was distributed more effectively, repeatable load was absorbed earlier in the request path, compute could scale with demand, and the database was protected from work that did not need to reach it. The client kept the core application while gaining an AWS architecture better suited to production growth.
What changed
Higher performance under load
The request path was restructured so edge caching, horizontal compute and Redis could absorb work before it became application or database pressure.
Architecture that can scale
ECS on Fargate and scaling policies replaced a more static capacity model with infrastructure able to respond to changing demand.
Production became measurable
CloudWatch metrics, logs and alarms gave the team clearer visibility into service health and performance behaviour.
