node.js → aws · 2026 deployment and migration playbook

Migrate a Node.js app to AWS: the right compute target, the data layer, and the cutover.

The first decision decides the rest: is your Node.js app a long-running service (an Express, Fastify or NestJS API, a WebSocket server, a worker with a connection pool) or event-driven and bursty? Long-running belongs on ECS with Fargate. Event-driven belongs on Lambda behind API Gateway. Then the data layer maps cleanly: RDS or Aurora, DynamoDB where it fits, ElastiCache for Redis.

long-running APIs
ECS on Fargate
bursty and event-driven
Lambda + API Gateway
pooling fix
RDS Proxy
TL;DR
  • Long-running services (persistent HTTP APIs, WebSocket servers, queue workers, anything holding a connection pool) go on Amazon ECS with Fargate; ECS Express Mode is the simplest way to stand one up. Event-driven, spiky or cron-like work goes on AWS Lambda behind API Gateway. Many systems are hybrid: the synchronous core on Fargate, the async edges on Lambda.
  • Relational apps (Prisma, Drizzle, Sequelize, TypeORM, Knex) move to RDS or Aurora with a connection-string change. DynamoDB fits key-value, high-scale tables, but moving a relational app to it is a refactor. Redis (BullMQ, sessions, rate limits) moves to ElastiCache. Uploads go to S3.
  • Two Node-specific gotchas: Lambda cold starts on latency-sensitive APIs, and database connection exhaustion from many tasks or functions (use RDS Proxy). A vetted AWS partner can run the move. MAP is built for migrations with meaningful ongoing AWS spend, so a small app may not qualify; when the migration does, your matched partner files it: typically $50K to $150K for startups. Depends on the workload; AWS approves.
the one decision that matters

ILong-running service or event-driven?

Most bad Node.js-on-AWS architectures come from forcing a long-running app into Lambda, or the reverse. Start from the shape of the workload.

Long-running services benefit from staying warm: a persistent API, a WebSocket server, a worker draining a queue, anything with a database pool or an in-memory cache. They want a container that boots once and serves many requests. On AWS that is ECS with Fargate.

Event-driven workloads are bursty, stateless and often idle: S3-triggered processing, webhook receivers, scheduled jobs, fan-out from SQS or EventBridge. Lambda bills only while code runs and scales from zero automatically.

The trap is the middle. A steady-traffic Express API wrapped for Lambda pays a cold-start tax on latency, fights connection exhaustion against the database, and can cost more than a small always-on Fargate task. Lambda is excellent for spiky and idle work; it is a poor fit for steady, latency-sensitive, pool-heavy APIs.

the 30-second test

Does a request benefit from a warm process with an open database pool? Yes: ECS on Fargate. Bursty, stateless, idle-heavy or cron-like: Lambda and API Gateway. Unsure about a steady synchronous API? Choose Fargate.

the landing spots

IIPicking the Node.js compute target

There are several ways to run Node on AWS. For a team migrating an existing app, these are the sensible ones.

  • ECS on Fargate: The default for production Node APIs: serverless containers with VPC networking, a load balancer, per-service scaling, and separate API and worker services. The process boots once per task, so pools are reused and there is no cold start. ECS Express Mode creates the service, load balancer and scaling from one image for simple web services.
  • Lambda and API Gateway: Per-request billing and scale from zero, for spiky APIs, webhooks, scheduled jobs and event triggers. Costs: cold starts on latency-sensitive paths, a 15-minute execution limit, payload limits, and connection pressure on relational databases. Provisioned concurrency removes cold starts but also scale-to-zero.
  • App Runner (existing users only): App Runner was the Heroku-like option, but it closed to new customers on April 30, 2026. New teams should use ECS Express Mode instead.
  • EKS or ECS on EC2: Only for specific needs (existing Kubernetes, GPUs, placement). Overkill for a single Node app.
where your data lands

IIIThe data layer: RDS or Aurora, DynamoDB, ElastiCache

The compute choice gets the attention; the data layer is where migration risk lives. The mapping is mechanical and your ORM usually does not change.

Relational. PostgreSQL or MySQL through an ORM or raw drivers moves to Amazon RDS (like-for-like) or Aurora (storage that grows on its own, faster failover, up to 15 readers, Serverless v2 for spiky load). Same wire protocol, so you change the connection string and move the data.

DynamoDB. A fit for key-value or single-table designs needing very high throughput, and it pairs well with Lambda because it uses HTTP connections. It is not a drop-in for a relational app: joins, ad-hoc queries and cross-table transactions make that a refactor.

Redis and files. ioredis or node-redis for caching, BullMQ queues, sessions and rate limits moves to Amazon ElastiCache (Redis OSS or Valkey) with a connection-string change. Uploads must go to S3: local-disk writes break as soon as you run more than one task. Self-hosted Elasticsearch moves to Amazon OpenSearch Service.

the real-time question

IVWebSockets: ALB and Fargate, or API Gateway WebSocket APIs

WebSockets are long-lived and Lambda is ephemeral, so real-time often decides the compute choice.

