DEV Community

Cover image for How I Would Structure a Node.js Backend on AWS: EC2 vs Lambda
Sahinur
Sahinur

Posted on

How I Would Structure a Node.js Backend on AWS: EC2 vs Lambda

When building a backend on AWS, one of the first decisions is not which framework to use.

It's where and how the backend should run.

As a Node.js developer, I've worked with Express-based APIs and AWS EC2, and one question that keeps coming up is:

Should I run my backend on a traditional server, or move toward a serverless architecture such as API Gateway + Lambda?

There isn't one answer for every application.

The right choice depends on traffic, workload, architecture, team experience, and operational requirements.

Here's how I think about the decision.

The requirement

For a typical Node.js backend, I usually need:

  • REST APIs
  • Authentication and authorization
  • MongoDB or another database
  • File uploads
  • Background processing
  • Logging and monitoring
  • Reliable deployment
  • The ability to handle changing traffic

A simple backend might look like:

Client
   ↓
Node.js + Express API
   ↓
MongoDB
Enter fullscreen mode Exit fullscreen mode

When deploying this to AWS, there are several ways to run it.

Options I considered

Option A: EC2 + Node.js + Express

This is the traditional approach.

Client
   ↓
Nginx
   ↓
AWS EC2
   ↓
Node.js + Express
   ↓
MongoDB
Enter fullscreen mode Exit fullscreen mode

The biggest advantage is control.

I can manage:

  • The operating system
  • Node.js process
  • PM2
  • Nginx
  • Networking
  • Installed dependencies
  • Background processes

It's also a straightforward model for developers who already understand traditional server deployment.

But that control also creates more responsibility.

I need to think about:

  • Server maintenance
  • Scaling
  • Memory usage
  • Process management
  • Security updates
  • Monitoring
  • High availability

I've seen this firsthand with production Node.js applications: the application itself may be working correctly, but server resources such as memory can become a problem under real traffic.

Option B: API Gateway + Lambda

The serverless approach changes the architecture:

Client
   ↓
API Gateway
   ↓
Lambda
   ↓
Database
Enter fullscreen mode Exit fullscreen mode

Instead of keeping a Node.js server running continuously, individual Lambda functions execute in response to requests.

This can reduce the amount of server infrastructure I need to manage.

It can also make automatic scaling much easier for workloads that aren't constantly running at high utilization.

But serverless introduces its own considerations.

For example:

  • Cold starts
  • Execution limits
  • Function design
  • Database connection management
  • Logging
  • Local development
  • Vendor-specific architecture

So serverless isn't automatically "better."

Option C: ECS / Fargate

Another option is containerizing the Node.js application:

Client
   ↓
Load Balancer
   ↓
ECS / Fargate
   ↓
Node.js + Express
   ↓
MongoDB
Enter fullscreen mode Exit fullscreen mode

This gives me many of the benefits of containers without requiring me to manage the underlying EC2 instances directly.

For larger applications or teams already using Docker, this can be a very attractive middle ground.

The architecture I'd choose

For a small-to-medium Node.js API with predictable traffic, EC2 can still be a practical choice.

A basic architecture could be:

                 ┌──────────────┐
                 │    Client    │
                 └──────┬───────┘
                        │
                        ▼
                 ┌──────────────┐
                 │    Nginx     │
                 └──────┬───────┘
                        │
                        ▼
              ┌──────────────────┐
              │     AWS EC2      │
              │                  │
              │ Node.js +        │
              │ Express + PM2    │
              └────────┬─────────┘
                       │
                       ▼
                 ┌──────────────┐
                 │   MongoDB    │
                 └──────────────┘
Enter fullscreen mode Exit fullscreen mode

This architecture is simple, familiar, and gives me direct control over the application environment.

But I wouldn't automatically use it for every new project.

If the application has highly variable traffic, independent functions, or a strong serverless requirement, I'd seriously consider API Gateway + Lambda.

The trade-offs

The interesting part isn't choosing the "most modern" AWS service.

It's understanding what you're giving up and what you're gaining.

Factor EC2 Lambda
Server management Higher Lower
Scaling Requires configuration Automatic
Long-running processes Good Limited
Cold starts No Possible
Infrastructure control High Lower
Deployment model Server/application Function-based
Operational complexity Higher Different, not zero
Best fit Persistent services Event/API-driven workloads

This is why I don't think "serverless means no problems."

It means you're moving some operational responsibilities away from servers and taking on a different set of architectural considerations.

A lesson from production

One thing that changed how I think about architecture is realizing that application behavior matters just as much as infrastructure choice.

For example, a Node.js API can run perfectly on a powerful EC2 instance and still have problems if an endpoint loads thousands of MongoDB documents into memory.

Likewise, moving that endpoint to Lambda wouldn't automatically fix inefficient data processing.

The architecture can help, but good application design still matters.

What I'd change next time

If I were starting a new AWS backend today, I'd make the architecture decision based on the workload instead of choosing a service simply because it's popular.

I'd ask:

  1. How predictable is the traffic?
  2. Does the application need long-running processes?
  3. How much infrastructure do we want to manage?
  4. What are the database access patterns?
  5. How important is automatic scaling?
  6. What are the latency requirements?
  7. Does the team already have experience with containers or serverless?

Only after answering those questions would I choose between EC2, ECS/Fargate, and Lambda.

Final takeaway

There is no single AWS architecture that is perfect for every Node.js application.

EC2, ECS/Fargate, and Lambda solve different problems.

For me, the important lesson is to start with the application's requirements and workload, then choose the AWS service that fits.

The goal isn't to use the most services.

The goal is to build a system that is reliable, maintainable, scalable, and appropriate for the actual workload.

And that's one of the things I'm continuing to learn as I work deeper with AWS and backend engineering.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.