One question kept coming up while I was learning AWS.
After building an application, where should it actually run?
AWS offers several compute services, but three appear repeatedly:
- Amazon EC2
- Amazon ECS with AWS Fargate
- AWS Lambda
Initially they all seemed to do the same thing—they execute code.
The more I learned, the more I realised they represent three different deployment models rather than three competing services.
This article explains the mental model that helped me understand when each one makes sense.
Every Application Needs Compute
Regardless of whether you're building a REST API, processing uploaded images, or running background jobs, somewhere there must be a computer executing your code.
AWS offers different ways to provide that compute.
The question isn't:
Which service is the best?
Instead, the better question is:
Which execution model matches my application?
Option 1: Amazon EC2
Amazon EC2 gives you a virtual machine.
Inside that virtual machine you install:
- Linux (or Windows)
- Docker (optional)
- Your application
- Any additional software you need
Conceptually:
Amazon EC2
│
▼
EC2 Instance
│
▼
Ubuntu Linux
│
▼
FastAPI / Node.js / Spring Boot
With EC2 you are responsible for managing the server.
That includes operating system updates, security patches, monitoring, backups, scaling, and maintenance.
When EC2 Makes Sense
EC2 is often a good choice when:
- Your application runs continuously.
- You need complete control over the operating system.
- You install custom software.
- You require GPU instances.
- You need SSH access.
Typical examples include:
- Web applications
- Jenkins
- GitLab
- Minecraft servers
- Machine learning servers
The biggest advantage is flexibility.
The trade-off is operational responsibility.
Option 2: AWS Lambda
Lambda follows a completely different execution model.
Instead of creating a server, you upload only your code.
Whenever an event occurs, AWS creates the execution environment, runs your function, returns the result, and then releases the compute resources.
Conceptually:
Event
│
Start Function
│
Execute Code
│
Return Result
│
Stop
Unlike EC2, no server sits waiting for requests.
Compute exists only while the function is running.
When Lambda Makes Sense
Lambda works particularly well for workloads that are:
- Event-driven
- Short-lived
- Stateless
Common examples include:
- Processing uploaded files
- Sending emails
- Scheduled tasks
- Payment processing
- API Gateway integrations
- Image resizing
One major advantage is that there are no servers to manage.
AWS automatically provisions infrastructure whenever the function is invoked.
Option 3: Amazon ECS with AWS Fargate
Suppose you've already containerised your application using Docker.
You don't necessarily want to manage Linux servers, but you also don't want to rewrite the application as Lambda functions.
This is where ECS and Fargate become useful.
Amazon ECS manages containers.
AWS Fargate provides the compute needed to run those containers.
You simply provide a Docker image.
AWS handles the underlying infrastructure.
Conceptually:
Docker Image
│
▼
Amazon ECS
│
▼
AWS Fargate
│
▼
Running Container
This provides many of the benefits of containers without requiring direct server administration.
When ECS + Fargate Makes Sense
Fargate is often a good choice when:
- Your application already runs in Docker.
- You want containers without managing Linux servers.
- Your application runs continuously.
- You're building microservices.
It provides a balance between the flexibility of containers and the convenience of managed infrastructure.
Comparing the Three
| Requirement | Recommended Service |
|---|---|
| Need a virtual machine | Amazon EC2 |
| Running Docker containers without managing servers | Amazon ECS + AWS Fargate |
| Event-driven function execution | AWS Lambda |
Rather than replacing one another, these services address different architectural needs.
A Helpful Mental Model
One way I started thinking about these services was by asking what remains active while the application waits.
With a traditional web application:
Start Server
│
Waiting...
│
Receive Request
│
Process
│
Waiting...
The server is always running.
With Lambda:
Event
│
Execute
│
Finish
There is no continuously running server.
Execution begins only when an event occurs.
Background Processing
Another interesting distinction appears when using Amazon SQS.
With a traditional application:
Server
│
Waiting
│
Request
│
Response
The application waits for work.
With SQS and Lambda:
Message
│
SQS Queue
│
Lambda Starts
│
Process Message
│
Lambda Stops
Instead of the server waiting, the queue stores work until Lambda is triggered.
This architecture is particularly useful for asynchronous tasks that don't need an immediate response.
So Which One Should You Choose?
Over time, I realised that the decision is usually simpler than it first appears.
If you need a virtual machine and complete control over the operating system, EC2 is often the right choice.
If you've already packaged your application as a Docker container and don't want to manage Linux servers, ECS with Fargate provides a managed container platform.
If your workload is short-lived and event-driven, Lambda allows you to focus entirely on your code without thinking about servers.
Each service solves a different problem.
The goal isn't to memorise features but to understand which execution model best matches the application you're building.
Final Thoughts
One lesson that stood out while learning AWS was that compute isn't a single concept.
Amazon EC2, ECS with Fargate, and Lambda all execute code, but they do so using different architectural approaches.
Understanding those approaches makes it much easier to choose the right service instead of trying to force every application into the same deployment model.
Once I started thinking in terms of execution models rather than AWS products, the differences between these services became much clearer.
Top comments (0)