There is a short list of things a technology leader is not supposed to build. A database. A crypto library. And somewhere near the top, an SS7 stack.
We built one. SCTP, M3UA, SCCP, TCAP and MAP, from the specifications down to the octet, and on top of it an SMSC, an SMPP server, a signaling firewall and a fleet of STPs. It took years. It was the right call, and I can still defend every part of it, which is a different claim from saying it was easy, or that it would be right for you.
This is the reasoning, not the code.
What "buy" actually costs
Commercial signaling stacks are licensed the way telecom assets are licensed: per node, per link, per transaction rate, with a support contract sized to the assumption that you cannot leave. Add a second point of presence and you are negotiating again. Add a market and you are negotiating again. The cost does not scale with the value you create; it scales with your ambition.
That was a problem. It was not the problem.
The problem was on the other side of the contract. Every capability we wanted that the product did not already have became a feature request against somebody else's roadmap, built to serve their median customer. We were not their median customer, and no amount of relationship management changes that arithmetic. You end up with a permanent coupling between what your business wants to do next quarter and what a supplier is willing to prioritise this year.
For a company whose entire product is the routing of messages, that coupling is not a procurement detail. It is a ceiling.
The requirement that would not fit inside a product
Our business lived in the details of routing and policy. Which path a message takes, under which commercial agreement, with what filtering applied, with what fallback when a route degrades, evaluated per message, at full traffic rate, across markets with different rules.
Products expose knobs. We did not need more knobs. We needed to own the shape of the decision itself: to be able to express a policy that no vendor had anticipated, deploy it the same week, and change it again when a carrier agreement changed. The moment your differentiator is expressible only as a support ticket, you do not have a differentiator.
That is the honest build-versus-buy test, and it has nothing to do with engineering pride: is this capability the business, or is it supporting the business? Billing is supporting. Monitoring is supporting. For us, signaling and routing were the business.
Reading specifications like source code
So we read them. ITU-T and IETF documents, in order, bottom up.
SCTP first, our own userspace implementation rather than a kernel socket, because everything above it depends on association lifecycle behaviour you want to see and control. Then M3UA, then SCCP, then TCAP, then MAP. Then SMPP on the customer-facing side, and Cloudhopper-based tooling to exercise it.
Specifications tell you what the protocol is. They do not tell you what the network does. The gap between those two is where this kind of project actually lives: the carrier whose equipment is a decade old, the peer that sets a flag no document mentions, the timer that is theoretically optional and practically mandatory. Interop testing against real carrier equipment was not the verification phase. It was most of the work.
If you take one implementation lesson from this: state machines written carefully, and a test harness that can replay a real capture, are worth more than any amount of clever code.
The decision that mattered more than building it
It was not the decision to build the stack. It was the decision that the stack would not be the product.
Every layer was built as a component with a defined boundary: independently deployable, configurable as data, composable with the others. That sounds like ordinary architecture hygiene. In telecom software of that period it was not: the norm was a monolithic platform on bare metal, tuned by an engineer with physical access, where every new capability was a new procurement.
We built for containers, for horizontal scale, for configuration as data, for replacing a node without dropping traffic. Cloud-native before that phrase reached this corner of the industry.
What that bought us was compounding. Out of the same foundation, without a second build, came:
- More than one SMSC, rather than one blessed instance everything had to route through.
- A signaling firewall, applying policy at the layer where it can actually be applied.
- STPs at the edge, facing the licensed SS7 carriers.
- STPs on the inside, through which aggregators and partner companies connected to us. The same protocol competence, pointed in the opposite direction, and a business line rather than a cost.
- USSD applications, which are trivial when you already own TCAP and absurd when you do not.
The first capability cost a project. Every capability after it cost a configuration. That is the whole return on a platform, and it is invisible in the business case you write at the start, which is why most of these projects are killed before they get there.
What it cost, and what it bought
It cost years, a small team's sustained attention, and a tolerance for a period where we were demonstrably worse than the product we had replaced. Anyone who tells you their from-scratch protocol implementation was correct on day one is describing a different project than the one they ran.
What it bought: the third-party platform dependency disappeared, and the in-house signaling foundation was a direct contributor to a 9× profitability improvement. Not because the code was elegant. Because the cost per message fell, and because capabilities that used to require a purchase order became a week of work.
The larger return was optionality. When the business asked for something new, the answer stopped being let me ask the vendor.
Would I do it again?
Yes, under conditions, and I would say no far more often than yes.
- The capability is the business. If it is supporting infrastructure, buy it, and spend the years on something your customers can see.
- The specification is public, stable and testable. A protocol frozen in a standards document is a fundamentally different risk from a moving vendor API.
- You have real interop partners. Without equipment to test against, you are not building an implementation. You are building a theory.
- You can afford to be wrong for a while. Not financially. Organisationally. If the first outage ends the project, do not start the project.
- You keep the people. A from-scratch protocol stack is a bet on retention as much as on engineering. Losing the two people who hold the state machines in their heads is the real single point of failure, and the mitigation is documentation and pairing, started early, not after someone resigns.
Miss any of those and buy the product. Buying is not the coward's option; it is the correct option most of the time, and a CTO who cannot say so is not making a decision, they are expressing a preference.
But when all five hold, when the thing everyone tells you to buy is the thing your business actually is, then the received wisdom is just somebody else's context, and the most expensive dependency you will ever carry is the one between your roadmap and a supplier's.