rails → aws · 2026 migration playbook

Migrate a Rails app to AWS: the architecture, Sidekiq, and the database cutover.

A Rails monolith on AWS usually means Puma and Sidekiq as separate ECS services on Fargate behind a load balancer, PostgreSQL on RDS or Aurora, ElastiCache for Sidekiq, Action Cable and the cache, Active Storage on S3, and assets through CloudFront. ActiveRecord and your jobs do not change. The work is packaging, scheduled jobs, and a careful Postgres cutover.

web and workers
Puma + Sidekiq on Fargate
database
RDS or Aurora Postgres
code changes
config, not logic
TL;DR
  • Each Procfile process becomes a service: Puma on ECS with Fargate behind an Application Load Balancer, Sidekiq as a second service. PostgreSQL moves to RDS or Aurora. ElastiCache (Redis OSS or Valkey) backs Sidekiq, Action Cable and the Rails cache. Active Storage uses S3; precompiled assets are served through CloudFront.
  • The Rails-specific work: the generated multi-stage Dockerfile, credentials and config moved to Secrets Manager and Parameter Store (one RAILS_MASTER_KEY or SECRET_KEY_BASE for every task), scheduled jobs recreated (sidekiq-cron, or EventBridge Scheduler for whenever or Heroku Scheduler), and RDS Proxy for connection pooling.
  • Coming from Heroku, check your Postgres plan first: classic Heroku Postgres plans do not allow streaming replication to AWS, so the cutover is usually a dump and restore in a planned window. A vetted AWS partner can run it. MAP is built for migrations with meaningful ongoing AWS spend; when the migration qualifies, your matched partner files it: typically $50K to $150K for startups. Depends on the workload; AWS approves.
the trigger

IWhy move a Rails app to AWS

Most Rails apps arrive at AWS from Heroku. The move is triggered by cost, by platform limits, or by requirements Heroku does not meet.

Cost as you grow. A Rails monolith is rarely one dyno: web dynos, Sidekiq dynos, a scheduler process, managed Postgres and Redis, log and APM add-ons. Buying the underlying services on AWS and right-sizing them can cost less at scale, but it is not automatic. Price both sides with your real usage; the Heroku vs AWS page has the list prices and a break-even formula.

Platform limits. Heroku Postgres caps connections by plan (200 on Standard-0 and Premium-0, 500 on larger plans), and Rails opens a pool per Puma process and per Sidekiq process, so a busy fleet hits the cap. Heroku's 30-second router timeout ends slow requests. On AWS you size connections and timeouts yourself.

Requirements. VPC isolation, IAM, compliance controls and integration with the rest of an AWS estate.

where things land

IIThe target architecture: a Rails monolith on AWS

Data, cache and storage map almost one-to-one. The compute layout is the main decision.

Compute. Amazon ECS on Fargate: Puma as one service behind the load balancer (scaling on requests or CPU), Sidekiq as another (scaling on queue depth), both from the same image. For a small, mostly-web app, ECS Express Mode creates the service, load balancer and scaling from one image. (App Runner closed to new customers on April 30, 2026.)

Database. RDS for PostgreSQL (like-for-like) or Aurora PostgreSQL (storage that grows on its own, faster failover, up to 15 readers). Many teams land on RDS first and evaluate Aurora once stable. Put Amazon RDS Proxy in front to pool connections across Puma and Sidekiq.

Redis, files and assets. ElastiCache covers Sidekiq queues, Action Cable pub/sub (config/cable.yml) and :redis_cache_store with a connection-string change. Active Storage uses the :amazon service on S3. rails assets:precompile runs at build time and CloudFront serves the fingerprinted files.

the hands-on part

IIIDockerizing Rails, and credentials into AWS

Modern Rails (7.1 and later) generates a production Dockerfile, which is a good starting point.

The generated multi-stage build installs gems, runs rails assets:precompile (with SECRET_KEY_BASE_DUMMY=1 so it does not need real secrets), and copies only what runtime needs into a slim image. Each Procfile process becomes a service with a different command from the same image.

