FaaS: It’s like CaaS, but worse

I’m not entirely sure that I’m on board the FaaS train at this point, compared to a container-first pipeline built on a CaaS platform.

Or that I buy the idea that FaaS is “the next big paradigm” or “the Next Step”.

FaaS mostly benefits metered cloud providers, because it allows them to become the connective tissue of your solution in a much more fundamental way than they used to be. They’re literally your runtime. This is of course why commercial cloud providers are still the primary advocates of the FaaS model, which leads to the first problem: The main reason FaaS exists (to tightly couple your code to metered cloud provider platforms at a fundamental level) is fundamentally at odds with best practice for actually writing code (decoupling your code from the underlying cloud provider platform specifics). This is not true of CaaS.

I really, truly do think that when people talk about “the benefits of FaaS”, they aren’t talking about benefits inherently granted by choosing to model and build their software using “the FaaS paradigm”.

They’re talking about benefits granted by hosted platforms and pipelines, and frankly that has nothing to do with “the FaaS paradigm” specifically. Or rather, if that’s all “the FaaS paradigm” amounts to, the FaaS paradigm isn’t a architectural/development/ops “paradigm” at all, but a rate plan. A sales model.

The things that grant FaaS platforms their initial velocity benefits largely do not emerge as side effects of “the FaaS paradigm” itself, but from specific tooling and pipeline implementations provided by AWS/Google/etc. Not to mention that commonly-cited benefits such as “I don’t have to provision or manage servers” or “I don’t have to worry about scaling” are also wholly true of CaaS platforms.

You can bring a lot of this home to yourself by setting up and trying out on-prem or self-hosted FaaS frameworks. It becomes clear that you’re still just running code in containers, and all “the FaaS paradigm” really buys you is a delivery pipeline and an event bus. And that if someone else isn’t managing and scaling that delivery pipeline and event bus for you, “the FaaS paradigm” amounts to a layer on top of CaaS that trades a focus on containers for a less standardized, less robust, less flexible, less portable, less organized, and less trackable type of artifact.

“Ok, maybe from an ops perspective FaaS is less desirable and not really a ‘paradigm’, but from a development perspective, what it’s REALLY about is event-based programming and small, testable functions!”

Well, first off, you can build apps out of small, testable functions sitting on a hosted event bus in CaaS too, just as easily. Because that’s literally all FaaS platforms are doing.

The idea of building small, isolated functions that will be composed into useful functionality is not new, or a unique benefit enabled by FaaS platforms. From a development perspective, the structural/reliability/simplicity benefits of the FaaS programming model are identical to the pure functional programming model, which has been with us since the 1960s. FaaS is just doing this at at the framework level rather than the runtime/language level, which is arguably a more over-engineered/kludgy and error-prone approach.

“But so what, why does it matter if all of the magic comes from the fact that it’s a hosted, tightly-coupled solution? I can solve the lock-in problem with Serverless! It’s still the fastest way to get my code in front of people, because there’s no initial pipeline setup!”

As the scale of what you’re building and the length of time it will be in service increases, the development and operational flaws of the FaaS model start to rapidly overtake the merits. FaaS is great for rapid TTM (time to market), and continues to be great for exactly as long as that is the most important metric. Which explains why it’s popular with startups trying to get sold before they have to start maintaining and significantly extending the software they’ve built, and quick-n-dirty stage demos.

And it also explains why I believe FaaS will never be an easily-recommendable universal platform in the way that CaaS is. Containers-as-the-central-artifact-of-deployment-and-execution is simply a better long-term paradigm for your development and ops teams, because containers are a more robust/manageable/reliable/agnostic artifact to build your process around.

The processes you will inevitably have to build as your app becomes more complex and more mature will scale better if built around containers as the central artifact.

Containers make better atoms. To quote Kelsey Hightower, they “provide a better contract”.

Alright, but a lot of the things you’re criticizing are things that can/will likely be solved by 3rd-party standardization of the FaaS development/operations story as the model matures.

Yes, you could probably solve a lot of this by standardizing FaaS deployment artifacts, defining cross-platform bundling and packaging standards, and then building out smart abstractions (which Serverless is already doing), but

  1. You will always be fighting against the fact that FaaS’s raison d’être is to tie your code to the underlying provider’s platform.
  2. Those standardized, platform agnostic bundles/artifacts/runtime models already exist, and we call them OCI containers. Which means as the FaaS model matures, it will inevitably start to look more and more like CaaS, and will either be absorbed into the CaaS paradigm, or people will start inventing new wheels for it to solve the problems that CaaS has already solved.

If both CaaS and FaaS free us from having to deal with infrastructure management and scaling, then CaaS is by nature simply more robust, more scalable, has a healthier ecosystem, and is simply a more wisely-designed paradigm. FaaS is a sales & lock-in tactic, CaaS is based on a well-designed, well-abstracted, battle-tested paradigm.

A true paradigm, in the sense that building your process around containers has pervasive, positive side effects for the entire application lifecycle, from architecture, to development, to testing, to operations.

Thoughts? Holes/flaws in the above points that I’m not seeing?