This month, we're turning off the last SaaS tool in a system we spent 18 months building. When we started, those tools were the hero of the architecture. Today, they're the part we're ripping out.
Here's how we got there, and why I'd probably do it differently if I started the same project today.
How we got here
A year and a half ago, we had a discovery meeting with a client in the health sector. They walked us through their workflows, the tools they were using, and how everything connected. What astonished us wasn't the complexity itself, but the fact that non-technical people had built something this functional out of off-the-shelf tools. Zapier, Typeform, Salesmate… A real hero, glued together from SaaS tools.
Our job was to build a central system on top of all of that. A customer-facing portal that connects the existing tools and makes the experience self-serviceable. The way health clinics actually work is more complicated than you'd think :D, but at the time the plan was straightforward: keep the SaaS tools, build the portal around them, integrate the gaps.
At first, we thought leaning on those tools would make our life easier. And for the first release, it did.
The real problem: you inherit every limitation of every tool
Here's what we underestimated. When you build a central system that depends on five SaaS tools, you don't just integrate five APIs. You inherit five sets of limitations. Every workaround in every tool becomes a workaround in your system. Every quirk, every blackbox behaviour, every missing capability, every release schedule you don't control, all of it now lives in your stack.
And there's no engineering discipline that can mitigate that. You can't refactor your way out of someone else's product decisions.
Three things broke us over the 18 months, all flowing from this one root.
Three sources of truth
The central entity in these workflows was the product. We needed to have products in at least two of the SaaS tools plus our central system. Two sources of truth is already a problem. Three? Imagine the clinic's staff looking at a product in their CRM and seeing the wrong price, while our central system and the customer's checkout show the correct one. The customer is fine. But the staff is now making decisions based on a wrong number, and the analytics they track in that CRM, revenue, conversion, performance per product, are quietly off. The answer was always the same: hope, then check.
Testing without a net
Most SaaS tools don't give you a dev environment. And on top of that, regulated healthcare meant some of the legacy systems in the stack were government-certified, no proper API, no test environment, and no chance of being replaced.
So testing turned into hoping. In our dev environment we built fake providers that returned fake outputs, and we had to keep those fakes in sync with what the real tools returned (which was often uncharted territory). In production, we shipped and watched.
This is the part a CTO will feel in their stomach. You can't write a meaningful integration test against a system that has no test mode.
Staff bouncing between login screens
The system stopped being just for clients. The clinic's own staff lived in it too. Every time they had to jump from our portal into a differently-looking CRM or form tool, the friction added up. We used SSO where we could, but SSO doesn't fix the fact that you're in a different system, with a different mental model, looking at different buttons. Our goal was to minimise clicks. The SaaS stack maximised them.
The cost
Cost was a major factor too. We'll dig into SaaS vs custom economics in a separate piece, but here's the short version: the change over the last 18 months has been enormous. It used to be unthinkable to replace a SaaS tool with a custom build and actually save money. Now it's perfectly possible, and in a lot of cases, it makes complete sense.
Once the build cost dropped, every one of the problems above stopped being a tradeoff and started being a tax.
So, would I do it again?
If your central system depends on more than two SaaS tools to support one core workflow, you are inheriting more limitations than you realise. The integration cost is visible. The tax of testing-without-a-net, three-sources-of-truth, and staff-bouncing-between-tools is not, until you've lived it for a year.
Run the custom-build math before you sign another renewal. The number you get back will not be the number you got two years ago. If you want a starting point, we wrote up how we think about replacing SaaS with custom builds.
Would I do this project the same way 18 months ago? Probably. Would I do it the same way today? Almost certainly not. The SaaS-glue start was correct for its moment. The moment changed faster than the architecture did, and that's the part worth paying attention to.
Authentic thoughts by human me :). Grammar fixed by AI.