Serverless technologies have been with us since Google released Google App Engine in 2008. For the first time a developer was able to develop a program and launch it to run on Google’s cloud without having to be concerned with details like how the server was provisioned or if the operating system required patches. Amazon launched a similar service, Lambda in 2015. Now, developers could create software and not have to worry about hardware, operating system maintenance, scalability, or locality.
I have spent a number of years working in a 100% serverless environment running a website and APIs at large scale with amazing success. This hosting strategy can be applied to the majority of businesses and there are very few cases where lambda is not a suitable choice.
But, to my surprise there appears to be very few business embracing serverless technologies and instead most are opting for running their estate in containers on PaaS solutions that come with expensive hardware rental pricing models and require significant operational efforts.
So lets cover some of the benefits of using serverless.
One of the many beautiful aspects of serverless technology is the pricing model. If I write a small piece of code and deploy it as a lambda function to AWS eu-west-1 (Ireland) then I will not pay a penny until the code needs to be executed. If I allocate the lambda function 512MB memory then I will be charged only $0.0000000083 per 1ms of execution time. Where this really shines is for an application that has an inconsistent usage pattern. I can deploy a staging environment that is equal to production in terms of resources but only costs money when in use. I can also add cheap redundancy in other geographic regions. Or if I have a SaaS application that sees heavy usage during the daytime and barely anything at night. When the application idles, so do the PaaS compute costs. In comparison, an application running on an EC2 machine or containerised service requires fixed performance all of the time. A machine with a number of processors and quantity of RAM must be provisioned and left running round the clock, racking up huge bills. You can automate scaling but it gets tricky (more to come on that…). I have seen platforms running on EC2 and then migrated to serverless and the reduction in cloud bills is staggering. This also makes serverless ideal for start-ups when you need to keep your cloud spend to a minimum and have it gently scale at the same pace as your business.
Another huge win of serverless technologies is the scalability. As mentioned already, when there is no processing required and the functions idle then compute power automatically scales to zero. On the other side, when business picks up and there are many requests to handle then serverless automatically scales to huge concurrency very quickly. AWS lambda has a service limit of 2000 concurrent invocations per region (within your account) and this limit can be increased with a simple request to AWS support. In comparison to running servers, you can put auto-scaling rules in place which could monitor metrics such as CPU utilisation, memory usage, network bandwith, etc. But, it is not easy to determine the right rules and thresholds and the machines do not provision quickly. It can take minutes for a new server to be added to the pool and fully initialized whereas a new lambda instance is up and running your code within milliseconds. Where I have seen platforms running on EC2 and then migrated to serverless, engineers have found themselves no longer preparing for peak loads with load tests and traffic forecasts, but instead not even noticing when a peak comes and goes.
Another benefit of serverless is that each lambda invocation is isolated within its own runtime process with dedicated hardware resource. This adds some default protection to your application from common bugs and issues that can occur. When you have a single process running on a server that handles multiple simultaneous requests then single request can consume more than its fair share of resources, slowing down other requests or even stopping the application from handling new requests. AWS will always fire up a new lambda instance as long as you haven’t reached the concurrency service limit.
There is little more frustrating in a software engineer’s day than a slow build and deployment pipeline. Deploying to servers and containers can be very slow. If you want to run some integration tests against your deployed application before pushing to production then you can be waiting minutes for a deployment to complete and machine or container provisioned and ready to run before the tests can begin. Contrasted to serverless, your function deploys very quickly and is available to run immediately after deployment. This is a game changer as CI/CD processes can run very quickly, providing fast feedback and allowing engineers to get on with their day.
Monitoring is easier to tackle in a serverless world. Processes that run in containers or on servers can handle lots of concurrent requests but there is little visibility on what is happening inside the process. It is possible to generate metrics within the process and scrape or push those metrics to a monitoring service but this can require significant implementation time and complexity. If there is an issue with the running process then those metrics may be unavailable. The isolated request nature of serverless functions provides some great monitoring functionality by default. You can view standard metrics for function invocations, error count, memory used per request, invocation duration, request concurrency and more. If you want to create your own custom metrics from within the function then AWS Lambda supports metrics logged in EMF (Embedded Metric Format). EMF is a standard JSON format that is automatically detected by AWS CloudWatch and converted from a log entry into a metric data point. Logging metrics to the console is very simple and does not add any significant latency to the lambda invocation.
Most importantly, serverless technologies allow businesses to MOVE FASTER. A lot of operational complexity is removed, complex networking configurations can disappear and engineers can quickly build simple distributed architectures that scale with little effort. Product engineering teams can focus on solving business problems rather than technical problems, writing small pieces of code that provide value to the business. The PaaS provider takes care of many cross cutting concerns, making a DevOps culture easy to implement.
Where is serverless not a good fit?
What doesn’t work..?
AWS lambda has a maximum invocation duration of 15 minutes. Generally, if your request handling is taking over 15 minutes then there is probably an opportunity to break up the task into smaller executable chunks. In some cases, long running processes could also be more costly on serverless and using a dedicated server may be more cost efficient. There are some processes that just need to run all the time, such as Prometheus. In those cases you have little choice but to find a server to run it on.
Vendor lock in
There is a argument that using serverless creates vendor lock in due to differences in serverless implementation. To date, I have not seen a real life situation where it was necessary to switch PaaS provider, but maybe in the future this will be thing… I’m sure it would also be fairly easy to use an adapter to interface your function code with different serverless runtimes.
I have witnessed much anxiety around cold start times for serverless functions and even I was sceptical before I started using serverless. But, in my experience, a combination of careful, efficient function design and picking the right runtimes and memory size can make this a non-issue. I have seen large scale production websites and APIs running on 100% serverless without performance issues and handling some fast ramp-up load tests.