The Serverless Citadel
A simple path to outgrow the Serverless Monolith
Starting a new project as a Serverless Monolith is often a good idea. It's easier to get something off the ground that way since this type of setup requires less mental and configuration overhead.
On the other hand, microservices are an important tool in our arsenal and can be key to unlocking sustainable growth. And, needless to say, serverless fits incredibly well within a high-scale, event-driven microservices world.
But transitioning from a fully fledged Serverless Monolith to microservices can appear intimidating. There are ways to make that transition easier, and today I want to introduce an idea that could make leaving the monolith behind even more gradual and cognitively easier.
I call it the "Serverless Citadel".
It's based on the Citadel concept from DHH (who is no friend of microservices and seems to have a particular antipathy towards serverless).
Let's look at the idea first, and then a couple of points where we might want to differ with DHH.
The Citadel pattern encourages us to take away specific workloads from the main monolith. The Citadel looks like a big monolith at the centre, surrounded by a few small, independent services (the “Outposts”).
It's simple, yet effective. It doesn't take nearly as much planning and thinking as migrating from a monolithic architecture to microservices does.
By separating critical parts of your application into small independent services, we begin to enjoy some of the benefits of a microservice architecture without abandoning the serverless monolith that has taken us this far. Not yet, at least.
There are one or two points where DHH's advice, originally meant for the traditional monolith community, shouldn't really apply to a Serverless Monolith.
Firstly, DHH encourages us to look for ways to improve the monolith as our "first instinct". In other words, adopting the Citadel pattern should be a last resort.
But there's no need to adopt that mindset when it comes to serverless. Spinning up a side service or two is relatively easy. It can be done in a matter of minutes using your favourite framework.
So, as soon as it makes sense (and as early on as is feasible), new independent services should be activated to support our Serverless Monolith.
Secondly, as a staunch supporter of the Majestic Monolith, DHH believes that in almost every case the Citadel is as far as we should stretch our application.
But again, with serverless there is no need to think that this is the case. Serverless makes building and scaling microservices a lot easier.
So, while the Citadel is a great approach to transition away from a Serverless Monolith, our goal should be to (eventually) kill the monolith.
Notice that I'm not saying that ending up with microservices is inevitable; perhaps, the Citadel will be all you need. But as your application grows in scale and complexity, microservices are a natural end goal.
In my view, the Citadel is a great idea. It gives us the peace of mind of knowing that we can start with a simpler model (namely, the Serverless Monolith) and still, over time, end up with a highly scalable architecture without radical, overnight migrations in the process.
As a reminder, "Serverless Monolith" is an imperfect shorthand term. It describes a serverless system that resembles an old fashion monolith, but is also different in a few radical ways.
The Strangler Pattern is a great way to do this, and the Citadel makes the strangling even easier.