Move config vars and secrets out of the platform: real secrets (RAILS_MASTER_KEY or SECRET_KEY_BASE, DATABASE_URL credentials, API keys) into AWS Secrets Manager, plain config into SSM Parameter Store. ECS injects both as environment variables. Run rails db:migrate as a one-off task at deploy time, not on container boot.

background work

IVSidekiq, Action Cable and scheduled jobs

Background work is the classic "we forgot one" area after a migration.

Sidekiq runs as its own ECS service against ElastiCache, scaled on queue depth and sized for memory-hungry jobs without overpaying the web tier. Solid Queue apps run the same way with the database as the backend.

Action Cable needs the Redis pub/sub backend and a load balancer that allows WebSocket upgrades with a generous idle timeout.

Scheduled jobs. sidekiq-cron rides along on the Sidekiq service. The whenever gem (a crontab) and Heroku Scheduler do not exist on Fargate: recreate each schedule as an EventBridge Scheduler rule that runs a one-off ECS task.

the risky part

VThe Postgres cutover: check your source first

Containers, the landing zone, Sidekiq and assets can be built and tested without touching production. The Postgres cutover is the one moment that touches live data.

From classic Heroku Postgres (Essential, Standard, Premium): Heroku does not grant the replication role, so AWS DMS change data capture and logical replication to RDS are not available. Plan a write freeze and a pg_dump into pg_restore, and time a test restore to size the window. On Heroku Postgres Advanced, managed logical replication to an external database makes a short cutover possible. The Heroku Postgres to RDS page has the full runbook.

From a self-managed or other cloud Postgres: AWS DMS can do a full load and then stream ongoing changes, so the switch is a short pause.

The sequence: maintenance mode, pause Sidekiq, finish the restore or drain replication, switch DATABASE_URL and REDIS_URL, update Route 53 (TTL lowered a day ahead), re-check sequences, verify writes, leave maintenance. Keep the old platform as a rollback until you are confident.

who runs it, who funds it

VIWho runs the move, and who can fund it

You can do this yourself with the steps above. Many teams have a partner run the landing zone, the containers and the cutover.

Partner-filed funding: AWS says the Migration Acceleration Program (MAP) helps offset initial migration costs. It is built for migrations with meaningful ongoing AWS spend, so a small Rails app may not qualify. When the migration does qualify, your matched partner files it and AWS approves: typically $50K to $150K for startups. Depends on the workload; AWS approves. Activate credits are separate, and you apply for those yourself.

CloudRoute matches you with one vetted AWS partner. Startups pay CloudRoute nothing; partners pay CloudRoute a monthly membership plus 10% of AWS-approved funding.

Who files it
FundingWho files itAmountWhen it fits
Migration Acceleration Program (MAP)Your matched AWS partner$50K to $150K for startups. Depends on the workload; AWS approves.You are not on AWS yet and want to migrate.
AWS Activate FoundersFounder applies$1,000 to start, up to $5,000Self-funded startups with no investor or accelerator behind them.
AWS Activate PortfolioFounder appliesup to $200,000Startups backed by a VC firm, accelerator or angel investor that is an AWS Activate Provider.
Facts checked on October 10, 2026. AWS decides every application.
what bites rails teams

VIIRails-specific gotchas

The small set of things that turn a clean migration messy.

  • Assets compile wrong: No CSS after cutover usually means assets were not precompiled in the image or the asset host is wrong. Precompile at build time and check CloudFront.
  • Connection limits move, they do not vanish: RDS limits scale with instance memory. Size pools per process and use RDS Proxy.
  • Scheduled jobs must be recreated: whenever and Heroku Scheduler do not move. Rebuild each schedule in EventBridge Scheduler or sidekiq-cron.
  • Slow requests the timeout used to hide: Without Heroku's 30-second wall, slow endpoints run longer. Set load balancer and Puma timeouts deliberately.
  • Secret drift: Different RAILS_MASTER_KEY or SECRET_KEY_BASE values across services break credentials and sessions. One value from Secrets Manager.
  • Ephemeral filesystem: Anything written to local disk (uploads, generated files) must go to S3.
component by component

Rails component to AWS service

Every Rails building block, where it lands on AWS, what changes, and the effort.

