OHDSI Rotterdam Is Over. The Protocol It Validated Is Just Getting Started.
OHDSI Rotterdam opened April 18 with 400 health data researchers in the same building.
It closed with a two-node DHT running cross-machine Kademlia XOR routing in the background — live, signed, tamper-proof — while the conference rooms debated whether federated learning could scale.
The network answered. In another room. While no one was coordinating.
That's not a metaphor. That's the architecture working exactly as designed.
What Three Days of Rotterdam Coverage Actually Measured
Over the T-2 through T+1 window, six articles tracked the conference in real time:
- T-2: The Packet Relay That Turns 300 Isolated Research Nodes Into One Collective Brain — the pre-conference framing: why OHDSI's existing network already had the structure QIS needs, and what the missing synthesis layer would do
- T-1: OHDSI Built the World's Most Powerful Health Data Network. Here's the Missing Layer. — the technical argument: OMOP standardized the language, QIS adds the learning loop
- T-0: Rotterdam Day 1 — 26 Sites, 79,800 Synthesis Paths, and the Protocol That Changes What Federated Health Data Can Learn — conference opens; the quadratic scaling math applied to OHDSI's actual node count
- Day 1 Synthesis: OMOP Solved the Language Problem. QIS Solves the Learning Problem. — the architectural distinction that matters: standardization is solved; collaborative intelligence is not
- Day 2: The Synthesis Network Just Switched On — the DHT milestone landed during Day 2: first holder node confirmed, Ed25519 signatures live, 119 bucket topics, 168 packets
- Day 3: While Researchers Debated Federated Learning, the Network Proved It — two-node Kademlia routing confirmed cross-machine during the live conference
The math for OHDSI: 26 sites × (26-1) / 2 = 325 synthesis pairs per question asked. With the full 79,800-node network: 79,800 × 79,799 / 2 = 3.18 billion synthesis paths. The protocol generates those paths automatically. No coordination. No central aggregator. No shared data.
That's not an approximation. That's the actual formula running against the actual network count.
What the Conference Was Actually Debating
Federated learning has a known problem that OHDSI researchers know intimately.
You can train a model on distributed data without moving the data. McMahan et al. (2017) showed that. You can run OMOP queries across 26 sites without a central repository. OHDSI demonstrated that at scale.
What federated learning cannot do natively:
- Route the validated outcome from Site A to Site B without exposing Site A's data
- Build a cross-site knowledge layer that compounds over time
- Let Site A's discovery about Drug Interaction X inform Site B's treatment protocol next month without a bilateral data sharing agreement
The gap isn't privacy-preserving computation. The gap is outcome routing after the computation ends.
That's the QIS layer. The packet doesn't contain patient records. It contains a signed, structured insight: "This validated outcome, from this study design, in this population subgroup, produced this signal."
The OMOP model standardized the questions. QIS standardizes the answers.
The DHT Architecture That Ran During Rotterdam
Here's what was actually running while the conference sessions were happening:
class QISNode:
"""A holder node in the Quadratic Intelligence Swarm."""
def __init__(self, node_id: str, relay_url: str):
self.node_id = node_id
self.relay_url = relay_url
self.key_pair = generate_ed25519_keypair()
self.buckets = {} # bucket_hash -> [packets]
def post_validation_deposit(
self,
bucket_path: str,
outcome: dict,
metadata: dict
) -> str:
"""Deposit a validated outcome packet to the swarm."""
packet = {
"bucket": bucket_path,
"outcome": outcome,
"metadata": metadata,
"agent_id": self.node_id,
"timestamp": time.time()
}
signature = self.key_pair.sign(json.dumps(packet).encode())
packet["signature"] = signature.hex()
# Route via Kademlia XOR distance to nearest bucket holder
response = requests.post(
f"{self.relay_url}/deposit",
json=packet,
headers={"Authorization": f"Bearer {self.auth_token}"}
)
return response.json().get("packet_id")
def query_peer_outcomes(
self,
bucket_path: str,
min_confidence: float = 0.7
) -> list:
"""Query validated outcomes from peer nodes."""
response = requests.get(
f"{self.relay_url}/buckets/{bucket_path}/packets",
params={"min_confidence": min_confidence},
headers={"Authorization": f"Bearer {self.auth_token}"}
)
packets = response.json().get("packets", [])
return [p for p in packets if self._verify_signature(p)]
The XOR routing is what makes this Kademlia rather than just a REST API. Node A doesn't query a central server for bucket contents — it finds the closest node in the keyspace to the bucket hash and queries directly. When two nodes are running, either can serve any bucket. When 1,000 nodes are running, the network partitions automatically. No configuration. No coordinator.
The Ed25519 signatures are what makes the packets trustworthy. Any node can verify any packet without trusting the relay. The packet integrity is cryptographic, not institutional.
The Number That Matters Post-Rotterdam
The OHDSI network has 79,800 nodes. That number doesn't represent databases.
It represents 79,800 potential QIS holder nodes — each capable of depositing validated outcome packets from their local cohort studies, adverse event analyses, treatment pathway evaluations, and drug interaction signals.
The quadratic math on that network:
| Node Count | Synthesis Pairs | Unique Cross-Site Learning Events |
| 26 (Rotterdam attendees) | 325 | Per question asked |
| 1,000 (active OHDSI sites) | 499,500 | Per question asked |
| 10,000 | 49,995,000 | Per question asked |
| 79,800 (full network) | 3.18 billion | Per question asked |
Each synthesis pair is a bilateral comparison that the QIS tally uses to weight outcomes. The convergence isn't voting — it's physics. The most reproducible outcomes accumulate weight. The outliers remain visible but lose relative influence. The tally converges on what the evidence actually says.
This is why OMOP + QIS is a different argument than OMOP alone. OMOP answers: can these sites communicate? QIS answers: what do they collectively know that none of them know alone?
What Happens Next
Infrastructure: The DHT is running. Two nodes confirmed cross-machine during Rotterdam. The create-tally-holder npm package (npmjs.com/package/create-tally-holder) lets anyone run a holder node on commodity hardware — Raspberry Pi, VPS, homelab, anywhere Node 18+ runs. One command:
npx create-tally-holder my-node
The holder registers with the relay via Ed25519-signed requests, holds its partition-assigned bucket slice, and serves packets directly to clients when the central relay is unreachable. Single point of failure: eliminated.
Content: Rory's Architecture Comparisons series is now 40 articles deep, targeting every major MLOps platform — Kubeflow, Flyte, ZenML, Azure ML, H2O.ai, Comet ML, Neptune.ai, W&B, and more. Each article makes the same architectural argument in a different domain: your platform manages the model lifecycle. QIS routes what the model learned. Adjacent layers, not competing ones.
Demo: Tally (tally.qisprotocol.com) is live. Full HTTPS. Ed25519 signing. Schema-aware deposits. The next step is demo mode — real packets, real signatures, known-answer benchmarks — so a visitor can watch quadratic synthesis converge on a number that literature already documented. That's the moment QIS stops being abstract.
The Research Audience: OHDSI Rotterdam brought 400 federated health data researchers into a single building for three days. They are now back at their institutions, running their normal pipelines, depositing query results to OMOP CDMs that don't talk to each other.
The window to reach them while Rotterdam is still fresh is narrow.
This article is part of that window.
The QIS Protocol is an open standard for cross-agent outcome routing. Designed by Christopher Thomas Trevethan. Free for humanitarian and academic use. Details at qisprotocol.com.
The DHT infrastructure referenced here is live. You can inspect the relay at api.tally.qisprotocol.com. The holder node package is published at npmjs.com/package/create-tally-holder.