A few months ago, I wrote about how my team is actively merging microservices back into the monolith. Then, yesterday, I shared my opinionated guide to managing Pull Requests (PRs) for my team of 4 engineers at InVision. In that guide, I talked about how my team prioritizes code reviews, shipping product, and providing value to our customers. These two strategies - using a ColdFusion monolith and making PRs our number one priority - allow my team to move fast and deploy hella often. And while I've always felt this in my bones, I was delighted to see that my Operations Team just created a dashboard that allows me to see those feelings materialized in a service-deployment bar chart:
This chart shows the number of deployments, per service, over the last 3-months. The
cfprojects service is the legacy monolith that my team owns and operates (
cf in this context stands for ColdFusion, hecks-to-the-yeah!).
To be clear, while my team deploys our service almost 4x more than the next highest service, this is not a direct comparison to other services. Since the newer platform is using microservices, deployments for like-functionality are naturally spread-across many services. As such, I would not expect a monolith and any given microservice to be deployed at the same rate. In fact, one of the selling points of microservices is that they can be scaled and deployed independently, which is exactly what we see playing out in this bar chart.
The reason that this chart is so exciting for me (and my team) is because it codifies the fact that the ColdFusion monolith does not slow us down. A "monolith" - like a "microservice" - is just an architectural decision chosen to solve a set of technical and organizational problems. One style of architecture is not inherently better than the other - each has a set of trade-offs that have to be taken into account when choosing the appropriate tool for the given job.
For me and my small team, we continue to double-down on the monolith because it is what works well for us. And, the more often we merge a "microservice" back into the monolith - what my team has dubbed remonolithification - the faster and more effectively my team is able to move.
ASIDE: My team just created a JIRA Epic to merge yet another service back into the monolith!
And, perhaps the most controversial part of all of this is that the ColdFusion monolith has essentially no automated testing. In fact, as my team continues to merge microservices back into the monolith, we drop any tests that the microservice had - we don't "port" tests into the monolith.
In lieu of automated testing, we make very heavy use of LaunchDarkly feature flags. This allows us to deploy code safely and - when needed - slowly in production. This gives us the confidence to move quickly, deploy often, and not break things.
The Point Is, It's All Subjective And Terribly Contextual. Period.
I'm writing this because one, I'm very proud of my team and the work that we do; but two, I'm writing this because I think it's important to remind people that every context is unique. When it comes to building web applications, there's no "one size fits all". There's only what works best for you and your team and their skills and their resources.
For my team, what works best is a ColdFusion monolith, re-imagined in Lucee CFML, and a generous helping of feature flags.
I am not saying this is what will work for your team. Your team is going to have a whole other set of problems that you need to solve in your own way with your own best practices. That might be 100% test coverage. It might be a "monorepo". It might be a thousand microservices and a service mesh. Or, it might be a ColdFusion monolith.
You do you! Pave your own cow paths and extract and codify the patterns that seem to be working for your team. And when your existing practices are causing you pain, fix those specific problems.