Rails componentAWS serviceWhat changesEffort
Puma webECS on Fargate plus ALB (ECS Express Mode for small apps)Dockerfile; ALB terminates TLSMedium
Sidekiq workersSeparate ECS serviceProcfile process becomes a serviceMedium
PostgreSQLRDS for PostgreSQL or Aurora PostgreSQL (plus RDS Proxy)DATABASE_URL; cutover by dump and restore or DMSHigh (cutover)
Redis (Sidekiq, Action Cable, cache)ElastiCache (Redis OSS or Valkey)REDIS_URL and cable.ymlLow
Active StorageAmazon S3:amazon service in storage.ymlLow
AssetsPrecompiled in the image, served via CloudFrontAsset host settingLow
Scheduled jobssidekiq-cron or EventBridge SchedulerRecreate every scheduleLow
Credentials and config varsSecrets Manager and SSM Parameter StoreInjected as env vars by ECSLow
Domain and TLSRoute 53 and ACMDNS and a free certificateLow
The "Medium" and "High" rows (containers, Sidekiq, the Postgres cutover) are what a migration partner usually handles.
want this run for you?
Get matched with an AWS partner who runs your Rails migration
Get matched free with a vetted AWS partner who can file it
how a match works

How a match works (example)

  1. You tell us about the work

    You fill in a short form: what you run today, what you want to move, test or build, your stage and your region.

  2. We pick one partner

    We read your answers and pick one vetted AWS consulting partner that fits the work, the stack and the region. We reply within 24 hours; your matched partner reaches out within 5 business days.

  3. The partner checks MAP funding

    Your matched partner scopes the migration with you. Then it checks whether the move qualifies for MAP (Migration Acceleration Program) funding. MAP is for teams that are not on AWS yet.

  4. The partner files, AWS decides

    If the work qualifies, the partner files the funding request with AWS. AWS reviews it and decides. The amount depends on the workload.

  5. You pay nothing

    CloudRoute is free for startups. Partners pay CloudRoute a monthly membership plus 10% of AWS-approved funding.

AWS Activate credits are separate, and you apply for them yourself. Use Activate Founders if no investor backs you. Use Activate Portfolio with the Org ID or invite from your VC, accelerator, incubator or angel group if it is an Activate Provider. A consulting partner cannot apply for Activate on your behalf.

faq

Common questions

What is the best way to run Rails on AWS?
For most production apps: Puma and Sidekiq as separate ECS services on Fargate behind an Application Load Balancer, PostgreSQL on RDS or Aurora with RDS Proxy, ElastiCache for Sidekiq, Action Cable and the cache, Active Storage on S3, and assets via CloudFront. App Runner closed to new customers on April 30, 2026; ECS Express Mode is the simpler option now.
Can I replicate Heroku Postgres to RDS with DMS?
Not on classic Heroku Postgres plans. Heroku does not grant the replication role that AWS DMS change data capture needs. Plan a write freeze and a pg_dump and pg_restore, or use managed logical replication if you are on Heroku Postgres Advanced.
How do I handle Sidekiq and scheduled jobs on AWS?
Run Sidekiq as its own ECS service against ElastiCache, scaled on queue depth. Keep sidekiq-cron if you use it; recreate whenever or Heroku Scheduler jobs as EventBridge Scheduler rules that run one-off ECS tasks.
Does my Rails code need to change?
Mostly no. ActiveRecord, Sidekiq, Action Cable and Active Storage are storage-agnostic. What changes is packaging, credentials, scheduled jobs and connection settings.
Can AWS fund a Rails migration?
Sometimes. MAP is filed by an AWS partner and is built for migrations with meaningful ongoing AWS spend, so a small app may not qualify. When the migration qualifies, your matched partner files it and AWS approves: typically $50K to $150K for startups. Depends on the workload; AWS approves.

Move your Rails app to AWS with a partner who has done it before.

CloudRoute matches you with one vetted AWS partner who runs the Rails migration: Puma and Sidekiq on ECS, RDS or Aurora, ElastiCache, S3, CloudFront and the Postgres cutover. The partner files MAP funding when the migration qualifies and AWS approves. CloudRoute is free for startups.

we reply within24 hours
partner-filed funding$50K to $150K
CloudRoute fee for startups$0