A trading application can parse every FIX message perfectly and still lose an order, because a restored socket says nothing about processed state. Parsing answers what a message says; the FIX session layer answers whether it arrived at all, in order, exactly once, and whether both sides agree on that. When a TCP connection drops mid-burst, when a counterparty restarts, or when a gateway goes quiet without closing the socket, the session layer detects the problem and recovers the missed messages. This article covers that machinery: the session message types, sequence number management, gap recovery, and the failure modes that only appear in production. For reference, the FIX application level message and parser requirements are covered in the article on FIX message anatomy.
The FIX protocol session layer has its own messages
A FIX session is a bidirectional, ordered message stream whose sequence numbering begins at 1 and can continue across several sequential transport connections: a broken TCP connection and a new socket can belong to the same session. That distinction between session and connection is what the session vocabulary manages, and each message exists because a specific failure needs handling:
|
Message |
Role |
What breaks if it is mishandled |
|
Logon (35=A) |
Opens the session and proposes the heartbeat interval (HeartBtInt, 108); initiator connects, acceptor authenticates and confirms, and both sides compare sequence numbers with expectations |
Sessions that half-open, or resume with mismatched state |
|
Heartbeat (35=0) |
Proves liveness during quiet periods and answers a TestRequest |
Dead connections held open through trading opportunities |
|
TestRequest (35=1) |
Forces a Heartbeat carrying a matching TestReqID (112), turning silence into a correlated check |
Premature disconnects on a slow counterparty, or late detection of a gone one |
|
ResendRequest (35=2) |
Asks for retransmission of a range bounded by BeginSeqNo (7) and EndSeqNo (16) |
Missed executions treated as if they never happened |
|
SequenceReset (35=4) |
Advances the expected number over a gap-filled range, or forces synchronisation in reset mode |
Recovery that skips real business messages, or sessions stuck unrecoverable |
|
Logout (35=5) |
Closes the session through an orderly exchange |
Ambiguity over what the counterparty processed before the close |
Everything else, orders, executions, quotes, rides as application messages on top, and both classes consume the same sequence space. The OnixS FIX Dictionary documents the full session protocol per version, including the FIXT.1.1 session layer used with FIX 5.0 and later.
Sequence numbers carry the session's memory
Every message carries a sequence number (MsgSeqNum, tag 34), and each side tracks the next number it will send and the next it expects. Those counters must survive connection loss so the parties can compare state at the next Logon, and they put four obligations on an implementation.
Gap detection. A message above the expected number means messages were missed: the receiver sends a ResendRequest and defers newer traffic until the gap resolves. The protocol expects a garbled message to be disregarded; the next valid message then exposes the gap. A number below expectation is different: with PossDupFlag (43) set it marks a retransmission the receiver may already have processed, and without that flag it signals invalid sequence state and, by default, closes the connection.
Duplicate handling. Retransmissions carry PossDupFlag=Y, OrigSendingTime preserving the first transmission time, and an updated SendingTime (52). Whether the message was processed the first time is a business-layer check: code that treats PossDupFlag as an instruction to discard can lose an event that failed before the first application commit.
Resend semantics. During a resend, administrative messages are not retransmitted; the sender replaces them with a SequenceReset in gap-fill mode (GapFillFlag, 123, set to Y), advancing NewSeqNo (36) over numbers it will not resend. Reset mode (GapFillFlag=N) forces the expected number to NewSeqNo and abandons whatever sat in the gap: an exceptional repair, distinct from the agreed clean start both sides can take with ResetSeqNumFlag (141) = Y on Logon. An unmatched reset can hide unresolved orders, so it needs counterparty agreement and reconciliation.
Restart survival. Two crash boundaries create business risk: a sender that increments its outbound counter but loses the message record cannot satisfy a later resend, and a receiver that applies an execution report but loses its updated inbound counter risks applying the same fill twice when the retransmission arrives. Sequence state, outbound history and application commits need coordinated session persistence.
What breaks in production
Silent disconnects. TCP can hold a socket "open" long after the far end has gone. The heartbeat and TestRequest cycle exists for this, and the TestReqID correlation is the part worth testing: only the Heartbeat carrying the matching identifier answers an outstanding TestRequest, and a missing answer should end in Logout and transport termination. Timer configuration is a judgement: too long and dead sessions linger, too short and a busy counterparty gets cut off.
Clock validation is a separate control. SendingTime on an inbound message must fall within the agreed tolerance of the receiver's synchronised UTC clock; a value outside it draws a Reject with SessionRejectReason (373) = 10, then Logout. Monitor elapsed-time liveness and UTC synchronisation as two different alarms, because clock drift fails sessions that every heartbeat says are healthy.
Restart and reconnect. Reconnection restores the transport, reloads persisted state and completes session recovery in both directions before the business layer can trust its view of in-flight orders. Session stores range from file to in-memory to asynchronous to pluggable, and in-memory is only valid where counterparty rules permit state discard; test the chosen store under abrupt termination. Venues also impose session schedules with defined reset points, so production runs a scheduler at the venue's boundaries.
FIX drop copy and post-trade feed sessions. Many firms consume a FIX drop copy feed, a separate session on which a venue mirrors execution activity for risk, compliance and back-office systems, alongside related read-only sessions such as trade capture and private order feeds that report executed or open activity rather than accepting new orders. CME's iLink FIX Drop Copy sends carbon copies of execution reports, acknowledgements and trade busts for one or more order-entry sessions, with its own Enhanced Resend Request and Convenience Gateway and Market Segment Gateway session types. ICE's FIX Trade Capture and FIX Private Order Feed report real-time, and on request historical, trade and order activity across WebICE and FIX Order Servers, each running standard FIX session maintenance (Logon, Logout, Test Request, Heartbeat, sequence gap-fill) plus a scheduled session reset during the exchange's daily maintenance window. Nodal Exchange's FIX Trade Capture feed serves the same role for its North American energy market participants. All of them run the same session layer with their own CompIDs, schedule and sequence history, and deserve the same recovery discipline: sharing counters with an order-entry connection, resetting a feed without venue approval, or missing a venue's own scheduled reset window cuts holes in a control record even while the trading session stays healthy.
A forced-failure acceptance sequence turns these from war stories into tests:
- Establish the session with known counters and record the accepted Logon values.
- Introduce an inbound gap and confirm the ResendRequest range, deferral policy and recovery order.
- Retransmit an application message with PossDupFlag=Y before and after its first business commit, and request a mixed range of session traffic and a stale application message, inspecting the retransmissions against the gap fill.
- Break the TCP connection without Logout, reconnect, and confirm both sequence series continue rather than restart.
- Terminate the process at controlled points around message storage, sequence persistence and application commit.
- Delay peer traffic until TestRequest fires and confirm only the Heartbeat with the matching TestReqID satisfies the check.
- Repeat the gap and restart tests on every configured order-entry, acceptor and drop copy session.
The evidence is the audit trail, persisted state, business result and counterparty-visible sequence; a connection-status flag supplies none of it.
Detecting TCP trouble before the counterparty does
Some failures sit below the FIX session entirely. A connected socket can carry an ordered byte stream while receive queues build between the network interface and the engine, from slow consumption or host contention, and the delay grows before any liveness timer expires. The OnixS reference on detecting TCP congestion describes how the OnixS SDKs can record when data reaches the host, using a network-interface hardware timestamp where supported, and compare that against delivery to the application. A growing interval is the early signal; track socket state, FIX liveness, sequence gaps and receive-path delay as separate signals.
The OnixS FIX Engine SDK: engineered for production-grade integrity
Everything above is implementable from scratch, and all of it must be correct before a single order flows. This is the work a FIX engine absorbs, whether the requirement is a C++ FIX engine, a Java FIX engine, a .NET FIX engine or a C# FIX engine on .NET Framework. The OnixS FIX Engine SDKs implement the session layer in four editions: the OnixS FIX Engine SDK - .NET implementation, the OnixS FIX Engine SDK - .NET Framework implementation, the OnixS FIX Engine SDK - C++ implementation and the OnixS FIX Engine SDK - Java implementation. They cover the connection lifecycle for initiator and acceptor roles, heartbeat and test-request timers, gap detection with resend and gap-fill logic under application control, and persisted sequence and message state with synchronous or asynchronous storage for restore after fail-over. The distributions include pluggable session state and message storage, a session scheduler, and FIX initiator/accepter client application examples supporting the full FIX implementation of session layer standards. The division of labour is the point to evaluate: the engine owns the protocol mechanics, while the firm retains counterparty rules, storage durability, resend policy, duplicate business handling and the acceptance evidence, across every venue FIX API it connects.
FIXP and session continuity in newer binary interfaces
The session problem does not end with classic FIX. FIXP, the FIX Performance Session Layer, is the FIX Trading Community's lightweight session protocol for high-performance contexts: independent of both transport and message encoding, with per-flow delivery guarantees such as recoverable, exactly-once delivery with retransmission, though venues pair it in practice with binary encodings such as Simple Binary Encoding. CME iLink 3 and B3 Binary EntryPoint build on FIXP, with Negotiate and Establish in place of Logon, NotApplied for client messages the gateway did not apply, and retransmission capped at 1,000 outstanding messages within the trading session. ICE Binary Order Entry does not use FIXP; it addresses the same session-continuity problem with its own design, discovering its gateway through the BUS and BGW workflow and running independent inbound and outbound counters.
Make the forced-failure sequence the production gate
Session behaviour has no online sandbox; the way to evaluate an implementation is to run one against your own disconnect, restart and resend scenarios. Run the acceptance sequence above with your session schedule, persisted store and duplicate-handling rules, run on the target production deployment architecture and platform so reconnect and failover timings hold up in practice, and keep the session out of production until the evidence accounts for every sequence number across reconnect and restart. Request a free evaluation of the OnixS FIX Engine SDK for your platform: .NET, .NET Framework, C++, or Java.
