THE CHALLENGE
The challenge
An automotive industry client approached Bytesol with a straightforward concern: their AWS infrastructure was costing more than they believed it should.
The application itself was anything but trivial. It was a business-critical platform on which the organisation's day-to-day operations depended, built using .NET, Angular, SQL Server and IIS, and handling approximately 3,000 requests per minute.
The AWS environment had been established more than a decade earlier and had evolved over time under previous developers. While the application continued to operate reliably, the infrastructure had never undergone a structured cost-optimisation exercise.
The client's goal was therefore simple:
Understand where AWS spend was going and determine how much could be reduced without negatively affecting application performance or reliability.
THE METHOD
Our approach: understand before optimising
Cloud cost optimisation can easily become an exercise in buying Reserved Instances, Savings Plans or simply moving workloads onto smaller servers.
We deliberately took a different approach.
Our methodology was:
Before making any infrastructure changes or long-term financial commitments, we first needed to understand how the application actually behaved.
We reviewed AWS Cost Explorer, billing data and six months of CloudWatch utilisation metrics across EC2 and RDS.
Using six months of historical data was particularly important because it allowed us to account for potential seasonal usage rather than making infrastructure decisions based on a few days of activity.
THE SIGNAL THAT LIED
Finding an unusual 5am CPU spike
One of the first areas investigated was the production EC2 server.
Its average CPU utilisation was approximately 25%, suggesting that there could be an opportunity to reduce the instance size.
There was, however, one concerning pattern.
Every morning at approximately 5am, CPU utilisation would suddenly spike to 100%.
At first glance, that spike could easily have been interpreted as evidence that the server required its existing compute capacity.
But the CloudWatch metrics did not explain why the spike occurred.
Not customer demand. A legacy scheduled IIS restart.
Rather than treating the metric in isolation, we logged into the server and investigated the IIS configuration directly.
That investigation revealed that IIS had been configured to restart every morning at 5am.
The configuration appeared to date back to an earlier version of the application where session handling could cause memory utilisation to increase over time. Restarting IIS had effectively been used as a way to release that memory.
The application architecture had since changed, but the scheduled restart had remained.
The infrastructure was therefore exhibiting a useful lesson in cloud optimisation:
A utilisation graph tells you what happened. It does not necessarily tell you why it happened.
The daily CPU spike was not caused by customer demand or application workload. It was being generated by a legacy operational configuration.
VALIDATE THE EVIDENCE
Measuring memory before making a decision
CPU was only part of the picture.
Memory utilisation is not available as a standard EC2 CloudWatch metric, so we configured the CloudWatch Agent in accordance with AWS guidance to collect memory data.
The results reinforced the earlier findings.
Memory utilisation consistently remained below approximately 25%.
With both CPU and memory utilisation understood, we had much stronger evidence that the production instance was significantly oversized.
CONTROLLED RIGHT-SIZING
Gradually reducing EC2 capacity
Both the production and development environments were running on t2.xlarge EC2 instances.
Rather than immediately changing the production server to a significantly smaller instance, we took a controlled approach.
The smaller configuration was first tested in the development environment.
For production, we used the infrastructure redesign itself to progressively test smaller instance sizes.
An Application Load Balancer and Auto Scaling Group were introduced, initially operating with a combination of larger EC2 instance sizes. Over several days, instance sizes were gradually reduced while monitoring CloudWatch metrics and gathering feedback from the client about real-world application performance.
The production workload ultimately moved from:
The development server was similarly reduced from:
This represented a substantial reduction in compute capacity and cost, but importantly, it was based on observed application behaviour rather than assumptions.
Application performance remained unaffected.
BETTER, NOT JUST CHEAPER
Improving resilience while reducing cost
The optimisation exercise was not limited to making the existing infrastructure cheaper.
The original production architecture depended heavily on a single EC2 instance.
We redesigned the production environment around:
- ✓ An Application Load Balancer
- ✓ An Auto Scaling Group
- ✓ A launch template using the latest approved production AMI
- ✓ Deployment across two Availability Zones
- ✓ CPU-based Auto Scaling
The Auto Scaling configuration provided the ability to scale production capacity between one and four instances depending on demand and scheduling requirements.
During normal business operation, the environment could run the required production capacity while distributing workloads through the load balancer.
This meant the client was able to move away from depending on a single large production server while simultaneously reducing the size of the individual EC2 instances.
The result was an architecture that was both more cost-efficient and more resilient.
CAPACITY THAT FOLLOWS THE BUSINESS
Matching infrastructure capacity to business hours
The next opportunity was to question whether every environment needed to operate at full capacity 24 hours a day.
The development environment previously operated continuously — 168 hours every week — despite development and QA activity occurring primarily during normal working hours.
We configured AWS Instance Scheduler so that the development environment operated:
Monday to Friday, 8am to 6pm
Outside those hours, the development instance could be shut down.
Production capacity was also adjusted according to business requirements, allowing the system to reduce its running instance count after hours while remaining available.
This enabled the client to stop paying for compute capacity that was providing little or no business value.
REMOVE STRUCTURAL WASTE
Cleaning up forgotten infrastructure
Long-lived cloud environments frequently accumulate resources that were once necessary but are no longer actively used.
During the audit, we identified three EC2 instances belonging to an old Elastic Beanstalk environment.
The related project had been put on hold more than a year earlier, but the infrastructure supporting it had continued running.
Rather than simply deleting the environment, we first backed up the application and documented how the Elastic Beanstalk deployment could be recreated if the client needed it again.
The environment was then safely removed.
We also identified an unused RDS database and reviewed other resources including EBS volumes, snapshots and Elastic IPs.
Not every possible optimisation was implemented.
For some low-cost resources, the engineering effort and operational risk required to fully analyse and remove them outweighed the potential saving.
That decision was intentional.
Good cloud optimisation is not about removing every dollar of AWS spend. It is about focusing engineering effort where it creates meaningful business value.
OPTIMISE FIRST
Optimise first, commit second
Once the infrastructure had been rightsized and unnecessary capacity removed, we turned our attention to AWS pricing commitments.
This sequencing was deliberate.
Purchasing Reserved Instances or Savings Plans too early can lock an organisation into paying for infrastructure that it never needed in the first place.
By optimising compute usage first, we could establish a much more realistic long-term baseline.
Only then did we purchase a three-year, all-upfront Compute Savings Plan.
This provided additional savings on top of the infrastructure reductions already achieved.
The principle was simple:
Don't reserve inefficient infrastructure.
DATABASE SAVINGS
Reducing RDS cost by approximately 60%
The database layer provided another significant opportunity.
Rather than changing the database architecture or instance class unnecessarily, analysis showed that the primary opportunity was pricing optimisation.
A three-year, all-upfront RDS Reserved Instance was purchased for the existing database workload.
This reduced the relevant RDS cost by approximately 60%.
Because the workload characteristics were understood before making the commitment, the client could take advantage of the lower pricing with greater confidence that the reserved capacity reflected their genuine long-term requirement.
THE RESULT
The result: more than 50% reduction in AWS spend
The optimisation was conducted progressively over approximately one week, including around three days of testing and ongoing monitoring.
More than 40 hours of engineering effort went into analysing, testing, implementing and validating the changes.
The outcome was substantial:
Overall monthly AWS infrastructure spend was reduced by approximately 50%.
Most of the saving came from the EC2 architecture and rightsizing changes, with additional reductions achieved through the Compute Savings Plan and RDS Reserved Instance.
Just as importantly:
- ✓ Application performance was unaffected
- ✓ The production migration resulted in no downtime
- ✓ Production resilience was improved through load balancing and multi-AZ deployment
- ✓ Development infrastructure no longer ran unnecessarily outside business hours
- ✓ Long-abandoned infrastructure was removed
- ✓ Long-term AWS commitments were based on optimised workloads rather than historical overprovisioning
During the production migration, the existing production instance was also retained as a fallback until the new load-balanced and Auto Scaling architecture had been validated.
This allowed the infrastructure transformation to be completed without disrupting the client's business-critical application.
BUSINESS IMPACT
From infrastructure savings to product investment
The value of the project extended beyond reducing an AWS invoice.
The savings freed up budget that the client could redirect towards further application development and performance improvements.
Bytesol also continued working with the client on ongoing AWS infrastructure management and optimisation.
The client's feedback summarised the impact:
“We are amazed by the savings that Bytesol helped us to achieve. We simply could not have done all of this on our own. We really appreciate the deep insights and bias for action by Bytesol.”
THE BROADER LESSON
The broader lesson
The biggest mistake businesses can make when trying to optimise cloud costs is treating infrastructure resources as isolated line items on an AWS bill.
An EC2 instance cannot be properly optimised without understanding the application running on it.
A CPU spike cannot be interpreted properly without understanding what caused it.
A server cannot be rightsized safely without understanding memory, traffic patterns and business criticality.
And a three-year AWS commitment should not be purchased until the organisation understands what capacity it actually needs.
For SMEs reviewing AWS expenditure, a useful starting framework is:
- 01Understand application behaviour
— traffic patterns, workloads, dependencies and business usage.
- 02Establish business criticality
— determine which workloads require higher levels of resilience and where greater optimisation flexibility exists.
- 03Analyse historical utilisation
— review sufficient CloudWatch history to account for normal and seasonal workload patterns.
- 04Identify structural waste
— oversized resources, idle environments, abandoned projects and unnecessary 24/7 workloads.
- 05Optimise before committing
— rightsize and validate infrastructure before purchasing Savings Plans or Reserved Instances.
Cloud optimisation should not simply produce a cheaper AWS bill.
Done properly, it should produce an infrastructure environment that is better aligned with how the business actually operates.Discuss your AWS costs