The low-friction path for Socket.IO or ws is a long-running container on Fargate behind an Application Load Balancer, which handles WebSocket upgrades natively. Your real-time code does not change. Across several tasks, add the Socket.IO Redis adapter on ElastiCache so a message emitted on one task reaches clients on another.

Amazon API Gateway WebSocket APIs manage connections for you and invoke Lambda on connect, disconnect and message events. They scale to large connection counts with no servers, but it is a different programming model: you rebuild the connection lifecycle around API Gateway routes and a connection store. Good for greenfield fan-out; usually not worth it for an existing Socket.IO server.

the hands-on part

VDockerizing, secrets and CI/CD

Three mechanical tasks make up most of the hands-on work for a long-running Node app.

Dockerfile. A multi-stage build: npm ci and your build in the first stage, then a slim runtime image that copies only production dependencies and the build output, runs as non-root, sets NODE_ENV=production, and starts node dist/main.js directly. Push to Amazon ECR.

Secrets. Split process.env by sensitivity: secrets in AWS Secrets Manager (which can rotate RDS credentials), plain config in SSM Parameter Store. ECS (or Lambda) injects both as environment variables, so process.env.DATABASE_URL works as before.

CI/CD. Keep GitHub Actions and add build and test, push to ECR, and an ECS service update with health checks and rollback. Or use CodePipeline, CodeBuild and CodeDeploy for blue/green on ECS. Lambda apps use AWS SAM, the Serverless Framework or AWS CDK.

the risky part

VIThe database cutover: DMS, DNS and a short window

Everything else can be built and tested without touching production. The database cutover is the one moment that touches live data.

AWS DMS does a full load into RDS or Aurora, then streams ongoing changes where your source database allows it, so at cutover you switch to an already-current copy. If change data capture is not possible from your current host, or the database is small, use a dump and restore inside a maintenance window and time a test run first.

The cutover: maintenance mode, drain the last changes, pause workers, switch DATABASE_URL and Redis settings, update Route 53 (TTL lowered a day ahead), check that writes land in RDS, leave maintenance. Re-check sequence or auto-increment values after a data-only load. Keep the old environment as a rollback until you are confident.

who runs it, who funds it

VIIWho 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 seed-stage API 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 node teams

VIIINode.js-specific gotchas

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

  • Lambda cold starts: A cold function plus your dependency tree adds latency to the first request. Keep latency-sensitive synchronous APIs on Fargate, trim dependencies, or pay for provisioned concurrency.
  • Connection exhaustion: Many Lambda invocations or autoscaled tasks each opening pools can exceed the database's connection limit. Use Amazon RDS Proxy and size pools per task.
  • Local disk and in-memory state: Uploads, sessions and caches kept in one process break across tasks. Use S3 and ElastiCache.
  • Socket.IO across tasks: Without the Redis adapter, messages do not reach clients on other tasks.
  • Graceful shutdown: Handle SIGTERM so in-flight requests and jobs finish when ECS replaces a task during a deploy.
side by side

Node.js compute targets on AWS

The landing spots for a team migrating an existing Node.js app.

DimensionECS on FargateLambda + API Gateway
Best forSteady APIs, workers, WebSocketsSpiky, event-driven, idle-heavy work
Cold startsNone (process stays warm)Yes, unless provisioned concurrency
Database poolsReused per taskNeeds RDS Proxy at scale
Execution limitNone15 minutes
Idle costPays for running tasksNone
Simplest setupECS Express ModeAWS SAM or CDK
Mature systems often use both: the synchronous core on Fargate, the async edges on Lambda. App Runner closed to new customers on April 30, 2026.
want this run for you?
Get matched with an AWS partner who runs your Node.js 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 deploy a Node.js app on AWS?
For a long-running API, worker or WebSocket server: containers on Amazon ECS with Fargate behind a load balancer (ECS Express Mode is the simplest setup). For spiky, event-driven or scheduled work: Lambda behind API Gateway. App Runner closed to new customers on April 30, 2026.
Should I put my Express API on Lambda?
Usually not if traffic is steady and latency matters. Cold starts, connection pressure on the database and per-request pricing at steady volume often make a small Fargate service the better fit. Lambda shines for spiky, idle-heavy and event-driven work.
Do I need to change my ORM or database code?
Not for a relational move: PostgreSQL or MySQL to RDS or Aurora keeps the same wire protocol, so you change the connection string. Moving a relational app to DynamoDB is a refactor, not a migration.
How do I avoid database connection exhaustion on AWS?
Use Amazon RDS Proxy between your functions or tasks and the database, and size connection pools per task. It matters most with Lambda and with aggressive autoscaling.
How do WebSockets work after the move?
Keep a Socket.IO or ws server long-running on Fargate behind an Application Load Balancer and add the Socket.IO Redis adapter on ElastiCache for multiple tasks. API Gateway WebSocket APIs are an option for new real-time features with a different programming model.
Can AWS fund a Node.js 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 Node.js app to AWS with a partner who has done it before.

CloudRoute matches you with one vetted AWS partner who picks the right compute target, moves the data layer and runs the 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