Binary Messaging
This page explains the byte-oriented transport of Celeris. You control the encoding, and compact formats can reduce payload size and bandwidth.
Less to send. More room to build.
Celeris carries application payloads as bytes. You choose how to encode and decode them: MessagePack, Protobuf, a custom format, or JSON encoded as UTF-8. You control the format and the bytes. Celeris does not require a JSON conversion.
Compact formats can reduce payload size, depending on the format and the workload. They can also reduce the work to encode and decode frequent messages. Smaller messages mean less payload bandwidth at the same delivery rate. Where infrastructure charges depend on transferred bytes, that can reduce costs. A smaller payload does not guarantee a lower Celeris bill.
Binary transport does not automatically compress JSON or convert objects into MessagePack. Binary encoding and compression are separate operations. The application selects its serializer. The SDK specification places serialization above its byte API and does not require a serialization library.
One message, measured three ways
Each encoding carries the same values for one position message:
{ "playerId": "p1", "x": 142, "y": 88, "action": "move" }
| Encoding | Payload size |
|---|---|
| Minified JSON, UTF-8 | 48 bytes |
| Standard MessagePack | 32 bytes |
| Protobuf, with the schema below | 15 bytes |
The MessagePack measurement used @msgpack/msgpack 3.1.3 with the default encoding, without extensions or shared dictionaries. The decoded values are identical. The counts exclude Celeris protocol, WebSocket, TLS, and network overhead. The measurement applies no compression. The Protobuf measurement used protobufjs 8.8.0 with the schema below. One million payload deliveries carry 48 MB, 32 MB, or 15 MB of payload data respectively (decimal units).
syntax = "proto3";
message PositionUpdate {
string playerId = 1;
uint32 x = 2;
uint32 y = 3;
string action = 4;
}
JSON and the MessagePack map carry field names in each message. Protobuf uses field numbers instead. Both ends must already have the same schema. The 15-byte count excludes schema distribution. All three encodings decode to the same values for this example.
This is one example, not a typical reduction or a speed benchmark. Different data, numeric representations, encoders, and compression settings can change the result. Binary can also be larger.
Encode and decode in your application
This standalone JavaScript example uses the independent MessagePack library. It shows serialization before the application passes the bytes to the SDK.
import { encode, decode } from "@msgpack/msgpack";
const position = { playerId: "p1", x: 142, y: 88, action: "move" };
const jsonBytes = new TextEncoder().encode(JSON.stringify(position));
const binaryBytes = encode(position);
console.log(jsonBytes.byteLength); // 48
console.log(binaryBytes.byteLength); // 32
console.log(decode(binaryBytes)); // the original values
Your application passes encoded bytes to a segment's publish(). It decodes received bytes with the same codec. Follow Payload formats for SDK text/JSON helpers, validation, and createPayloadCodec.
For Protobuf, encode with your schema. Decode with the compatible schema at the receiver. Celeris transports those bytes. It does not supply your application schema or decoder.
Measure the work that matters
Compare representative production payloads, not only one small object. Record the encoded byte size, the time to encode and decode, allocations, and the runtime and library versions. Include warm-up runs and repeated measurements. A compact representation can reduce the computation work. But an optimized native JSON implementation can outperform a particular binary codec.
Measure end-to-end performance separately. Smaller payloads are not proof of lower network latency or higher service throughput. Compression, fan-out, message rate, and connection traffic also affect actual bandwidth.
JSON remains a valid choice
JSON can be useful for interoperability and lower-frequency messages. It is also easy to read when you debug. Encode it with TextEncoder in your application. Decode it with TextDecoder and JSON.parse. There is no need to change formats before you have a reason to do so.
Binary payloads do not establish ordering, deduplication, or delivery receipts. See Message Ordering and Reconnection and Recovery for those boundaries. See pricing to explore payload volume at your delivery rate.