Scaling a Monolith in the Cloud: The Fastest Path to Stability (Without Splitting Everything)
💡 “If it runs on a server, it can run in the cloud. If it can run in the cloud, it can scale. You don’t need to split everything to move forward.”
And it definitely doesn’t need to become a 6-month architecture project before you ship anything.
“We need to be stable, we need to move faster, and we can’t afford to break stuff.”
A tactical guide to scaling monoliths in the cloud — especially when migrating from non-hyperscaler setups (like Hetzner, IONOS, or Linode) to AWS or similar.
Running on a single VM (sometimes two) with local volume mounts
Deployments via manual SSH, or bash scripts pulling main and restarting
Tests might exist — but no health checks, no structured alerting
docker-compose or basic Docker usage, no orchestration
No CI/CD pipelines, or CI without delivery
One shared database, often MySQL or PostgreSQL, no replicas
Documentation? Maybe in someone’s head
Logs? Possibly local, rarely centralized
Let’s be clear: migration is not the goal.
Start by stabilizing the monolith, making it observable, and enabling it to scale. Split later — based on signals, not assumptions.
If it’s not Dockerized yet, that’s priority zero.
Get the build reproducible. Build once, run anywhere.
Next: make it visible.
- 🔍 Add centralized logging
- 📊 Pipe metrics and traces into Grafana, Sentry, or DataDog
- ✅ Expose liveness/readiness checks
Even if the app is a black box, at least you’ll know when it breaks — and where.
Many teams test locally, deploy manually, and hope for the best. That stops here.
We create:
A realistic staging environment (on EKS, ECS, or EC2-based infra)
CI/CD pipelines with test -> build -> deploy steps
Environment isolation with env vars, secrets management, etc.
This becomes your team’s safe zone to test changes without fearing the prod dragon.
Before you “microservice all the things,” here’s how you get scale now:
A. Horizontal autoscaling
Spin up multiple instances behind a load balancer. Use Kubernetes HPA, or EC2 Auto Scaling. Add instance-level health checks.
B. Split at the route level
Run the same app in multiple instances, each handling specific routes or use cases. This reduces blast radius without changing code structure.
C. Move static and large objects to S3
Offload all static assets, logs, or generated files. Use S3 + CloudFront to serve assets quickly and reduce load on the app.
D. Use Redis or Memcached for caching
If you can’t split it, cache it.
Add smart caching to high-traffic endpoints or expensive DB queries.
E. Queue the heavy stuff
Anything CPU-heavy or IO-blocking?
Add a job queue. Even in the monolith, you can route background tasks to workers — no need to split yet.
F. Add DB read replicas
Separate reads from writes.
This one simple change can dramatically reduce write latency and help scale reads independently.
Tech scale without team scale is short-lived. You have to unblock developers to keep velocity high.
Here’s how we do that:
Multiple environments: dev, staging, preview per branch
Slack + dashboards: surfacing logs and metrics where devs already live
Simple Git-based configs: YAMLs to control app behavior, deployments, resources
Incident process: alerts, ownership, and fast response paths
Boilerplates for new services: for when they’re ready to split the monolith
Crucially, we don’t say “you have to split this now.” We give devs space to grow the architecture over time, based on experience and product need.
Don’t refactor a system you can’t even observe or ship safely. That’s how outages and regressions happen.
Bad microservices are worse than a decent monolith. Splitting by “team” or “feature” without understanding business context leads to cross-service messes.
Deploying directly to prod without a staging mirror? That’s asking for rollback drama.
It doesn’t. Kubernetes helps with scaling, isolation, and ops — but it doesn’t fix a poorly-structured app. Don’t over-engineer just to feel “cloud-native.”
🧠 Split when you need to, not because you “should”
⚖ A scalable monolith beats unstable microservices
🧰 Invest in infra devs understand and can extend
🔭 Make things observable before you scale them
⛑ Improve deploy speed and incident visibility early
You don’t need to know how to run Grafana, Prometheus, or EKS. You just need a partner who’s done it dozens of times — and can hand you a tested, working setup.
Start with visibility.
Add automation.
Scale the existing app.
Empower your devs.
Then — when the time is right — split it on your terms, not because someone said “microservices are better.”
We’ve helped teams go from SSH deploys to autoscaling prod-ready platforms in weeks — and your setup might be next.