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 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 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 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 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 │ └──────────────┘ 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: How predictable is the traffic? Does the application need long-running processes? How much infrastructure do we want to manage? What are the database access patterns? How important is automatic scaling? What are the latency requirements? 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.