In your journey to cloud-native nirvana, you may be adopting microservices architectures for your next-generation applications. You may have had some initial successes with DevOps and automating your builds to help forge a path forward for your microservices journey. After a year or so, you may also be trying to convince the rest of the organization to go down this path, as well. Unfortunately, whether anticipated or not, you'll run into issues. Microservices is a complex architectural pattern and distributed systems themselves are difficult to get right. While you march down the path of working through and solving some of these challenges, you will certainly have naysayers and folks who wish to go in a different direction. With how fast technology moves, and with the new shiny options for building services and applications, can you be sure your effort to make microservices a successful endeavor for your organization is not in vain?

The simple answer is yes.

These days, "serverless" and "functions-as-a-service" (FaaS) have found themselves at the early side of the hype cycle. Some folks have gone so far to say that serverless and functions are the next evolution of microservices, and that you should just skip the whole microservices architecture trend and go right to serverless. Just as you'd expect, this is a bit hyperbolic; by which you shouldn't be surprised. There's a lot of exciting, new technology available to us as architects and developers to improve our ability to achieve our business outcomes. What we need is a pragmatic lens through which to judge and apply these new technologies. Although as technology practitioners, it's our responsibility to keep up with the latest technology, it's equally our responsibility to know when to apply it in the context of our existing technology and IT departments. Let's take a look at a model for understanding how microservices architectures and serverless along with functions-as-a-service fit into our toolbox.

First, let's understand why we would use a microservices architecture. The main reason you'd opt to use a microservices architecture is to improve the speed at which you're able to make changes to your application when your application's monolithic nature has become the source of bottlenecks and impedance for change. All of the other benefits of microservices are derived from that basic premise. Of course, the reason why we'd want to go faster with our changes to our applications is to quickly get new features and functionality out to our customer to test whether we can achieve the expected positive outcomes as a result of these changes. If we make changes to our software in an effort to improve our business value and it does not pan out, then we need to quickly know that and move on to try something new. Microservices is an optimization of our application architecture to allow us to move faster and get those changes out quicker.

Most organizations will find that some percentage of their custom-built applications will benefit from an iterative progression to a microservices architecture. These applications will benefit from this change, and as architects and developers, we should not get discouraged with the hurdles we'll see. The important thing here is to identify and measure improvement indicators, like how many changes we can make to the software per day, how safely we're able to make these changes, and so on.

On the other hand, not all applications require a highly complex, decomposed set of services to move faster. On the contrary, when you're first experimenting with a minimum viable product and you're testing whether your idea has any market value, you may opt for a different architecture more amenable to this part of the lifecycle of an application. There's a good chance that for an MVP test, you strike out and there is very little, if any, market value. In that case, you would just throw that MVP application away. You will probably be iterating it very quickly and eliciting feedback from potential users. In this case, the business value is not understood, the domain that you implement in code will be constantly changing (if not disappearing altogether), and you'll gain insight into your code as you go. In this environment, you'll be changing APIs, boundaries, components, etc. that make up your system. Prematurely optimizing all of these components into distributed services with API contracts et. al will actually slow you down. You'll be constantly changing your APIs and components together and coordinating with all of your small "two-pizza" teams, which smells of a distributed monolith. You might as well just use a monolith for that and you'll be able to go faster and get farther.

At this point, we see that microservices can be appropriate for some percentage of the application portfolio, while monolith applications make sense for some other percentage. There is no single "one-size-fits-all" strategy. Another angle to consider when building either microservices or monoliths (and it follows whether you're optimizing an existing architecture or building to test ideas) is whether the functionality you need to build already exists either as third-party services or as existing services you own within your enterprise. The idea that we can fully leverage existing services to build our applications without having to procure hardware, install and patch operating systems, and optimize our capacity for the highest expected throughput for the life of the software is what the cloud and its services are really all about. Cloud providers and their partners regularly offer databases, message queues, caches, CDN, etc. and even higher-order functionality like language translation, mapping/geo-spatial coordinate mapping, weather, etc. as on-demand, pay-as-you-go services that can be combined in interesting ways to build applications. When we leverage existing higher-order services without worrying about how to install, provision, and plan for capacity, we are moving towards a "serverless" architecture. Serverless architectures strive to re-use existing services without worrying about what it takes to run the service.

Functions-as-a-service is related to serverless because it allows us to use a compute model (scoped down to that of a single application function) that helps stitch together the various services we may consume to build an application. In this compute model, functions are spun up on-demand and you're billed only for the time a function was running. This fits well with being billed on-demand and pay-as-you-go with the various other services youmay consume. Now, you can build applications that scale without having to worry about solving all of the difficult technology problems that need to be solved in order to make this happen. It's someone else's (the service provider or cloud provider's) problem. If you're able to outsource a lot of those difficult infrastructure challenges to someone else, focus squarely on the business logic that's differentiating to your business, pay-as-you-go, and on-demand, you're able to more quickly experiment, try out ideas, and deliver business value for your customers.

Outsourcing this kind of functionality may not always be possible, however. When we decide to leverage cloud services, we give up control of uptime/SLA, feature road-map, bug fixing, regulatory compliance, et. al to someone else. This may be an appropriate tradeoff for a part of the portfolio or for parts of the organization. Others may not be comfortable doing this.

Serverless doesn't have to be a full "public cloud or nothing" proposition, however. If we look within a single organization, parts of it may be "serverless" to other parts. For example, the "buying" side of a retail operation may provide services to other parts of the organization or even third-party vendors/partners that help others build analytics, recommendations, or other applications using the "buyer" services. With well-defined APIs and a workflow for subscribing and paying for the APIs, you could use microservices/monoliths on your own infrastructure (or cloud) and provide serverless capabilities. In many ways, this is just an evolution of service-oriented architecture (SOA). The big difference when you're doing it yourself (or one part of the organization providing services to another) is that the organization as a whole is not serverless; someone still has to set up, manage, and patch the servers and all of the supporting infrastructure.

Ultimately, business decisions, business goals, maturity and capability of an IT organization, and any existing legacy constraints come in to play when we decide what application architecture or technologies we can leverage. If you're going down the path of microservices for the right reasons, don't get distracted by other shiny things. Conversely, you will need to continually invest into the latest technology and skills and know when to use them. Monolith, microservices, and serverless all have their place.