We migrated our stack from Heroku to AWS and cut 60% of operation cost

Last Updated
March 22, 2021
Silvercast
Author
Silvercast
Silvercast | We migrated our stack from Heroku to AWS and cut 60% of operation cost

It took me two years to write this post, for reasons I will spare you — the bottom line is I have no one to blame but myself, so let me get to the actual writing. 😇 Back when Pretty.Tips was in its early phase, our technology stack was refreshingly simple. Everything ran on Heroku: database, frontend, backend, and back-office. Before each campaign, we estimated incoming traffic and provisioned instances in advance — a bit of manual work, but we were happy with Heroku's services. Our average technical operation cost ran around $800–$900 per month. When Pretty.Tips began scaling its business, we realized that the cost of growing alongside it would be unsustainable for an early-stage startup. Fortunately, Pretty.Tips received AWS credits through its accelerator program, giving us the opportunity to do something significant. The migration experience was equal parts rewarding and painful.


It was rewarding because the entire stack was migrated without any downtime, far more smoothly than we had anticipated. We genuinely appreciated the stability and excellent customer support from AWS, and in the end, we cut our operation cost by 60% — one of the biggest wins we had. It was painful because the journey felt like driving down an endlessly bumpy road. The tech team truly struggled to get there: sleepless nights, unexpected gotchas, frustrating bugs, and countless back-and-forth deployments. Here are the key things we did along the way that brought us to a good place. I hope some of these save you significant time and effort.


We started by building a staging backend: at the point we decided to migrate, we already had 80,000+ live customers, so touching production required extreme care. The initial staging environment contained only the backend, running on a single Elastic Beanstalk (ELB) application. Once we were satisfied with the backend, it was natural to add ELB applications for the frontend and back-office as well. One might ask why ELB for the frontend — the answer is SEO. It plays a critical role for an e-commerce platform, which requires server-side rendering, and that in turn requires ELB on the frontend.


Spending significant time on CloudFormation was not a good idea. CloudFormation offers great flexibility, but my advice is to avoid it if your needs are as straightforward as staging and production environments with simple web servers and backend APIs. Setting that up through the AWS console might take an hour, compared to days — or weeks — spent wrangling CloudFormation templates and auto-deployment quirks.


Migrate the production database last: once we were confident in the AWS setup, we made the DNS switch to point to the ELB backend, as shown in the diagram below. The ELB still pointed to the database running on Heroku so that, in the event of a disruption, we could revert quickly. After a few days of observation, we migrated the database from Heroku to AWS RDS, completing the migration. The celebration 🎉🚀 came a week later when the entire Heroku environment was finally decommissioned.


AWS migration

Invest in serverless: we did not stop once everything was on AWS. A number of EC2 instances sat idle most of the time or ran at very low utilization, which led us to explore serverless architecture. In essence, serverless assumes you break your backend into small, short-lived, stateless API invocations — there is no dedicated host, only dynamically allocated compute resources. We had to wrestle with invocation timeouts and unclear logs early on, and lost a few days trying to run Lambda functions inside a VPC, which we ultimately decided to bypass. Amazon later acknowledged and patched that issue. After migrating our backend and back-office to serverless functions, our operation cost fell from $900 to under $350 per month. The engineering team no longer had to worry about the slow, reactive scaling of ELB instances, and the business team gained budget to reinvest in operations. A meaningful optimization by any measure.

One key lesson from this phase: serverless is not a silver bullet. Cold start latency can affect user-facing APIs depending on traffic patterns, and distributed tracing across Lambda functions requires deliberate investment. For background jobs and low-frequency endpoints it is an excellent fit; for latency-sensitive, high-throughput paths it warrants careful evaluation.



Fast-forward to today, and controlling your technology stack has never been easier. Amazon, Google, and Microsoft all offer mature developer experiences that can support an entire business solution with near-instant feedback loops. I would still reach for Heroku for quick proof-of-concept work — it remains the most frictionless environment I know. For medium to large projects, however, I strongly recommend planning and managing your technology stack with care. It is one of the highest-leverage investments you can make, and for small startups it can become a genuine do-or-die decision. Happy shipping, everyone.

All content © Silvercast