Serverless computing is increasingly popular, so when building a new application in 2019 should you go serverless or stick with PaaS? AWS started the serverless movement in 2014 with the introduction of its AWS Lambda service. Back then it felt as revolutionary as when Steve Jobs introduced the first iPhone. The main idea was to completely get rid of infrastructure management. You just need to write a small piece of code, upload it and cloud will take care of the rest. It felt like PaaS 2.0. The bigger, better, more advanced version of PaaS.
PaaS sought to make infrastructure easier to manage, so developers can focus on working within web frameworks rather than wasting time in dealing with the underlying infrastructure. The goal is to simplify the process of deployment and operation. At the same time, they still offer access to the infrastructure, which provides a balance between automation and flexibility to configure your servers. For example, Heroku today makes it as easy as a 1-line command to deploy, manage, and scale server apps.
So which approach should we choose for building apps today? Should you make the switch to serverless? The first step is to look at all our options objectively, evaluate them for our specific situation, and make a reasoned choice. Both can solve basic development needs: delivering functionality quickly and reliably. Understanding the technical differences will help you determine which approach is best for a particular project.
There are many serverless and PaaS platforms to use for our comparison. For serverless, popular options include AWS Lambda, Google Cloud Functions, Azure Functions and OpenWhisk. On the PaaS side we have Heroku, AWS Elastic Beanstalk, Google AppEngine and more.
To simplify our comparison, let’s focus on AWS Lambda for serverless and Heroku for PaaS as prototypical examples. We'll try be as fair as possible in our comparison.
Serverless offers some really great advantages. You don’t need to manage infrastructure or app servers, so you can focus on just coding functions. It also bills per-call basis rather than a per-hour basis.
There’s no infrastructure to manage.
Just write a small piece of code, upload it to the cloud and the cloud service will do everything else. No more server setup and management. No more scaling and load balancing problems. No more troubleshooting servers and network. Sounds like a dream! While a PaaS solves some of these issues, you may still need to think about managing dynos, geo-distribution, fault tolerance and scaling.
Increase development velocity.
There is no need to write code or use frameworks for handling HTTP, parsing JSON and so on. You just need to write pure business logic in a function. Lambda will do everything rest for you. With Heroku, you still need to write code to implement your application server.
Pay only for resources that are actually used.
With any PaaS provider, you are paying for the availability of specific compute resources, such as CPU and RAM, whether or not they are in use. With Lambda you are paying ONLY when you are actually using the resources. Using Lambda you will pay for a number of invocations, for the amount of consumed resources, and for execution time. This billing model itself is pushing developers to write compact and efficient code. With Heroku, you are billed for running dynos, even when they are not used. You can scale down unneeded dynos, but you must run at least one to have a functioning app.
Integrate with other AWS services.
Lambda is very well integrated with many other AWS services. It’s easier to use if all your infrastructure is running on AWS. You may even be forced to use Lambda as a way to integrate AWS services with external services, such as forwarding Cloudwatch events to a monitoring service.
Compute at the edge can lower average latency.
PaaS platforms offer an opinionated and standard infrastructure that makes them developer friendly. They simplified the management of the underlying infrastructure while still providing access to it.
Simple to use as part of regular developer workflow.
Getting your app running on Heroku requires fewer steps, and could be as simple as a Git push. As your app matures, Heroku also integrates other services in a convenient package like continuous integration and review apps. With Lambda, you have to package your code into a zip, upload it, and configure triggers and permissions. You are not able to expose your app to the internet without configuring API Gateway.
Unlimited HTTP requests for the same price.
Heroku doesn’t bill per request, so it’s more predictable, and a single dyno can handle thousands of requests per second, depending on your code. With Lambda you are forced to use API Gateway to expose it via HTTP. It can be expensive because you are paying for every request, on top of your Lambda request and bandwidth charges. At the time of writing this post, API Gateway alone costs $3.50 per 1M requests. That may not seem expensive at first glance. But don’t forget that we live in a world where an app or a service can go viral and become hugely popular overnight. The question is, will you be able to pay the AWS bill after that?
Fewer long tail latency issues.
Heroku dynos run continuously and are ready for requests at any moment. You can even use the preboot feature to ensure the dyno is ready to receive traffic before routing to it. One of the biggest potential issues with Lambda is long tail latency. When Lambda is triggered, it will spin up a Firecracker-based microVM and run your code there. This will take some time to start, so the first response will be longer. All subsequent requests that land on that existing Lambda instance will be processed without a cold start and the associated latency. In my experience, for Java-based Lambda, the cold start can be around 10 seconds. This shows how JVM is a bad choice for this use case. With Go, the cold start in my use case got down to 1.5 seconds — a pretty significant improvement, but it’s still long.
You can run any code.
Heroku lets you deploy, run, and manage applications written in Ruby, Node.js, Java, Python, Clojure, Scala, Go, and PHP. You can even run Docker containers with any image you choose. Lambda, on the other hand, supports only a limited number of runtimes. AWS tried to address this during last year’s re:Invent with the announcement of the Runtime API. Now, you can build a Linux-compatible binary in the programing language of your choice and run it on Lambda. However, not all programming languages allow you to do that.
There’s no need to rewrite existing apps.
If your application is already using an application server, you usually don’t need to make many changes in order to run on Heroku. On the other hand, it may require more effort to port existing apps to Lambda — particularly those not written as serverless functions originally. That’s also assuming that Lambda supports the necessary runtime. With legacy applications, this can be a significant limitation.
You have longer execution time.
The current limit for Lambda execution is 15 minutes. That’s enough for many tasks, but not for all. Some specific tasks, for example, from an ETL domain, may require longer execution time than is available on Lambda. With Heroku, you can use a worker dyno to run tasks for many hours at a time. Nevertheless, it’s best practice to design your dynos to be stateless, so consider using a job queue and saving your work periodically.
In summary, Lambda can be a great solution when you've got a bit of code you just need to run with as little overhead as possible, for task-based background work (if you can fit it into Lambda limits), infrequently used functions, and instances where long tail latency is not a problem. It can also be the right tool if you need very fast average latency at the edge. You can easily use it for gluing AWS services together with some custom logic and for building infrastructure or automation tools. Think about tasks like decoding small videos, resizing pictures, or processing AWS events as a good fit for Lambda.
On the other hand, Heroku is a good fit for new web applications because it integrates many common parts of the development lifecycle in a more convenient package, without requiring you to configure multiple services. Doing a Git push and getting a working app after a couple of minutes is a breeze. It's also better for compute operations that take longer than a few minutes or for frequently called functions. Visit the Heroku Platform description to learn more about how Heroku works.
What is your opinion on which to choose in 2019? Let us know in the comments below.