Skip to main content

Serverless myths

· 10 min read
Ivan Barlog
AWS Solutions Architect @ BeeSolve

Recently I've been talking to people on various meetups about the Serverless technology and I noticed pattern - lot of people think about serverless as limitation rather than solution to real problems.

I've decided to bust a few myths I've been hearing repeatedly lately regarding the whole Serverless ecosystem. I am going to focus on AWS serverless technologies not serverless technology in general.

AWS Lambda is all there is to serverless

This is simply not true. There is lot of other serverless services which AWS offers. They even have this list Serverless on AWS if you don't believe me.

Serverless is not only about computing. It is about all services. You can simply imagine serverless as managed service which can scale down to 0 (at least that's what you perceive) with pay per usage pricing model.

Whenever you don't manage the infrastructure, you don't maintain servers, security patches etc. and you only ask for resource which is provided to you by your cloud provider you can talk about serverless.

Cloud computing Serverless cost more than traditional VPS

Yes and no. Serverless and cloud computing in general can cost more if you are not fully utilize its all advantages and features.

This was too long so I've created separate article called Cost of running online service which you can read.

When you start with serverless you are stick with it

No. If you are running your serverless workloads in AWS you are still able to use any other traditional services. AWS services are very highly interconnected and you can invoke AWS Lambda from almost every other service. You can also invoke and use any other services within AWS Lambda. You don't need to stick with AWS Lambda and DynamoDB forever. You can start your project with these simple but powerful services and when you realize that you need something else you can still refactor your application - your application, your rules.

AWS Lambda does not support my programming language

Yes. AWS Lambda has limited options regarding runtimes. But at the same time AWS Lambda can be deployed with Docker. So you can essentially run anything within Lambda if you wish.

Don't forget that there is different lifecycle model for AWS Lambda than you might be used to. Lambda receives request, it handles it, responds and then it is frozen and eventually dies. So all the code within lambda should be stateless. You shouldn't rely on long running servers nor on inter-request memory storage.

In all cases your application which runs on AWS Lambda needs to handle AWS events - depending on which service has invoked your lambda function. Most of the time you will need to handle API Gateway event and respond with API Gateway response.

Fortunatelly there are projects like AWS Lambda Web Adapter which helps you run any HTTP server within lambda. If you are PHP developer you should try Bref.sh and their custom runtime. Also you are in luck as PHP has very similar execution model as AWS Lambda - request, response, die.

There should be only one function per AWS Lambda

No. Please don't do this. This just don't make any sense.

You should group your code by functionality.

For instance if you have simple CRUD application and you create 4 separate lambda functions per each operation this is really an overkill. You want your lambdas to be always warm so you want to hit them a lot. Meaning it is very OK to have entire REST API or GraphQL endpoint deployed within single AWS Lambda.

On the other hand if you want to separate your service into multiple services (services not micro-services - micro-services are overrated) which might make sense you will probably want to deploy them as two separate lambda functions. This is great pattern because for instance your authentication service will need access to your sessions table but you probably don't want your public REST API to have the same access to such sensitive information. You can split by functionality and by access to resources.

There are lot of best practices on how to group your application code within lambda functions but those are just best practices. You know your application the best you should know which code is related and which is not. You just need to learn what is possible with AWS Lambda and then you can make your own decisions.

You can do either OLAP or OLTP not both

You actually don't need to compromise between online analytical processing (OLAP) and online transactional processing (OLTP) when you use AWS and Serverless. You can read more on what is the difference here.

People usually implement OLAP like MySQL or Postgres when there is no clear specification and the project requirements changes a lot and frequently. You just model your database and then you can access the data by whatever means. Take in mind that even if you use OLAP you still need to optimize your data for various data accesses.

When you need performance and infinite scaling you should try OLTP database like DynamoDB. The constrainst on changing the existing structure within DynamoDB are more tight so it is great for fully specified applications which does not tend to change a much. DynamoDB is all about data access patterns. Your data and its structure can change however you like but you should think twice about data access patterns before implementing DynamoDB table storage.

Using DynamoDB does not mean that you cannot change your access patterns later - it just means it is harder and it most likely requires some data migration along the way. Which when this happens once a year is not that terrible and it might be more suitable for your usecase than using OLAP anyway.

Using DynamoDB also does not mean that you cannot have your fancy dashboards or your data analysts to analyze your data. It just means that you either need to keep aggregation tables for showing all the dashboard statistics. For allowing your data team to see the data through SQL without need of spinning up some Data Warehouse you can use DynamoDB streams to stream your data to S3 bucket and then lookup the data with another great serverless database - Athena. This gives you the best of both worlds - your customers will be happy with highly available performant service (if you specify and implement your data access patterns correctly) and your data team still can see all the statistics they want - yes, Athena is slower than MySQL or Postgres but for data analysis you shouldn't need the speed - this is not for the clients this is for your internal team.

Read more on how to connect DynamoDB with Athena.

DynamoDB is key-value NoSQL store not a database

Technically file on a disk is database. It is container which holds some data.

DynamoDB is key-value NoSQL store it does not mean that you cannot model relations in it.

There are no foreign keys and you cannot use SQL shouldn't use PartiQL for data querying but if you don't believe the relations can be modelled read about how you can model entire GraphQL API in it.

Lambda's 15 minutes timeout is not sufficient

It depends on what you are trying to achieve with it. If you want to run server in Lambda then yes 15 minutes is not sufficient.

Remember Lambda model is reqeust, response, freeze/die. This means that your mindset about running online service should shift as well if you want to use AWS Lambda in its full potential.

Usually when you are unable to respond to request under a second it means that something is wrong anyway. Maybe your database is missing index or you are getting lot of data from database and processing it in-memory instead of selecting just a subset of data.

Whenever you need to do some processing of data you should do it asynchronously. When we are talking about web, it means that you should receive a request, put the task to the queue (ideally SQS) respond quickly to the user and let them know that the request will be processed eventually. If you want great UX you can implement websockets and push the "done" message through the Websockeet to the client when the processing is done in SQS.

If you need more than 15 minutes for your processing to finish consider adding more compute power to your AWS Lambda (eg. finetune) or split the processing into multiple batches and run them in parallel through AWS Step functions (when it needs to be quick) or if you don't care about how long the processing will take put the batches to the SQS.

If you 100% need to process everithing within single runtime environment and 10GB of memory plus 6 vCPU is not enough eg. you are still hitting 15 minutes timeout you still can try to spin up Fargate Task which has no timeout limits and still is fully serverless - it costs more though so maybe use this as last resort.

We cannot have Lambda cold starts

Lot of things changed after 11 years of introduction of AWS Lambda. Cold starts used to be the problem but they are not anymore.

There are even almost no cold starts for some runtimes like Java, .Net and Python with SnapStart.

Nevertheless usually when I talk with people about cold starts they argue that they cannot let their customers way once in a while additional ~300-500ms but they are perfectly fine to serve 2-3s database queries.

As always whenever you experience cold starts which are unbearable (eg. more than 1-2 seconds - remember cold starts are very infrequent) you should try to optimize your lambda function code for quicker startups. Also whenever possible you can mitigate coldstarts by various UX techniques so whenever user waits longer he does not feel stuck - I bet you already done that instead of optimizing those database queries.

Lambda memory limit is not sufficient

As of 2022 AWS lambda supports memory limit up to 10GB with 6 vCPU.

If this is not sufficient then I am not sure what is.

Some regions like eu-central-1 eg. Frankfurt still does not have full capacity for 10GB Lambdas but when you ask for service limit increase usually you will be able to run this beast within few hours.

Conclusion

If you are still afraid that Serverless cannot handle your application or traffic please leave a comment and I will try to help you find out if that's true.