If you're new to the tech industry, you might be overwhelmed by the countless buzzwords floating around—serverless, containers, AWS Lambda, Docker—and what they actually mean for building applications. In this post, I’m going to explain it all in a simple and intuitive way. By the end of this post, you'll understand the most important differences between serverless and containers, along with how you can determine which one is right for your project.
What is Serverless?
Let’s start with serverless. The name "serverless" does not mean that there are no servers; rather, it means that you don’t have to manage or worry about servers. Instead, everything including provisioning, scaling and maintenance is abstracted away by a cloud provider like AWS, allowing you to focus purely on writing code.
One of the most well known serverless services is AWS Lambda. You essentially write a small function, upload it, and Lambda will run it every time it’s triggered ex. when a user clicks a button on your website. And the best part? AWS scales it up or down for you based on the demand and you pay only for what you use.
Example:
Let’s say you’re building a website where users can fill out a form to do some kind of calculation, like finding out a price or result depending on what they entered. Instead of having to setup and maintain a server that is always running and waiting for form submissions…you can use AWS Lambda instead!
With AWS Lambda, you write a small piece of code (called a function) that will only run when someone submits the form. Once Lambda runs the function, it gives back the result to the website.
Lambda also handles things like scaling automatically. So, whether 1 person or 1,000 people submit the form, Lambda can run the function for each of them, without you worrying about managing extra servers. This makes it really efficient and cost-effective.
What are Containers?
Now let’s talk about containers. Containers, especially with tools like Docker, allow you to bundle your application and all of its dependencies (libraries, configuration files, etc.) into one single lightweight unit that can run anywhere
Think of containers like a box that has everything you need to run an application – the code, the libraries and any other tools or runtime it requires. And because your app is in this “box”, it runs exactly the same on your computer, on someone else’s computer in the cloud, or on someone else’s computer with a different set-up.
In other words, you don’t have to worry about things not working just because they’re different. It’s like having a device that you can take anywhere and it still works but without having to change settings, or install the kitchen sink. Unlike serverless though, you have complete control of what’s inside that box running your app.
The most popular containerization tool is Docker. They are a way to make sure that the application will work the same in any environment as long as Docker works, and also make it easy to be moved between dev, staging or production environments.
AWS have a service like this called Fargate where you can run containers without having to worry about with the underlying infrastructure in a similar way Lambda does with serverless functions. You would use containers most of the time when you need more control over the operating environment, or if you have an application where you have several services running together.
Example:
If you were creating an e-commerce application, perhaps a online store, you would need several different parts to work together; one part that talks to visitors (the web server), one part that stores all the product and customer data (the database), and a number of parts that perform tasks such as sending e-mails or taking payments.
With a virtual machine you can’t run the same image on your laptop as you do in production, unless they have identical hardware. So if the developers work on MacBooks and the servers use HP ProLiant with Intel Xeon E5-2690 then people say it works on my machine much more often than we would like to hear.
On the other hand with Docker containers you can pack each of those parts into separate “boxes”. And each box has everything that part needs to work, so they don’t interfere each other. So this will make sure that each part runs smoothly, whether you’re working on your computer or running it in the cloud.
So even if web server, database or some other service have different needs but they’ll all work the same everywhere because they are packed into their own container very neatly.
Challenges of Serverless vs. Containers
Challenges with Serverless:
- Cold Starts: When a Lambda function has been dormant for some time, it may take a couple of seconds to “warm up” the next time it’s triggered. This is called a cold start and can be an issue for latency-sensitive applications.
- Execution Limits: Lambda functions have a maximum execution time of 15 minutes. If your application needs to run longer processes, you might run into limitations.
- Stateless Nature: Serverless functions are stateless, meaning they don't retain data between executions. For applications that need to keep track of user sessions or store data temporarily, this can be a challenge.
- Complexity in Orchestration – If you have many functions working together, their interactions can become perplexingly complex.
Challenges with Containers:
- Infrastructure Management: With AWS Fargate, you do not have to worry about many infrastructure related things but still containers needs more configuration than serverless function like memory, cpu, and storage.
- Complex Scaling: Container does not scale automatically as Lambda does. You have to do the setting of scaling policy which is quite complicated for the first timer.
- Deployment Overhead: Deployment of containerized application needs configuration of many services like Networking, Load balancing, Storage etc.
Why Choose Serverless?
Serverless is perfect for:
- Event-driven applications: If your app runs in response to specific events, like file uploads or user requests, Lambda is a good choice.
- Automatic scaling: Lambda scales up and down automatically based on the number of requests. Predicting unpredictable traffic spikes? Go serverless
- Cost-efficiency: You are only billed for the time your function actually executes. No requests, no cost!
- Instant deployment: No need to provision servers – just upload your code and it’s ready to run.
Example:
In a project that I’m currently involved in, users upload files to our website. Upon each file upload, an AWS Lambda function is triggered which processes the file (e.g., resizing an image, analyzing the content) and persisting the result in a database. I don’t have to care about setting up servers or scaling because Lambda just runs whenever a new file is uploaded and scales automatically if need be. Additionally, I only get charged for the time it takes for the function to run (cost-efficient!).
Why Choose Containers?
Containers are ideal when:
- You need more control: Containers give you a lot of control over the entire environment. If you have the need to run specific versions of software or libraries, containers are for you.
- You have long-running processes: If your app needs to run for more than 15 minutes, containers can handle it, as they don’t have the same execution time limits as Lambda.
- You have multiple services: Where as if you have requirement of multiple components (web server, database and cache etc) then container is more suitable to manage them in modular way.
- Portability: Container are portable i.e. you can run same container on your laptop, cloud or another cloud provider too.
Example:
In another project, we actually used Docker containers to execute an entire web application that was composed of many micro services. For example a Auth service, database, caching layer all being its own container. It was really slick as you could easily manage/deploy each service on their own and use the same deployment for your local dev environment as you did with stagging/production.
Challenges We Faced in Real-Time
Challenge 1: Splitting Large Dependencies in Serverless
I remember when I was deploying an app with large dependencies to AWS Lambda and we hit the 50MB package size limit pretty quickly because at first we just bundled everything together in one Lambda function and it grew too big.
Solution: We split the core logic into separate Lambda functions each responsible for a specific task, and used Lambda Layers to share common dependencies between them which resulted in smaller size overall and more modular design.
Challenge 2: Scaling Complexity with Containers
On one of our Docker container-based projects, we had to make each service (web server, database etc.) independently scalable. But it become quite complex to configure scaling policies for all the containers.
Solution: We used AWS Fargate to achieve hands-off scaling, and we leveraged CloudWatch metrics to monitor the resource usage. This way, we were in position automatically to update the amount of containers based on traffic or resource usage.
Benefits of Each Approach
Benefits of Serverless:
- No Server Management: You can say goodbye to server management or having to worry about what goes on beneath the application layer.
- Automatic Scaling: ****Lambda automatically scales with your application so you don’t have to worry about if your capacity is set correctly.
- Cost-Efficiency: You only pay for the compute time that you consume—there is no charge when your code isn't running.
- Quick Deployment: You can deploy updates faster, as there’s no need to manage the underlying infrastructure.
Benefits of Containers:
- Full Control: Containers allow you to have full control over your runtime environment and dependencies.
- Consistency Across Environments: You can run the same container in development, testing, & production.
- Longer Execution Times: Unlike Lambda, containers can run for as long as you want, making them ideal for longer running processes.
- Stateful Applications: Containers can maintain state, which allows building more complex and stateful applications.
The Future: What’s Next for Serverless and Containers?
Both serverless and containers are evolving. We’re seeing more powerful serverless offerings, like AWS Lambda@Edge and Azure Functions, which let you run your code closer to users in order minimize latency. I think we’ll continue to see the uses cases for serverless expand.
On the other hand, we’re still early in terms of containers and their use with cloud native architectures. With tools like Kubernetes and services like AWS Fargate, I expect we’ll quickly see the role of containers becoming more prevalent in this space.
In the future, it may not be an either/or choice between serverless and containers. Both will likely coexist. Developers will use serverless for simple, event-driven workloads and run containers for more complex, stateful applications.
Conclusion: Which One Should You Choose?
Now that you know how serverless and containers work, it’s time to make the decision according to the requirements of your application. If you need a programming model where you could focus only on your code, and requires massive scalability specially for short interval workloads based on events, then go with serverless, otherwise go with containers.
In the end, a lot of modern architectures are a hybrid that try to get the best of both worlds and be free to use what ever makes sense for the problem/solution. E.g. Use serverless for your APIs, and still have full docker/kubernetes-based environment to do all sorts of background processing.
But in order effectively utilise this approach you have to know both sides so you can make an educated decision on how far to go when scaling in cloud..
I hope you liked this article on Serverless vs Containers and it gave you a clear idea about the use cases of both serverless and containers. I will post more articles, deep diving into these technologies.
See you soon!
Top comments (0)