[Part 4] Six modern software architecture styles: Serverless

Fourth instalment in the "Six modern software architecture styles" blog post series. In short: Build and run services without having to manage the underlying infrastructure.

[Part 4] Six modern software architecture styles: Serverless

This blog post series reviews six common architectural styles used in distributed systems and talks about how to choose the best one for your use case.

This blog post focuses on the Serverless architectural style, however we also recommend checking the other posts in the series:

(1) Monolithic
(2) Microservices
(3) Event-Driven
(4) Serverless
(5) Edge Computing
(6) Peer-to-Peer

Serverless Architectural Style


One-liner Recap:

Build and run services without having to manage the underlying infrastructure.

Background:

The Serverless architectural style is a further evolution of cloud-native architectures - which were designed to leverage the uniqueness of cloud platforms for scalability, reliability, and agility requirements.

Like all other Architectural Styles, the concepts that underpin the Serverless architecture have been around for a long time but have become a fixture in mainstream software development since the rise of cloud computing, and, more precisely, since Amazon introduced the first mainstream Function as a Service (FaaS) platform - AWS Lambda - in 2014.

With FaaS, developers write their application code as a set of discrete functions, which perform specific tasks when triggered by an event. These functions are then deployed on cloud providers which fully abstracts away the infrastructure management.

The ‘on-demand’ nature of functions allows them to be scaled up to meet a spike in demand and scaled back down to zero on completion of the task. This makes them ideal for unpredictable loads and for quick (fail-fast) experimentation.

It’s important to note that the Serverless architecture is closely related to the Microservices architecture and the choice between the two is far from a binary one. Many modern applications combine serverless and microservices and, in fact, AWS Lambda functions typically play a crucial part in microservices and are invoked through event sources.

This has often led to the misconception that functions are microservices themselves - which ultimately caused some unfortunate, massively complex architectural designs when AWS Lambda functions first came out (see ‘Nano services’).

Weaknesses:

One of the biggest drawbacks of the Serverless architecture is vendor lock in.

Intellectually, we all know the benefits of a cloud-agnostic deployment, however, it’s never as evident as when things go south and you suddenly need to migrate to a different cloud provider. The ability to switch cloud providers and services allows you to select the one with the best solution price, performance and stability for your use case.

Unfortunately, FaaS providers natively support only certain technologies (i.e. programming languages, frameworks and tools) and while there are workarounds, they can be complicated and problematic. Therefore it’s not possible to run the same function with different providers and any migration will require reconfiguring it to some extent.

Another common hurdle is right sizing services: you need to achieve the right level of cohesion of functionality but maintain low coupling. Developers need to find a happy medium between the extremes of nano services and monolithic services. In other words, we want to avoid small microservices with noisy communication between them but also avoid lumping all functionality into one microservice!

The final hurdle is debugging. Serverless functions presents unique challenges due to their ephemeral nature and distributed execution. Functions spin up on-demand, execute, and disappear, making it difficult to reproduce issues or understand the context in which failures occurred.

Traditional debugging techniques like setting breakpoints or inspecting running processes don't work when your code only exists for milliseconds. Full stack session recordings transform this debugging experience by capturing the complete execution context. From the triggering event through the function's execution, API calls, and response, even after the function has terminated.

This persistent record of transient executions is particularly valuable when debugging cold start issues, timeout problems, or intermittent failures that are nearly impossible to reproduce in development environments where functions behave differently than in production.

Strengths:

The Serverless architecture it’s great at enabling fast, continuous software delivery. You don’t have to think about managing infrastructure, provisioning or planning for demand and scale!

More specifically, these are the four main benefits:

  1. Easy scalability: While microservices are generally used for continuous, constant workloads, serverless functions excel in scenarios where tasks are utilized occasionally and for a limited time. For instance, this architectural style is well-suited for resource-intensive tasks like image uploads.
  2. Cost efficiency: By adopting a pay-as-you-go model, you only pay for actual usage and scale back down as soon as the task is complete.
  3. Reduced operational overhead: By abstracting infrastructure management, it enables developers to focus on writing and deploying the application code. Serverless functions can also be reused across multiple applications, streamlining development efforts. For example, a serverless function for user profile picture uploads can be applied to various applications within an organization.
  4. Reliability and availability: The loosely coupled nature of serverless functions reduces dependence across components, enhancing reliability. If one function fails, the overall application can continue working seamlessly. The underlying infrastructure management by the provider further minimizes potential points of failure, ensuring enhanced reliability and availability for applications.

Real-world use cases:

An O’Reilly serverless survey in 2019 found that nearly 40% of companies worldwide are using serverless functions in some form. In fact, while it’s possible to build entire applications in a pure serverless architecture, in the majority of cases, only specific services are serverless - those that are not in permanent use and have a relatively short run-time, especially if it is resource intense.

For example, services particularly suited to being run as serverless functions include: rapid document conversion, predictive page rendering, log analysis on the fly, processing uploaded S3 objects, bulk real-time data processing, etc.

Adamdotdev and David Peter’s conversation on X (Twitter)

GETTING STARTED WITH MULTIPLAYER

👀 If this is the first time you’ve heard about Multiplayer, you may want to see full stack session recordings in action. You can do that in our free sandbox: sandbox.multiplayer.app

If you’re ready to trial Multiplayer you can start a free plan at any time 👇

Start a free plan