More than 400 serverless and function-as-a-service (FaaS) enthusiasts gathered recently in Austin for the fourth iteration of ServerlessConf and out of all the presentations given there, this might have been the most important slide:
Mike Roberts is its author and if you don’t know his work from the Symphonia cloud and serverless consultancy you might know him from Martin Fowler’s blog, where last summer Roberts published what many consider to be the definitive description of this young technology and its benefits.
What Roberts addressed during his talk was that although cost savings gets the headlines when it comes to serverless technologies, that isn’t the main benefit that should be getting people’s attention. Sure, serverless architectures scale down beautifully, and with the major FaaS vendors providing generous free tiers it is easy to get started with Serverless without spending a whole lot of money.
With monoliths you get four at-bats a year, and with microservices you get 365. Which one is more likely to find an innovation hit?
But Roberts’ main point that I’ll be expanding on here is that the smaller, more loosely coupled pieces that make up a serverless architecture lend themselves extraordinarily well to agile software methodologies. That means that serverless isn’t about cost savings, it’s about at-bats.
From Monoliths to Microservices
Software innovation comes from rapid iterations, or to borrow a baseball term, at-bats. The premise there is that most ideas are bad, so the best way to find good ideas is to cycle through as many ideas as possible to improve your chances at finding a good one. If you get more rolls of the dice, you increase the chances that one of them will come up a seven. To switch sports metaphors, the New England Patriots has historically hoarded picks in the NFL draft and end up getting more players that can contribute at a professional level. There are countless other examples.
In the software world, we collectively learned a lot from the move from monolithic architectures to the current microservices de facto standard. My favorite description of that phenomenon came from Amazon Web Services’ Vice President of Cloud Architecture Adrian Cockcroft, in a presentation on fast delivery at Monkotoberfest 2014. His before picture from that deck looks like this:
Tightly coupled components that typically communicated with each other via in-memory library calls of some kind, all with a single release plan written in a single language, is how we all used to do write software. All components had to synchronize during a QA Release cycle and if there was a bug found there, or heaven forbid in production, the whole release had to be backed out because the dependencies were so tight the components couldn’t exist independently.
In this monolithic model, you were lucky if you could release once per quarter because of the complexity involved in moving all these dependent pieces together at the same time.
Microservices, though, brought us more loosely coupled components that communicated with each other via the contract of a published API. As long as that API remained constant, the components could be released independently and even written in different languages. In this model, weekly or even daily releases are common because the risk of breaking an interface between two components is highest when an API change occur, which is rare.
With monoliths, you get four at-bats a year, and with microservices, you get 365. Which one is more likely to find an innovation hit?
From Microservices to Functions
Serverless architectures take two key concepts of microservices a step further to make it easier to add new functionality, and possibly more importantly, remove functionality that isn’t generating value, resulting in more and more focused at-bats. First, because they can be loaded in milliseconds from disk, functions are smaller. At ServerlessConf, more than one talk embraced the idea that a function should do exactly one thing.
Second, whereas microservices create contracts between components via APIs, the Serverless approach adds the ability to create those contracts not just between components but also between other services provided by the FaaS vendor via events. This loosens the coupling between components, even more, making it easier to add and subtract business logic without disrupting what is already there.
Let’s look at a concrete example based on the canonical AWS Lambda use case, which when you look more closely at it is incorrect:
This image thumbnail example is the most widely one when explaining Serverless concepts, but for where the movement is going, it’s not quite complete. As presented now, an image gets dropped into object storage, which causes a trigger to be fired. In response to the trigger, a function gets executed that takes the original image and generates three thumbnails out to a different portion of object storage.
What’s wrong with this? It’s that AWS triggers currently support one and only one function invocation. OpenWhisk and a few others support multiple function invocations per trigger and all the FaaS providers will likely support that at some point.
How does that change the example and better illustrate this concept of more and more focused at-bats? If multiple functions could be executed in response to a single event, the better approach would be to have one function per desired image size instead of a single function that handles all three.
Suppose you wanted to try out a fourth and a fifth image size to see if your application could be stickier for your users if they had more choices. In this multifunction model, you’d simply have to add two new functions to the same trigger without disturbing the code in the first three functions. Similarly, once you collected usage metrics you’d likely find that not all of the image sizes were popular and in this multifunction approach you’d simply remove the unpopular ones without disturbing the code in the ones that people are using more heavily.
Because of the small size of the individual functions and the loose coupling provided by the events, it becomes easier to add and subtract features, resulting in more and more focused at-bats.
Software engineering is still a young discipline compared to, for example, structural engineering where you can find new construction of archways that aren’t all that different than what Romans used to build aqueducts. As such, software architectures continue to be in a constant state of change as we all collectively try to figure out how to do it better.
Serverless approaches are the next evolutionary step in that constant change. By shrinking the unit of functionality and coupling connections between those units with events, it becomes easier to insert or delete those units. This aligns nicely with agile development, enabling teams to get more chances, more at-bats, to find innovative features for their applications.
Feature image via Pixabay.