When talking about serverless, two advantages immediately pop up:
- Scaling out of the box - Probably the best thing we can think of as developers.
- Don’t manage infrastructure issues - configurations, updates, patches are no longer issues.
Serverless is much more than FaaS - our managed database service that is responsible for scaling, encryption, backups, performance, logs and more IS Serverless. The same applies to managed queues, storages, web APIs and other services.
Ultimately, every application is comprised of 3rd party APIs. They are great because they allow us to focus on our product development, rather than implementing an in-house solution that someone has already implemented before - and probably better than what we can do. And the best part - we care neither about scaling nor about the infrastructure.
In serverless, there’s one major caveat regarding APIs. When we pay-per-use, or specifically, we pay for the amount of time that our code is running, fast interactions with APIs are crucial! We will need to measure the performance in order to understand the impact on our cost and our customer’s experience.
Using Auth0 with AWS Lambda for authentication
Let’s start with a quick example - setting up a Lambda function in Python, that returns the user details for a given ID. For user management and authentication we are going to use Auth0.
Our main handler.py that represents the Lambda function looks like this:
Measuring the performance of the APIs
To get the idea of how long it takes to get the response from Auth0 we can add time prints. That is very hard to maintain and analyze. As we said, we prefer a managed service that will take care of it. We will use a performance monitoring solution for Serverless - Epsagon. Once we set up the library in our code, we will get a full visualization of this function’s trace:
We can observe that it takes ~600ms for Auth0 to get the response from Auth0. Running this operation several more times yields a result of ~500ms on average. The additional idle time that we wait for the response, affecting us in a higher cost, and user experience.
Optimizing the performance with Lambda and Auth0
At this point, there are few things we can do in order to optimize the performance:
- Reduce the latency to the service - by selecting a closer service region in Auth0 (for example, US instead of EU) we can improve the response times. Measuring the new service region configuration puts us with ~150ms on average (a 350ms / 70% improvement!).
- Caching data (AKA memoization) - The user profile changes rarely, so there is no reason to request the same profile from Auth0 every time. Instead, we can store a dict with user_id mapped to his profile and timestamp of the last update. If this timestamp is up to date, we could use the cache data. Otherwise, we can send a new request. It improves the duration drastically (when using cache it’s 0ms!).
Considerations when choosing an API
For every component in the application’s architecture, there are several APIs to choose from. This list summarizes some key metrics to evaluate:
- Price - Undoubtedly, this is important.
- Integration - How easy is it to start work with the service? Does it have a library for the programming language I’m using?
- Performance - How fast will this API react?
- Documentation - It is sometimes underestimated, but for us, developers - it is critical.
- Limitations - Are there any API limitations? It might be a deal-breaker.
- Extra features - Security and regulations, community and support, etc.
Serverless is much more than functions - this is our entire application with managed resources and 3rd party APIs.
When integrating these with functions, it is important to benchmark their performance with the external resources and APIs and understand their impact on both on our cost and on customers experience.