Demystifying Serverless Compute Manifesto
Serverless is HOT!
This is no longer a secret to all, serverless is trending at this moment. Market becomes quite occupied with solutions available. With great number of options to choose more people start digging into what serverless is and what that should be. I didn’t made a research but there should be academic publications regarding serverless concept and how serverless solutions might look like. This post i want to dedicate to serverless computing manifesto that was presented by David Potes and Ajay Nair from AWS (and a lot posts and reposts based on their words).
Serverless compute manifesto
They defined set of “strict” rules that should be taken into account while determining technology as serverless as following statements:
- Functions are the unit of deployment and scaling.
- No machines, VMs, or containers visible in the programming model.
- Permanent storage lives elsewhere.
- Scales per request. Users cannot over- or under-provision capacity.
- Never pay for idle (no cold servers/containers or their costs).
- Implicitly fault-tolerant because functions can run anywhere.
- BYOC — Bring Your Own Code.
- Metrics and logging are a universal right.
I want to go over each of this statements and would try to understand them by myself and explain them to you. But before proceeding to the next topic i want you to read following article: “Serverless. Let’s make it clear!”.
Functions are the unit of deployment and scaling
Granular compute unit in serverless is a function. Function should be short-lived, stateless, scalable, event-driven unit. So, this means that function can’t be a daemon, it should not know anything about it’s previous state (but function can interact with remote persistence layer, i.e. database, file storage, etc.).
Function should be a unit of deployment. Indeed, no matter what kind of concept meant-to-be-serverless platform puts on top of functions it still should deploy functions in first place and treat them as its minimum deployment unit.
Function should be a unit of scaling. I would say that it’s not kind of clear to me. In order to understand function’s scaling we need to know more about and understand infrastructure scaling principles where it runs, no? It’s always a dispute of horizontal of vertical scaling. In case we don’t know how particular meant-to-be-serverless platform scales function we can only expect to get following scaling — one event to one function.
Scales per request. Users cannot over- or under-provision capacity.
As i mentioned before, it does look like that for every event meant-to-be-serverless platform should provision new function. And this is where i completely disagree, such policy doesn’t look like efficient or cost-effective, what if the same function can handle more than one event (it doesn’t affect its principles: functions is not a daemon, short-lived)? Let’s say that policy that defines function as single-event handler is a “cold” policy and as i said not effective because it’s always takes some time to provision underlying infrastructure. As the opposite to “cold” there should be “hot” policy — keep function around as long as there’s something to do (more events to process).
Second statement is pretty straight forward. Users don’t have an access to underlying meant-to-be-serverless platform resource capacity, but user can manage his own function (call or cancel any number).
Never pay for idle (no cold servers/containers or their costs).
There’s nothing much to say here, most meant-to-be-serverless platforms are managed, so user don’t have to worry about VMs, containers.
Permanent storage lives elsewhere!
This one is also honest truth, each new function gets created within fresh environment, so function developers should save data at function’s side and expect to have it there. If you want to save data — use remote store.
Implicitly fault-tolerant because functions can run anywhere.
Okay, we expect functions to be very reliable because they are piece of software and we do know that it works locally (on your machine) and it should work within meant-to-be-serverless platform.
But i would better rephrase given statement. Function itself can be full of bugs, but it’s environment (what makes your code a serverless function) should be stable, scalable, fault-tolerant.
BYOC — Bring Your Own Code
Given statement is quite interesting because it implies to a runtime, but before talking about it let’s deal with “BYOC”. So the function is a piece of code that suppose to do single task (no matter would that be a single file or a project), the most interesting question: what is the bare minimum distribution unit for code? Would that be a jar, tar, wheel, binary executable, etc.? BYOC concept doesn’t really elaborate delivery process. As conclusion it’s not clear what kind of runtime meant-to-be-serverless platform allocates/creates for a specific function (if my function is a *.jar would that mean it will be used within JVM, if my function is a binary executable what that mean it will be used in Windows, and so on). Moreover, if BYOC is all about code with undefined runtime it means that Docker container also is a runtime for functions. Actually, having container defined as runtime helps to make runtime configurable, predictable, container-as-a-runtime addresses implicit fault-tolerance by default, because it appears to be possible to test how your code on how it acts in container-as-a-runtime.
As you can see, original manifesto statements are not clear and require improvements or creating them from scratch. Initial manifesto was presented by AWS and it might be good for AWS Lambda (to all of us AWS Lambda is a black box, we have no idea what’s going on inside), but what about open standards, open source solutions? Maybe CNCF is a good place to deal with open serverless standard/manifesto? Anyway, having all that said i want to make my own conclusion by presenting own view on serverless manifesto:
- functions are the unit of deployment and scaling
- underlying serverless infrastructure is not in control of users
- function’s runtime is stateless
- function scales with respect to number of requests. It can go hot (N requests to one function) or cold (one request — one function)
- implicitly fault-tolerant because runtime has predictable behaviour because it can be reproduced out of serverless platform
- BYOR — bring your own runtime (serverless should operate containers as runtime for functions)