How a B2B SaaS Team Migrated a Rails Monolith to EKS With Zero Downtime

A 120-engineer SaaS company moved a decade-old Rails app from hand-managed EC2 to Amazon EKS using a strangler-fig approach, cutting deploy time from 47 minutes to 4 and eliminating weekend outages.

Containers & K8s · intermediate · 12 min read · 2450 words · By Sandip Das · Published

Composite scenario: built from common industry patterns; the figures are illustrative.

What this covers

  1. The Situation
  2. The Problem
  3. Constraints
  4. Options Considered
  5. The Solution
  6. Implementation
  7. Results
  8. What Went Wrong Along the Way
  9. Lessons Learned
  10. Apply It Yourself

Key numbers

MetricBeforeAfter
End-to-end deploy time47 minutes4 minutes
Monthly compute spend$28,400$19,100
Compute-related incidents (6-month window)9 incidents0 in first 90 days
P99 response time (baseline)340 ms290 ms
Scale-out time (plus 8 nodes equivalent)~12 minutes (ASG)90 seconds (HPA)

Key components

  • Amazon EKS Managed Node Groups — Replaced the hand-managed EC2 fleet with self-healing, automatically patched compute that the Cluster Autoscaler can grow or shrink in under two minutes.
  • Weighted ALB Target Groups — Enabled incremental traffic migration from EC2 to EKS in percentage steps, providing a one-click rollback path at every stage of the cutover.
  • Argo CD (GitOps) — Made every deployment a Git commit, providing an auditable history of every config change and eliminating configuration drift between environments.
  • Horizontal Pod Autoscaler — Replaced the static EC2 fleet with demand-driven scaling, reducing idle compute cost by matching pod count to actual traffic load.
  • PgBouncer (connection pooling) — Prevented RDS max_connections exhaustion by multiplexing hundreds of pod-level database connections into a fixed pool of 80 server-side connections.
  • Fluent Bit DaemonSet — Collected container stdout logs from every node and forwarded them to Datadog Logs without requiring any changes to the Rails application's logging configuration.

The Situation

This is a composite scenario assembled from patterns observed across multiple production migrations; all figures are illustrative and chosen for internal consistency, not to represent any single organisation.

The subject is a 120-engineer B2B SaaS company that sells workflow-automation software to mid-market finance teams. The product is a single Rails 6.1 monolith that has been in production since 2014. At the time of the migration it handled roughly 18 million requests per day, backed by a 1.4 TB RDS PostgreSQL 14 instance and a six-node ElastiCache Redis cluster. The application ran on a fleet of 22 c5.2xlarge EC2 instances managed with a combination of Capistrano, Ansible, and hand-edited launch templates. Sidekiq workers ran on a separate fleet of eight c5.xlarge instances. There was no container runtime anywhere in the stack.

The engineering organisation had three platform engineers, twelve backend engineers who touched the Rails codebase daily, and a director of engineering who had just come from a company running Kubernetes in production. The on-call rotation covered six engineers.

---

The rest of this case study — the trade-offs, the scaling numbers and the build prompt — is available to LearnXops members. Create an account or see membership.

Topics: kubernetes, rails, aws, containers, migration, zero-downtime

Related case studies

Browse all case studies