Connector architecture
At what point does wiring each source directly to each consumer stop being the cheaper option — and what does introducing a hub actually cost when it isn’t yet warranted?
- measure
- connections to build and maintain, as sources and consumers grow
- hypothesis
- point-to-point is O(S×C); a canonical hub is O(S+C)
- looking for
- the exact crossover, not a hand-wave about “it scales better”
Adding a source shouldn’t mean editing every consumer
Point-to-point integration is always right at the start. Two sources, one consumer, two pieces of glue — a hub would be ceremony. The trouble is that nothing announces the moment it stops being right.
CryptoFundingWatch has five sources and three consumers — the scoring engine, the live view, and the alerting path. Wired directly, that’s fifteen pieces of integration, and each new venue adds three more. Worse, every consumer has to learn that Kraken calls Bitcoin XBT and Hyperliquid quotes hourly. The knowledge leaks everywhere.
LatticePulse is the same shape with different sources — four feeds into the heatmap, the alert engine, and the insider rankings. Twelve connections, and the SEC filing parser’s quirks end up duplicated in three places, drifting apart as each is patched separately.
The failure mode isn’t that it’s slow to build. It’s that a bug fixed in one path stays broken in the others, and nobody notices until the numbers disagree.
One canonical model in the middle
Sources translate inward, consumers read outward, and neither knows the other exists. The hub isn’t infrastructure — it’s the canonical model from bench 02 given a place to live.
Drag the counts and watch the mesh explode
Same sources, same consumers, two wiring strategies. The connection counts are the thing to watch — the pictures are just how it feels.
Point-to-point15 connections
Canonical hub8 connections
Introducing the hub without a rewrite
The migration is what stops people, not the design. It can be done incrementally — the hub starts as one more consumer.
Write the canonical model first, from the consumers
Same rule as bench 02. If the model is derived from whichever source you happen to migrate first, every later source arrives as an awkward special case.
Stand the hub up alongside, reading from existing paths
No consumer switches yet. The hub populates in parallel with the point-to-point wiring, which keeps running. Nothing is at risk because nothing depends on it.
Reconcile the two for a full cycle before cutting over
Compare hub output against each direct path and account for every difference. Disagreements here are real bugs, usually in an assumption a consumer made years ago — better found now than after the old path is gone.
Move one consumer, the least critical one
It reads from the hub; the rest stay direct. Any latency, freshness or shape problem surfaces on the consumer you can most afford to be wrong.
Migrate the rest, then delete the direct paths
Deleting matters. A point-to-point path left in place gets quietly used, and then there are two sources of truth — which is worse than the mesh you started with.
Enforce the boundary in the build
A lint rule or import check that prevents consumer code importing anything source-specific. Otherwise the mesh grows back one “just this once” at a time.
Where this runs
CryptoFundingWatch
Five venues, three consumers. Direct wiring would be 15 connections and each new exchange would add 3 more, with venue quirks spread across all of them. Through the hub it is 8, and a sixth venue costs exactly one adapter.
LatticePulse
Four feeds, three consumers — heatmap, alert engine, insider rankings. The SEC parser’s quirks previously risked living in three places and drifting apart. One write-side adapter means one place to fix them.
What the bench showed
The crossover is exact, and it arrives much earlier than instinct suggests. Point-to-point costs S×C connections and a hub costs S+C, so the hub wins whenever S×C > S+C — which rearranges to (S−1)(C−1) > 1. At two sources and two consumers it is a genuine wash: four connections either way. At three sources and two consumers the hub is already ahead, and it never loses again.
That is a much lower bar than “wait until it hurts”. Most teams build the mesh well past the point where the hub was already cheaper, because the cost arrives as a slow tax rather than a bill.
The connection count understates the real saving. Each point-to-point path carries a copy of the source’s quirks, so the true cost is S×C pieces of knowledge, not just wiring. Fixing a parser bug in a mesh means finding every copy; in a hub it means editing one adapter. The counts in the bench are the floor of the benefit, not the ceiling.
The honest caveat: the hub adds a hop, and therefore latency and a new failure point. For CryptoFundingWatch on a 60-second cycle that is irrelevant. If the requirement were sub-second, the calculus would change — and the answer might be a hub for the slow consumers and one direct path for the fast one. Architecture is not a morality test.
Bench source: public/connectors/index.html ·
Related: bench 02 — schema normalisation