The cor format and cor://
cor is coraine's binary serialisation of a tree - a request, a response, an entity - and cor:// is the broker's binary API: the same trees, framed for a long-lived TCP connection. A request that arrives over cor:// is already a tree, so it goes into the same service routines an HTTP request does, without a JSON parse, and its response goes back as a tree.
The full specification - the encoding, the framing, multiplexing, the numbers - is in the details. How it came about: history.
When to use it
- Between brokers. A registration whose endpoint is
cor://host:portmakes forwarding to that context source go over cor:// instead of HTTP: no JSON rendered or parsed on either side of the hop. - A client that speaks it. corTools'
corRequestsends requests over cor://, one at a time or in its load mode. - Not for what only HTTP carries: a body that is not JSON, a text answer, HEAD.
cor:// is a communication protocol, not a bridge: it reaches the broker's API, both as a client (forwarding) and as a server (the listener).
How to turn it on
| the listener | --corPort <port> - a cor:// listener next to the HTTP one (0, the default: off) |
| forwarding | a context source registration with "endpoint": "cor://host:port" |
| the functests | COR_TRANSPORT=cor corTest ... - every test that can runs over cor:// (each broker on its HTTP port + 1000); doc/testing.md |
| the benchmark | test/perf/corChain.sh <http\|cor\|cor-all> - three brokers chained |
Compiled out: make COR_WITH_COR_PROTOCOL=0 (or coraine-build --features COR_PROTOCOL=OFF) builds a
broker without cor:// - corRest without its cor:// server and client (corRestCor.c), the broker without
--corPort and without the cor:// forwarder: 24 640 bytes less (stripped, 2026-10-13). --version and
GET /build say COR_PROTOCOL 0 / false. A registration whose endpoint is cor:// is accepted and not
forwarded to: the answer carries NGSILD-Warning: 299 <host:port> "The registration endpoint's scheme is not
supported by this broker" (cor_not_in_this_build.test). The cor format stays: corDB's log and history are
written in it.
What it is
- One format, three uses: cor://, and the bodies of the corDB log and snapshot records.
- The codec knows nothing about NGSI-LD. It lives in corTree and serialises any tree; corNgsild supplies, through callbacks, which names are core terms and which objects are attributes.
- Zero-copy on read - strings keep their NUL and point into the read buffer; skippable - objects and arrays carry their byte length; little-endian, no byte swapping.
- Small: core terms by id, an attribute's type folded into its node, IRIs split into a namespace and a local name, a string table - and on cor:// the tables live as long as the connection.
- Every frame starts with the magic
C0 4F 52 01, which no text or HTTP request can begin with: a wrong peer is refused at once. - Multiplexed: any number of requests in flight on one connection, answered in the order they
finish, run on the event loops' coroutines (
doc/coroutines.md). A distributed operation fanned out to several cor:// sources has them all in flight at once. Withmongoca request that waits is served on a thread of its own, one at a time.
Key numbers
Three corDB brokers chained A -> B -> C, a GET on A, 16 connections; each broker on two cores,
built-in server, release build with PGO, deep idle states, two runs (2026-10-02,
details ยง 6):
| Entity | Mode | req/s | p99 |
|---|---|---|---|
| 4 attributes | HTTP all the way | 42,992-44,418 | 0.85-2.23 ms |
| 4 attributes | cor:// between the brokers, HTTP client | 79,991-80,764 | 333-346 us |
| 4 attributes | cor:// all the way | 91,490-91,945 | 235-237 us |
| 20 attributes | HTTP all the way | 24,415-25,127 | 1.26-1.30 ms |
| 20 attributes | cor:// between the brokers, HTTP client | 39,703-40,871 | 784-810 us |
| 20 attributes | cor:// all the way | 50,988-53,642 | 398-402 us |
One broker, no forwarding: cor:// and HTTP are at parity on throughput (~145,000 against ~142,000 req/s with 16 connections), the p99 under load 209 us against 4-9 ms. On the wire, with the NGSI-LD callbacks, 71 % of minimised JSON over 660 test payloads.