Why CoralFIX is very fast and easy to use?

In this article we list the main reasons that make CoralFIX a very fast and easy to use FIX engine.

  • Network I/O: The most important part of a FIX engine in terms of performance is the network I/O library. That’s because FIX parsing can be done in nanoseconds while TCP latencies are in microseconds. So it is not enough to be super fast when parsing the FIX message while your bottleneck may be in the network I/O. In addition to parsing a FIX message very fast (in nanoseconds), CoralFIX uses CoralReactor under the hood, which brings our years of experience with Java NIO and network I/O. We provide our own selector implementation which is much faster than the standard JDK implementation.

  • Non-Blocking I/O: CoralFIX is built from the ground up to use non-blocking sockets through Java NIO selectors. That has several advantages over blocking sockets:

    • Ultra-Low-Latency: Blocking sockets are very slow and can block for any arbitrary amount of time when you try to send and receive data. Non-blocking sockets on the other hand never block and sending/receiving data becomes as fast as simply copying data to/from the underlying native socket buffer.

    • Scalability: The same CoralFIX thread can not only handle hundreds of clients but it can also handle clients, servers and any mix of the two. For blocking sockets on the other hand, the old one-thread-per-client approach must be used, which is very hard to scale when the number of threads surpasses the number of available CPU cores. Thread pools or any other trick will not match the flexibility and scalability of non-blocking sockets running inside the same super-fast thread.

    • Simplicity: The single-threaded approach of CoralFIX eliminates all the issues that are so common to multithreaded programming. You suddenly don’t have to worry about thread synchronization, lock contention, race-conditions, deadlocks, thread starvation, context switches and many other pitfalls that arise when different threads need to coordinate and share state. Because CoralFIX clients and servers run inside the same thread, all these problems disappear and you can re-allocate your brain power to other tasks.

  • Zero Garbage: All Coral Blocks components produce zero garbage for the GC in the critical path. With CoralFIX you are able to send/receive billions of messages without ever producing any garbage. No GC interruption, ever!

  • Zero Depedencies: At Coral Blocks we use Java as a syntax language. Our libraries have zero external dependencies and we don’t even rely on the JDK standard libraries. With CoralFIX you have total control over the critical path.

  • Zero Copy: When parsing a ByteBuffer into a FixMessage object, CoralFIX does not copy any bytes or create any objects. The resulting FixMessage object is backed up by the same ByteBuffer that was parsed. The parsing process simply delimits the tags and values of the FIX message. Moreover all values are lazy parsed, in other words, a price value won’t be parsed to a double until you explicitly call getDouble(FixTags.Price). Or you can call getByteBuffer(FixTags.Price) to return your value delimited in the original ByteBuffer, without any parsing.

  • Thread Affinity: Although not a requirement, it is recommended that you pin your critical threads to dedicated cpu cores. CoralFIX supports thread affinity out-of-the-box and can pin your critical threads to the cpu cores you specify. To pin your critical threads, all you have to do is pass the cpu core id in the command-line options below:
  • -DnioReactorProcToBind=CORE_ID 
    -DlogProcToBindAsyncThread=CORE_ID
    -DfixStoreProcToBind=CORE_ID
    


  • Kernel Bypass: CoralFIX is fully compatible with kernel bypass. We have the expertise with OpenOnLoad from SolarFlare and can help you with the setup/config to bypass the kernel and go straight to the network card buffers to save extra microseconds.

  • Audit Logging: Audit logging is a necessity for production FIX clients and servers. CoralFIX supports audit logging out-of-the-box and can asynchronously audit log a message in nanoseconds. To audit log all messages from your fix connection, all you have to do is:
  • config.add("auditLog", true);
    


  • Message Persistence: Although not always enforced, the FIX protocol specifies message retransmission for gap fills. When that’s in place, all application FIX messages sent must be persisted. CoralFIX supports messages persistence and retransmission out-of-the-box and can asynchronously persist application messages to disk in nanoseconds. To support persistence and to make your FIX client or server automatically retransmit messages through gap fills, all you need to do is:
  • config.add("supportPersistence", true);
    


  • Sequences Persistence: CoralFIX persists both inbound and outbound sequences to disk in a asynchronous way, without introducing any latency to the FIX client. That’s important if your FIX client is restarted so it can remember that last sequences it used. To tell CoralFIX to persist the sequences to disk, all you have to do is:
  • config.add("persistSequences", true);
    


  • FIX Versions: CoralFIX supports all FIX versions. To specify the version you want to use, all you have to do is:
  • config.add("fixVersion", FixVersions.VERSION_44);
    


  • FIX Session Protocol: CoralFIX makes all the FIX session protocol details transparent to the developer. That means you don’t have to worry about sequences, resend requests, sequence resets, gap fills, logon, logout, heartbeats, test requests or any other low level FIX detail. With CoralFIX you only focus on your application logic. You can even start a FIX client with few lines of code:
  • NioReactor nio = NioReactor.create();
    		
    MapConfiguration config = new MapConfiguration();
    config.add("fixVersion", FixVersions.VERSION_44);
    config.add("senderComp", "testClient");
    
    Client client = new FixApplicationClient(nio, "localhost", 45451, config);		
    client.open();
    
    nio.start();
    


  • FIX Session Timers: CoralFIX supports session timers out-of-the-box so you can synchronize your FIX session with the exchange hours of operation. You can set daily and weekly timers to start or stop your FIX connection and optionally reset the sequences (defaults to true). To set a timer all you have to do is:
  • // add a start session timer daily at 14:30:00 EST
    config.add("startSessionTimer", "D-EST-14:30:00");
     
    // add a stop session timer weekly on Sunday at 16:00:00 EST
    config.add("stopSessionTimer", "W-SUNDAY-EST-16:00:00");
    


  • High Level API: CoralFIX provides a high-level and easy-to-use API based on our vast experience writing several different FIX trading gateways and market data feeds for all kinds of markets. We are constantly improving the API based on our customers feedback and our own research to make it even easier to understand and use. Below an example of how you would send a message from a CoralFIX client:
  • // Get a FIX message ready to be sent out, with sequences, header and everything taken care for you
    FixMessage outFixMsg = getOutFixMessage(MsgTypes.NewOrderSingle);
    
    // Add any kind of value as a tag
    outFixMsg.add(Price, 50.34);
    outFixMsg.add(ClOrdID, "A123");
    outFixMsg.add(Side, '2');
    
    // Add a repeating group
    FixGroup partyIds = outFixMsg.createGroup(NoPartyIDs);
    partyIds.nextElement().add(PartyID, "BLAH").add(PartyIDSource, 'D').add(PartyRole, 54);
    partyIds.nextElement().add(PartyID, "TRD").add(PartyIDSource, 'D').add(PartyRole, 36);
    
    // Send out the message to the client
    send(outFixMsg);
    


  • Benchmarks: Our clients can modify and run our benchmark source code on their own environment to access the performance numbers. We publish our numbers as a reference but we encourage our clients to benchmark CoralFIX themselves. They have been doing that and reporting back results that they are unable to get through other FIX engine alternatives, even in C++. In our lab, we are able to go as low as 4.8 micros for the one-way latency to send a FIX message from a client to a server over loopback. We have also used tcpdump and Wireshark to measure the tick-to-trade latencies and they are around 8 micros.

  • Release Early, Release Often: We work very close to our customers and we are constantly listening to their feedback for improvements and new features. We have a quick release cycle and we release often to incorporate our customers needs as soon as they ask for them.

  • Satisfied Customers: CoralFIX has been used in production by small and big companies for years with great results. Our customers are not only happy with better performance numbers, but they are also able to complete and deploy their projects more quickly, increasing their productivity and reducing time-to-market.


Conclusion

Although it is important for a FIX engine to be as fast as possible, and we got that covered through fast parsing and networking, at Coral Blocks we believe that ease of use is even more important. Not just CoralFIX but all of our components must be very easy to understand, integrate and use. Our licensing model also allows us to have a commitment to our clients in providing first-class support and to share our know-how throughout the license period. We are passionate about what we do and we enjoy working side-by-side with our clients to bring outstanding results.