---
title: FIX Sessions and Recovery
description: Maintain FIX sessions, restart market data from fresh state, and recover order-entry sequence gaps.
---

Market data and order entry use separate FIX sessions. Both use FIXT 1.1 session messages with FIX 5.0 SP2 application messages. Each session has its own sequence numbers and recovery state.

This page explains session behavior. The [Header and Trailer](/api-reference/fix/header-and-trailer) and [Session Messages](/api-reference/fix/session-messages/logon) references define the fields. See [FIX Message Layouts](/reference/fix-message-layouts) for field presence and repeating-group rules.

## Establish a Session

Complete the [Logon(A)](/api-reference/fix/session-messages/logon) exchange before sending application messages. Use a heartbeat interval of at least 30 seconds, such as `HeartBtInt(108)=30`.

If your Logon(A) requests a shorter heartbeat interval, the exchange answers with Logout(5) and closes the connection.

For market data, start fresh on every connection using the procedure in [Reconnect to Market Data](#reconnect-to-market-data). You do not need to preserve sequence numbers across connections.

An order-entry FIX session can continue across network connections. Keep that session's sequence state when reconnecting; opening a new connection is not a reason to start its sequence numbers over. Sequence recovery and an explicit reset have different consequences for order entry, described below.

## Maintain a Session

Send [Heartbeat(0)](/api-reference/fix/session-messages/heartbeat) when no other outgoing traffic has been sent during the heartbeat interval. Ordinary traffic also keeps the session active.

Answer each [TestRequest(1)](/api-reference/fix/session-messages/test-request) with Heartbeat(0) carrying the same `TestReqID(112)`. An unrelated heartbeat does not answer that test request. Handle these messages even while processing a busy application stream.

The exchange tests a session that stops responding and disconnects it if it remains unresponsive. Market-data sessions may also be disconnected when a subscriber falls too far behind. A lag-related disconnection can close the connection without completing a Logout(5) exchange. Follow [Reconnect to Market Data](#reconnect-to-market-data) to restore subscriptions; the exchange does not replay a market-data backlog.

## Track Sequence Numbers

Maintain the next outgoing and expected incoming `MsgSeqNum(34)` independently. Session and application messages share the sequence in each direction. A retransmitted message retains its original sequence number.

| Incoming sequence | Action |
| --- | --- |
| Matches the expected number | Process the message and advance the expected number. |
| Higher than expected | Hold later messages until the gap is resolved. For market data, reconnect and rebuild state. For order entry, recover the missing messages. |
| Lower than expected | Treat it as a possible retransmission only when it is marked as a duplicate. An unmarked lower sequence number can end the session. |

## Reconnect to Market Data

After a lag-related disconnection, wait at least 60 seconds before reconnecting; earlier Logon(A) attempts are rejected.

On every market-data connection, send Logon(A) with `ResetSeqNumFlag(141)=Y` and `MsgSeqNum(34)=1`. The exchange confirms the reset in its Logon(A). Sequence numbers then increase for the duration of that connection.

After logout or connection loss, the session's book, catalog, and trading-status subscriptions are removed. After completing the fresh logon:

1. Reissue the subscriptions you still need.
2. Rebuild each book from its initial [MarketDataSnapshotFullRefresh(W)](/api-reference/fix/market-data/messages/market-data-snapshot-full-refresh).
3. Apply subsequent updates according to that subscription's refresh mode.

Missed market-data messages, including trades, are not replayed. A fresh book snapshot restores the current book; it does not recover missed trades. If a sequence gap occurs during a connection, reconnect and rebuild state before applying further incremental updates.

## Recover Order Entry

Order entry can replay retained application messages. Retention is bounded, so a requested range may contain messages that are no longer available. The exchange gap-fills those numbers and session messages instead of returning their original payloads.

Use [ResendRequest(2)](/api-reference/fix/session-messages/resend-request) to request a missing range. `BeginSeqNo(7)` identifies the first missing number and `EndSeqNo(16)` the last requested number. `EndSeqNo(16)=0` requests the range through the most recently sent message.

The exchange may answer with retransmitted application messages, [SequenceReset(4)](/api-reference/fix/session-messages/sequence-reset) gap fills, or both. A gap fill advances the expected number to `NewSeqNo(36)`, which is the next expected number, not the last skipped number. It supplies no application payload for the skipped range.

Retransmissions carry `PossDupFlag(43)=Y`, retain the original `MsgSeqNum(34)`, and identify the original transmission time in `OrigSendingTime(122)`. `SendingTime(52)` reflects the retransmission. Apply duplicate detection before applying a retransmitted application's effects again. When the exchange requests messages from your session, let your FIX engine resend retained application messages and gap-fill skipped session traffic.

Distinguish retransmission from the first delivery of a report held during downtime:

| Delivery | Sequence and duplicate handling |
| --- | --- |
| Retransmission | A previously sent message returned during recovery. Retains its original `MsgSeqNum(34)` and carries `PossDupFlag(43)=Y` and `OrigSendingTime(122)`. |
| Held report | First delivery of an execution or RFQ report held while the session was disconnected. Sent after logon as a new message with a newly assigned `MsgSeqNum(34)`, without `PossDupFlag(43)=Y`. Held reports are delivered oldest first, ahead of newer reports. |

A connection loss does not establish that an order or RFQ action failed. Recover and reconcile the resulting reports before deciding whether to send another action. Creating another order to replace an uncertain request can create a second order.

A gap fill is not an order-status report and does not prove that no trade occurred. If recovery leaves an order or execution unresolved, contact support to reconcile it before retrying.

## Reset an Order-Entry Session

An explicit reset starts a new sequence history. Logon(A) with `ResetSeqNumFlag(141)=Y` resets both sequence counters to 1 and clears retained messages from the old replay history. Logon(A) itself uses the first sequence number; subsequent messages continue from there. A reset is not a substitute for recovering missing execution reports.

Coordinate an order-entry reset with support when the two sides cannot reconcile sequence state. Do not reset an order-entry session merely because a connection dropped. Routine market-data reconnects use the reset-on-logon procedure above and do not require a coordinated reset.

Reports held for an order-entry session that have not yet been sent are separate from its retained replay history. A sequence reset does not discard those held reports; they are delivered as new messages after logon.

## End a Session

Use [Logout(5)](/api-reference/fix/session-messages/logout) to end a session cleanly and allow the logout exchange to complete before closing the connection. A clean logout and an unexpected connection loss both remove market-data subscriptions.

Order-entry cancel-on-disconnect is off by default. When enabled for the session, it requests cancellation of that session's resting orders after either clean logout or connection loss. Do not treat disconnection as confirmation of cancellation: cancellation can fail or remain incomplete, including during a service interruption. Reconcile the resulting order reports after reconnecting.
