The FIX Trading Community realised that its message encoding was no longer fit-for-purpose for high-performance trading. It came up with the Simple Binary Encoding (SBE) standard to balance the needs of latency versus bandwidth utilisation. We look at how the market data interfaces at the CME Group were implemented with SBE.
The low latency challenge
Circumstances change in unforeseen ways, no matter the brilliance of planners. What should you do about a protocol that is wildly successful for exchanging financial information around the world and yet is not fit-for-purpose for new use cases? That is the question that challenged the FIX Trading Community regarding high performance trading. FIX Protocol was created by the non-profit organisation 20 years ago to exchange trading information between US stock brokers. It became a standard in the industry as its usage extended to more asset classes, including futures and options, fixed-income and other instruments. At the same time, it covered other facets of the business beyond order routing, including market data dissemination, securities reference data and post-trade processing. FIX then spread geographically from the US to Europe and Asia. FIX was able to meet all these various scenarios because they were expansions of business semantics. The new challenge was high-performance trading – a technical challenge to deliver messages with latencies measured in microseconds and even nanoseconds.
To be clear, the FIX Protocol is an industry standard, not a software implementation. Implementations need to follow the standard to interoperate, and there are numerous open-source and proprietary implementations of FIX. However, the composition of a standard has a strong influence on whether high performance is attainable. Unfortunately, the original FIX protocol design created barriers that prevented achieving really low-latency performance.
ASCII Protocol doesn’t cut it
To see why Simple Binary Encoding is part of the solution to the low-latency challenge, let’s first take a tour of the original FIX Protocol. The first significant characteristic of the original FIX Protocol is that it is all-in-one. It specifies message encoding, rules for message exchange (session establishment and check-pointing) and business semantics, such as how order and execution quantities are managed. In the terminology of the Open Systems Interconnection conceptual model (OSI), it is the application layer, the presentation layer and the session layer, all rolled up in one big ball of wax. The problem with a monolithic protocol is that there is no substitutability for a better solution offered at one layer. Separation of layers is clearly desirable and technical standards recently created by the FIX Trading Community aim to do just that. SBE was created to replace the presentation layer, no more and no less. The application layer of FIX that is familiar to thousands of users is retained. It is a requirement for SBE to be able to express existing FIX messages but also to make it possible to optimise them for performance. (A performance session layer is also under development but this is a discussion for another day.)
The second aspect of the original protocol that one needs to understand is why its message encoding is no longer fit-for-purpose. The first problem is that although FIX has about 20 data types, they are all encoded as human-readable ASCII text. Text is acceptable for fields like an account identifier and the like, but numeric data, timestamps and so forth cannot be processed directly by computers. To calculate a price or time difference, text must first be converted back into native binary types. Then, to put the data back in a response message, the computer must convert the binary types back to ASCII text. This is a waste of processing time, especially for time and calendar functions, and it has no place in a high-performance system. Some FIX applications spend up to 80% of their CPU budget in translation of data type representations!
Another problem with the original FIX message format, known as ‘tag=value encoding’ (see an example in Table 05PN), is that message encoding is highly variable. It was designed for a high degree of optionality. For example, ‘expiration date’ is an optional field on an order message, because it is only required for derivatives, but not equities. FIX also has a concept of conditionally required fields. A stop price field is only required in an order message if the order type is stop or stop-limit, but is not required otherwise. Moreover, field order within a message is largely non-deterministic. Price and then quantity is as equally valid as quantity and then price. Since the message layout is non-deterministic, it is necessary to convey metadata to identify each field in the message. The field tag is small for each field, but the combination of field tags, field delimiters and a verbose message header result in a typical message size of hundreds of bytes.
Lastly, string fields in tag=value encoding are all of variable length. Even when the receiver of a message has an internal storage limit on string length, such as a database schema, there is no way to express that limit in tag=value encoding. All these characteristics resist performance optimisation. High variability defeats CPU optimisations such as branch prediction and memory pre-fetch. Additionally, high variability of message layout in memory and large message size tends to cause cache misses that can stall a CPU. The variability also makes the encoding unsuitable for hardware implementations such as FPGA.