---
title: "Equities and Options Connectivity"
book: "Networks, Hardware and Trading Infrastructure"
subject: quant
language: en
chapter: 22
exercises: 8
source: https://one-course.com/books/quant/14/en/chapter/22-equities-and-options-connectivity
---

# Chapter 22 — Equities and Options Connectivity

A firm that wants the whole U.S. options market must take a consolidated feed split across 96 multicast lines, sized by its operator for bursts rather than averages, and send its quotes through ports whose number and message budgets it cannot exceed. The feed’s operator publishes its capacity in 10-millisecond peaks; the busiest millisecond of July 2026 held 0.35 million messages, about $135\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ on the wire for one millisecond. Connectivity for options is capacity planning before it is latency.

Book 1 introduced direct feeds, the securities information processors and sponsored access; Book 11 the mass quote, the message throttle and the market access rule; Book 13 the feed handler. This chapter turns them into numbers of ports, links and cores: the port types a venue sells, the bandwidth of the consolidated options feed, the risk layer that sits between a sponsored firm and the venue, and the engineering of quote traffic. The plan is computed by `firm.portplan` from the operator’s and the venues’ dated documents, with a simulated busy minute labelled as such.

## 22.1 Gateway and port types

**Definition 22.1 (Order-entry port).**

An *order-entry port* is one logical connection, with its own session and credentials, through which a member sends orders, quotes or cancels to a venue’s gateway and receives their acknowledgements; venues sell ports by type (order entry, bulk quoting, purge or mass cancel, drop copy) and charge and limit them per port.

A venue’s connectivity has two layers. The physical one is chapter 9’s: a [cross-connect](https://one-course.com/books/quant/14/en/chapter/9-colocation-products-and-how-they-are-sold#def-nw-colocation-products-and-how-they-are-sold-mmr), a port speed, a [colocation cabinet](https://one-course.com/books/quant/14/en/chapter/9-colocation-products-and-how-they-are-sold#def-nw-colocation-products-and-how-they-are-sold-cabinet). The logical one is the ports: sessions on the gateway, each with a type, a fee and rules. Options venues separate quoting from ordinary order entry, because a market maker’s quotes are the bulk of their inbound traffic.

The MIAX Express Interface shows the pattern. A Full Service port accepts every message, bulk quotes included; a Limited Service port every message except bulk quotes; a Priority Mass Cancel port only mass cancels, processed ahead of the firm’s other traffic. Each matching environment (a “cloud”) trades all options on a set of underlyings, and a firm gets two Full Service and twelve Limited Service ports per cloud: to quote every underlying, it connects to every cloud. On Nasdaq’s Phlx the quoting interface is SQF, for quotes, immediate-or-cancel orders and auction responses; the exchange’s own filing says one port suffices to meet a market maker’s quoting obligations, and its fee schedule caps a market maker at 250 of them.

**As of September 2026 — Quoting ports on U.S. options exchanges, from the venues’ filings and specifications.**

- Phlx: SQF port $1 185 a port a month from January 2026, 10% to 50% off by market-maker volume share; at most 250 SQF ports per market maker. BOX: $1 000 a month for all ports. MIAX: MEI fees by classes quoted, up to $20 500 a month for over 100 classes. NYSE Arca and NYSE American: $510 a port for ports 1 to 40, $170 from port 41. Cboe EDGX Options: $750 a logical port (all as compared in Phlx’s September 2025 filing).
- MIAX MEI: 2 Full Service and 12 Limited Service ports per cloud; a Simple Bulk Quote message carries up to 50 single-sided quotes, 51 bytes of header and 15 bytes a quote; the specification calls MEI “a synchronous quoting interface”.

Twenty-four ports cost $28 440 a month on Phlx, $18 000 on EDGX, $12 240 on Arca or American, $1 000 on BOX, and on MIAX the fee depends on the classes, not the ports ($20 500 for all of them). The drop copy and the purge ports come on top. Fees differ by a factor of twenty-eight for the same count of sessions: the count is a design choice, and the fee schedule is one of its inputs.

## 22.2 Consolidated options-feed bandwidth

**Definition 22.2 (Feed partition).**

A *feed partition* is one of the parallel streams (lines, channels, [multicast groups](https://one-course.com/books/quant/14/en/chapter/1-networking-for-trading#def-nw-networking-for-trading-group)) into which a feed’s operator splits its messages by a published rule on the instrument, so that each stream fits a link and a handler and a subscriber can take only the partitions it needs.

The consolidated options feed has 96 lines since its expansion, and since 1 June 2026 a published symbol distribution spreads the load over them: by symbol range, and within the busiest symbols by calls and puts and by odd and even expiration months or days, “for optimal symbol balancing and line capacity utilization”. Its capacity notice is written for burst planning ([Box 22.2](#dat-nw-equities-and-options-connectivity-opra)).

**As of September 2026 — The consolidated options feed’s capacity, from its operator’s notices.**

The projection effective July 2026 gives for one stream 13.575 million messages, 4.403 gigabits and 1.564 million packets in the busiest 100 milliseconds; 1.562 million messages and 0.501 gigabits in the busiest 10; 311 billion messages a day; and at most 625 000 messages per 100 milliseconds on one line. Both redundant streams double the bandwidth; add 10% for retransmissions. The median latency through the processor is under 18 microseconds. Ninety-six lines, with a new symbol distribution from 1 June 2026.

Read as rates, the notice asks for $44.0\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ over the busiest 100 milliseconds and $50.1\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ over the busiest 10. Its gigabits divided by its packets give 352 bytes a packet and 8.68 messages a packet; treating those bytes as UDP payload and adding Ethernet, IP, UDP and the line’s own overhead with `firm.netsim` gives 418 bytes on the wire a packet, $48.0\,\mathrm{bytes}$ a message. On the wire the 10-millisecond peak is $59.4\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ a stream, and with both streams and the retransmission allowance $130.6\,\mathrm{G}\mathrm{bit}/\mathrm{s}$.

A switch port does not average over 10 milliseconds. To plan links, the chapter simulates a busy minute in 1-millisecond bins: a slowly varying level (a log-AR(1) with a persistence of a second) times rare spikes (one bin in a thousand) and a little noise. Two parameters, the level’s spread and the spikes’ size, are fitted to two published ratios: the busiest millisecond of July 2026 against the busiest 10 milliseconds, 3.93, and the projection’s busiest 10 milliseconds against its busiest 100, 1.151. The fit gives 3.90 and 1.152; scaled to the projection’s 10-millisecond peak, the simulated minute’s busiest 100 milliseconds hold 13.56 million messages against the notice’s 13.575, a check the fit was not asked to pass. Each bin’s messages are then shared over the 96 lines with lognormal noise around equal shares (spread 0.5, an assumption).

```python
def burst(n_bins, sigma_s, spike, q=0.001, phi=0.999, sigma_w=0.1, seed=0):
    """Messages per 1-ms bin, mean 1: exp(slow + noise) * (1 + J); slow is a log-AR(1),
    s.d. sigma_s, persistence phi; J is spike * Exp(1) in a fraction q of bins, else 0."""
    rng = np.random.default_rng(seed)
    e = rng.standard_normal((2, n_bins))
    slow = lfilter([sigma_s * math.sqrt(1 - phi * phi)], [1, -phi], e[0])
    jump = (rng.random(n_bins) < q) * spike * rng.exponential(1.0, n_bins)
    x = np.exp(slow + sigma_w * e[1]) * (1 + jump)
    return x / x.mean()
```

***Listing 22.1.** The simulated busy minute: a slow level times rare spikes, in 1-ms bins. code/firm/portplan/firm_portplan.py*

![Simulation: six hundred milliseconds of the busy minute around its busiest millisecond, one stream, on the wire. The busiest millisecond runs at 234\, G bit/ s, the 10-millisecond average around it below 40\, G bit/ s. Data: fig_options.py, nw_options.LINES_GBPS.](https://one-course.com/images/onecourse/chapters/quant-14/nw-equities-and-options-connectivity/fig-cd2edc31f398.svg)

***Figure 22.1.** Simulation: six hundred milliseconds of the busy minute around its busiest millisecond, one stream, on the wire. The busiest millisecond runs at $234\,\mathrm{G}\mathrm{bit}/\mathrm{s}$, the 10-millisecond average around it below $40\,\mathrm{G}\mathrm{bit}/\mathrm{s}$. Data: `fig_options.py`, `nw_options.LINES_GBPS`.*

The lines are then packed onto links, whole and in order, and a link is enough at a planning percentile when that percentile of its 1-millisecond rate fits $10\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ less the 10% allowance.

```python
def links_needed(lines_gbps, pct, link_gbps=10.0, retrans=0.10):
    """Fewest links, lines kept whole and packed in order, whose pct-th percentile 1-ms rate fits the link."""
    cap = link_gbps / (1 + retrans)
    n = lines_gbps.shape[1]
    for links in range(1, n + 1):
        groups = np.array_split(np.arange(n), links)
        if all(np.percentile(lines_gbps[:, g].sum(axis=1), pct) <= cap for g in groups):
            return links
    return math.inf
```

***Listing 22.2.** Links for one stream: the fewest groups of whole lines whose planning percentile fits a link. code/firm/portplan/firm_portplan.py*

**Proposition 22.3 (Links against the percentile).**

The number of links a feed needs never falls when the planning percentile rises, and at the 100th percentile of 1-millisecond bins it is at least the feed’s busiest millisecond divided by a link’s usable capacity.

**Proof.** A higher percentile of each group’s rate is at least the lower one, so every packing that fails at the lower percentile fails at the higher. At the maximum, each link carries at most its capacity in every bin, so the links together carry at most their number times the capacity in the busiest bin, which must hold the whole feed’s busiest millisecond. ∎

![Simulation: links needed for both streams of the consolidated options feed, 96 lines packed whole, against the percentile of 1-millisecond bins the plan must carry. Median: 4; 99th: 12; 99.99th: 44; the busiest millisecond: 178 links of 10\, G bit/ s or 32 of 25\, G bit/ s. Data: fig_options.py, nw_options.links_table().](https://one-course.com/images/onecourse/chapters/quant-14/nw-equities-and-options-connectivity/fig-bea1910819cd.svg)

***Figure 22.2.** Simulation: links needed for both streams of the consolidated options feed, 96 lines packed whole, against the percentile of 1-millisecond bins the plan must carry. Median: 4; 99th: 12; 99.99th: 44; the busiest millisecond: 178 links of $10\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ or 32 of $25\,\mathrm{G}\mathrm{bit}/\mathrm{s}$. Data: `fig_options.py`, `nw_options.links_table()`.*

The answer depends on the percentile more than on anything else. At the median, four $10\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ links carry both streams; at the 99th percentile twelve; at the 99.99th, which leaves six milliseconds of the minute over budget, forty-four. The proposition’s bound for the busiest millisecond is 26 links a stream ($234\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ over $9.09\,\mathrm{G}\mathrm{bit}/\mathrm{s}$); packing whole lines needs 89, 178 for both streams, nearly one link a line, because a single line’s busiest millisecond reaches $6.8\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ and the lines’ bursts do not fall in the same millisecond. With $25\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ links, 32. What the plan does not carry at the link, a switch buffer or a drop absorbs (chapter 1), so the percentile is a choice of how often the firm accepts a queue or a gap. The line limit is not the constraint: the busiest line’s busiest 100 milliseconds hold 171 500 messages, a quarter of the 625 000 the notice allows.

The handlers are the second budget. At 10 million messages a second a core (an assumption: $100\,\mathrm{n}\mathrm{s}$ a message, well above Book 13’s decoding cost of a few nanoseconds, to leave room for building the book), the 10-millisecond peak rate of 156.2 million messages a second needs 16 cores a stream. They cannot absorb the busiest millisecond, 609 500 messages, without a queue.

```python
def backlog(cores):
    """Fluid queue over the 1-ms bins: the largest backlog and the time the cores need to clear it."""
    rate = cores * PER_CORE / 1000
    q = worst = 0.0
    for a in AGG:
        q = max(0.0, q + a - rate)
        worst = max(worst, q)
    return worst, worst / rate
```

***Listing 22.3.** The queue in front of the handler cores, as a fluid over the 1-ms bins. code/networks/22-equities-and-options-connectivity/python/nw_options.py*

With 16 cores the queue reaches 449 500 messages and takes $2.8\,\mathrm{m}\mathrm{s}$ to clear; with 32, $0.9\,\mathrm{m}\mathrm{s}$; with 48, $0.27\,\mathrm{m}\mathrm{s}$; 64 cores never queue. Cores bought for the 10-millisecond peak turn the busiest millisecond into milliseconds of stale books, exactly when the market moves.

## 22.3 Risk-check layers under sponsored access

**Definition 22.4 (Sponsored-access risk layer).**

A *sponsored-access risk layer* is the sponsoring broker’s pre-trade control, in software or in a hardware gateway, through which every order and quote of a sponsored firm passes on its way to the venue, and which adds its processing latency to every message.

Under the market access rule (Book 11), a broker that gives a firm access to a venue under its membership must check that firm’s messages before they reach the venue. The check sits on the path, and on a quoting interface it sits on every round trip. Vendors publish their gateways’ latency.

**As of September 2026 — Published latencies of hardware risk gateways.**

Magmio’s FPGA Risk Check Gateway: pre-trade risk and compliance checks “as low as 200 nanoseconds”. Algo-Logic’s FPGA Pre-Trade Risk Check: checks “well under one microsecond”, for Rule 15c3-5 compliance.

No broker publishes the latency of its software layer; the chapter assumes $5\,\text{µ}\mathrm{s}$ each way. The cost of a risk layer is not only the added microseconds on one message: on a synchronous interface, it lowers what a port can carry.

## 22.4 Quote-traffic engineering

A market maker’s quoting load is its classes times their series times the update rate times two sides. Bulk messages carry up to 50 single-sided quotes, so messages are fifty times fewer than quotes. On a synchronous interface, read here as one bulk message in flight per port until its acknowledgement (an assumption to confirm with the venue), a port sends one message per round trip.

```python
def port_msgs_per_s(rtt_us):
    """One bulk message in flight per port: a port sends one message per round trip."""
    return 1e6 / rtt_us


def ports_needed(quotes_s, rtt_us, engines=1, per_msg=BULK_MAX, min_per_engine=1):
    msgs = quotes_s / per_msg / engines
    return engines * max(min_per_engine, math.ceil(msgs / port_msgs_per_s(rtt_us)))
```

***Listing 22.4.** Ports: one message per round trip on each, and at least one per matching engine. code/firm/portplan/firm_portplan.py*

**Proposition 22.5 (Quote refresh time).**

On a synchronous quoting interface with $k$ ports per matching engine, $b$ quotes per message and a round trip $\tau$ (risk layer included), refreshing $Q$ quotes spread evenly over $E$ engines takes $Q\tau/(Ekb)$: linear in the round trip and in the inverse of the ports.

**Proof.** Each engine receives $Q/E$ quotes in $Q/(Eb)$ messages; its $k$ ports send $k$ messages per round trip in parallel, so they need $Q/(Ekb)$ round trips. ∎

![The time to refresh all 600 000 quotes of 1 200 classes of 250 series over twelve matching engines, 50 quotes a message, one message in flight per port, a 20\, µ s round trip before the risk layer (assumptions). Two ports and no risk layer: 10\, m s; a 5\, µ s software layer: 15. Data: fig_options.py, nw_options.refresh_curve().](https://one-course.com/images/onecourse/chapters/quant-14/nw-equities-and-options-connectivity/fig-cbfce6bf8f7c.svg)

***Figure 22.3.** The time to refresh all 600 000 quotes of 1 200 classes of 250 series over twelve matching engines, 50 quotes a message, one message in flight per port, a $20\,\text{µ}\mathrm{s}$ round trip before the risk layer (assumptions). Two ports and no risk layer: $10\,\mathrm{m}\mathrm{s}$; a $5\,\text{µ}\mathrm{s}$ software layer: 15. Data: `fig_options.py`, `nw_options.refresh_curve()`.*

The chapter’s firm quotes 1 200 classes of 250 series on average, four updates a second a side: 2.4 million quotes a second, 48 000 bulk messages, $0.31\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ of order entry. With a $20\,\text{µ}\mathrm{s}$ round trip a port carries 50 000 messages a second, so throughput alone asks for one port; the venue’s twelve engines ask for twelve, and the two quoting ports per engine the venue allocates give twenty-four. Order entry is bound by messages and engines, not bandwidth; the feed is bound by bandwidth.

The binding case is the market-wide move, when every quote must change at once: 600 000 quotes. Two ports an engine refresh them in $10.0\,\mathrm{m}\mathrm{s}$; behind the FPGA gateway, $10.2\,\mathrm{m}\mathrm{s}$; behind the assumed software layer, $15.0\,\mathrm{m}\mathrm{s}$; with one port an engine and no layer, $20.0\,\mathrm{m}\mathrm{s}$. Quote-traffic engineering is the art of not needing that full refresh: single-sided quotes let the firm send the important sides first (the specification’s own point), purge ports pull quotes faster than updating them, and the order in which series are refreshed is a risk decision.

**Method 22.6 (Sizing an options desk’s connectivity).**

1. Read the feed’s latest capacity notice and metrics; convert them to wire bits with the framing overhead; double for both streams and add the retransmission allowance.
2. Choose a planning percentile at the millisecond scale, and pack whole partitions onto links against it; decide what the switch buffers absorb above it.
3. Size handler cores on the 10-millisecond peak and check the queue of the busiest millisecond; add cores until the delay is acceptable.
4. From the quoting load, compute messages, ports per engine and the full-refresh time, with the risk layer in the round trip.
5. Price the ports on each venue’s schedule; add drop copies and purge ports; re-run at each new capacity notice.

| Budget | Quantity | Plan |
| --- | --- | --- |
| Feed, one stream | 10-ms peak on the wire | $59.4\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ |
| Feed, both streams | with 10% retransmissions | $130.6\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ |
| Links | 99.99th percentile, 10 Gb/s | 44 |
| Handler cores | 10-ms peak, one stream | 16 |
| Busiest millisecond | queue with 16 cores | $2.8\,\mathrm{m}\mathrm{s}$ |
| Quoting | quotes and messages a second | 2.4 million; 48 000 |
| Quoting ports | two per engine, twelve engines | 24 |
| Full refresh | two ports, software risk layer | $15.0\,\mathrm{m}\mathrm{s}$ |

***Table 22.1.** The capacity plan of the chapter’s options desk (feed from the July 2026 projection and a labelled simulation; quoting from stated assumptions). Data: `nw_options.feed_plan()`, `quote_plan()`.*

![The two budgets of an options desk: the feed side is bound by bandwidth and handler cores, the quoting side by ports, engines and round trips, with the broker’s risk layer on every one. Schematic.](https://one-course.com/images/onecourse/chapters/quant-14/nw-equities-and-options-connectivity/fig-ca5cd6cd5040.svg)

***Figure 22.4.** The two budgets of an options desk: the feed side is bound by bandwidth and handler cores, the quoting side by ports, engines and round trips, with the broker’s risk layer on every one. Schematic.*

## 22.5 Tutorial: a capacity table for an options desk

**Goal.** From the feed’s capacity notice and a quoting load, compute links, cores and ports. **End state:** [Table 22.1](#tab-nw-equities-and-options-connectivity-plan) and [Figure 22.2](#fig-nw-equities-and-options-connectivity-links).

1. **Notice.** `firm_portplan.projection` reads the dated rows for July 2026; `wire_bytes_per_msg` adds the framing with `firm.netsim` .
2. **Busy minute.** `fit_burst` fits the burst model to the two published ratios; `burst` ( [Listing 22.1](#lst-nw-equities-and-options-connectivity-burst) ) and `line_split` give each line’s 1-ms rates.
3. **Links and cores.** `links_needed` ( [Listing 22.2](#lst-nw-equities-and-options-connectivity-links) ) for each percentile; `nw_options.backlog` ( [Listing 22.3](#lst-nw-equities-and-options-connectivity-backlog) ) for the cores.
4. **Ports.** `ports_needed` ( [Listing 22.4](#lst-nw-equities-and-options-connectivity-ports) ) and `nw_options.quote_plan` with each risk layer.

**What to change next.** Replace the equal line shares with the published symbol distribution and a model of each symbol’s traffic; add the switch buffer with `firm.netsim.egress` and count drops at each percentile.

## 22.6 Build: the port and bandwidth planner

**Purpose.** Links, cores and ports for a desk that takes a partitioned feed and quotes through a venue’s ports: the equities and options rows of chapter 29’s plan.

**Interface.** `firm_portplan`: `load_capacity`, `projection`, `wire_bytes_per_msg`, `burst`, `window_peak`, `ratios`, `fit_burst`, `line_split`, `links_needed`, `cores_needed`, `quotes_per_s`, `port_msgs_per_s`, `ports_needed`, `bulk_bytes`.

**Rules.** Published capacities and fees are dated rows with sources; the busy minute is a labelled simulation whose free parameters are fitted to published ratios; every other parameter is a stated assumption.

**Acceptance tests.** `code/firm/portplan/tests/`: the capacity rows, flat traffic giving ratios of one, equal lines packing by hand, and the port arithmetic.

**Stretch.** Line shares from the published symbol distribution; drops through `firm.netsim`’s [egress queue](https://one-course.com/books/quant/14/en/chapter/1-networking-for-trading#def-nw-networking-for-trading-egress); per-venue port rules.

Sources and further reading

- SIAC, OPRA capacity projections (September 2025) and 96-line symbol distribution notice (May 2026); OPRA key operating metrics (August 2026).
- SEC Release No. 34-103889 and Federal Register 90 FR 60788 (Phlx SQF port fees); MIAX Options, MEI Interface Specification, version 2.10a.
- Magmio and Algo-Logic product pages for FPGA risk gateways.

## 22.7 Exercises

**Exercise 22.1 ★.**

From the July 2026 projection, what are the busiest 100 milliseconds and the busiest 10 milliseconds as rates in gigabits a second, for one stream as the notice counts it?

**Solution of Exercise 22.1.**

$4.403 \times 10 = 44.0\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ over 100 milliseconds and $0.501 \times 100 = 50.1\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ over 10 milliseconds.

**Exercise 22.2 ★.**

How many bulk messages a second does a firm send for 2.4 million single-sided quotes a second on MEI?

**Solution of Exercise 22.2.**

$2\,400\,000/50 = 48\,000$ messages a second, if every message is full.

**Exercise 22.3 ★.**

Why does a firm quoting on MIAX need ports on every cloud, even with little load on some of them?

**Solution of Exercise 22.3.**

Each cloud trades all the options on its own set of underlyings, and a bulk quote reaches only the engine behind the port it is sent on: a firm that quotes an underlying must have a Full Service port on that underlying’s cloud, whatever the load.

**Exercise 22.4 ★★.**

Using [Proposition 22.5](#prop-nw-equities-and-options-connectivity-refresh), how long does a full refresh take with two ports an engine behind the FPGA gateway, and what would a third port an engine give?

**Solution of Exercise 22.4.**

$600\,000 \times 20.4/(12 \times 2 \times 50) = 10\,200$ µs, $10.2\,\mathrm{m}\mathrm{s}$; with three ports an engine $6.8\,\mathrm{m}\mathrm{s}$. On MIAX the third bulk-quoting port is not available: firms get two Full Service ports a cloud.

**Exercise 22.5 ★★.**

Why is the 99.99th percentile a demanding planning target at the millisecond scale, and what happens above it?

**Solution of Exercise 22.5.**

In a busy minute of 60 000 milliseconds it leaves only six over budget, and the busiest milliseconds run several times the 10-millisecond average. Above it, traffic queues in the switch’s buffers, adding delay, or overflows them and is lost, leaving gaps the handlers must recover from the other stream or by retransmission.

**Exercise 22.6 ★★.**

What does twenty-four quoting ports cost a month on each venue in [Box 22.1](#dat-nw-equities-and-options-connectivity-ports)?

**Solution of Exercise 22.6.**

Phlx $28 440 (before volume discounts), EDGX $18 000, Arca and American $12 240 each, BOX $1 000, MIAX $20 500 for over 100 classes whatever the number of ports.

**Exercise 22.7 ★★★.**

*Coding.* With `nw_options.backlog`, how many handler cores keep the busiest millisecond’s queue under $0.5\,\mathrm{m}\mathrm{s}$?

**Solution of Exercise 22.7.**

41 cores: the queue peaks at 199 500 messages and clears in $0.49\,\mathrm{m}\mathrm{s}$; with 40 it takes $0.52\,\mathrm{m}\mathrm{s}$.

**Exercise 22.8 ★★★.**

*Find the flaw.* “The notice says $50\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ at the 10-millisecond peak, so six $10\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ links per stream are plenty.”

**Solution of Exercise 22.8.**

Four errors: the notice’s bits are before the Ethernet framing ($59.4\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ on the wire); the allowance adds 10%; the 10-millisecond peak is an average, and the busiest millisecond runs at $234\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ in the chapter’s simulation; and lines are packed whole, so links cannot be filled evenly. Six links carry the 10-millisecond average, not the milliseconds inside it.

## 22.8 Problem: Quoting Every Series

**Problem 22.1.**

Weekend problem — ports and links for a U.S. options market maker

A firm will quote 1 200 option classes of 250 series on average, four updates a second a side, on a venue with twelve matching engines and synchronous bulk quoting, through a sponsoring broker; it takes the consolidated feed in full, both streams. Use the chapter’s planner.

**Part I — The feed.**

1. What bandwidth does the July 2026 projection ask for, as the notice counts it and on the wire, one stream and both with the allowance?
2. How many bytes a message does the chapter use on the wire, and from what?
3. How many 10 Gb/s links carry both streams at the median, 99th and 99.99th percentiles of 1-millisecond bins?
4. Why does carrying the busiest millisecond need 178?

**Part II — The handlers.**

5. How many cores does the 10-millisecond peak need at 10 million messages a second a core?
6. What queue does the busiest millisecond build with them, and how long does it take to clear?
7. How many cores remove the queue entirely?
8. Which check did the burst model pass without being fitted to it?

**Part III — The quotes.**

9. How many quotes, bulk messages and gigabits a second does the firm send?
10. How many ports does throughput need, and how many does the venue’s structure impose?
11. How long does a full refresh take with two ports an engine, without a risk layer, behind the FPGA gateway and behind the software layer?
12. What does the full refresh time mean for the firm’s risk after a market-wide move?

**Part IV — The verdict.**

13. State the *named result* : the ports and 10 Gb/s links needed to quote the firm’s classes at its update rate and to take the consolidated feed in full.
14. Which inputs are published and which assumed?
15. What would 25 Gb/s links change?
16. Which of the firm’s decisions does the risk layer affect most?
17. How should the firm order its quote updates after a move?
18. What must be re-run when the next capacity notice arrives?
19. Where do these numbers go in chapter 29’s plan?
20. In one sentence: why is options connectivity capacity planning before it is latency?

**Solution of Problem 22.1.**

**Part I.**

1. As the notice counts it, $44.0\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ over 100 milliseconds and $50.1\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ over 10; on the wire 52.2 and $59.4\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ ; both streams with the allowance 114.8 and $130.6\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ .
2. $48.0\,\mathrm{bytes}$ : the notice’s 352 bytes a packet taken as UDP payload, framed to 418 bytes on the wire, over 8.68 messages a packet.
3. 4, 12 and 44.
4. Lines are packed whole and each line has its own bursts, up to $6.8\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ in one millisecond, in different milliseconds; so nearly every line needs a link of its own, against a bound of 26 a stream from the busiest millisecond alone.

**Part II.**

1. 16 a stream, for 156.2 million messages a second.
2. 449 500 messages, cleared in $2.8\,\mathrm{m}\mathrm{s}$ .
3. 64: the busiest millisecond holds 609 500 messages, and 64 cores process 640 000 a millisecond.
4. Its busiest 100 milliseconds, 13.56 million messages against the notice’s 13.575 million.

**Part III.**

1. 2.4 million quotes, 48 000 bulk messages and $0.31\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ .
2. One for throughput (a port carries 50 000 messages a second); twelve, one per engine, by the venue’s structure, and the firm uses the two per engine it is allocated, 24.
3. $10.0\,\mathrm{m}\mathrm{s}$ , $10.2\,\mathrm{m}\mathrm{s}$ and $15.0\,\mathrm{m}\mathrm{s}$ .
4. For up to that long some of its quotes are stale, and anyone faster can trade against them; the firm needs purges and an order of refresh that removes the most dangerous quotes first.

**Part IV.**

1. *Named result* : quoting 1 200 classes of 250 series at four updates a second a side takes 2.4 million quotes and 48 000 bulk messages a second, which one port could carry but twelve engines turn into 24 quoting ports (two an engine), refreshing every quote in 10 to $15\,\mathrm{m}\mathrm{s}$ depending on the risk layer; taking the consolidated feed in full, both streams, takes 44 links of $10\,\mathrm{G}\mathrm{bit}/\mathrm{s}$ at the 99.99th percentile of milliseconds (12 at the 99th) and 16 handler cores a stream.
2. Published: the capacity projection, the busiest-millisecond metric, the line count, the port rules and fees, the gateway latencies. Assumed: line shares, the burst model’s shape, bytes as payload, cores’ speed, the round trip, the software layer, the firm’s load and the venue’s twelve engines.
3. The busiest millisecond needs 32 instead of 178, and the 99.99th percentile 16 instead of 44; fewer, faster links with the same switch ports.
4. The full-refresh time, and so how long its quotes are stale after a move; one message’s latency matters less.
5. Most dangerous first: the sides most likely to be hit (near the money, short-dated, those the move made cheap), purging what cannot be updated in time.
6. The feed plan (links, cores, queue) from the new projection, the fit to the latest metrics, and the port prices.
7. In the equities and options rows: links and cores for the feed, ports per venue, the risk layer, and their monthly costs.
8. Because the binding constraints are the feed’s bursts and the ports’ round trips, which set how many links, cores and ports the firm must buy before any microsecond is saved.

## 22.9 Interview questions

**Interview question 22.1 ★ developer.**

Why does a feed operator publish its capacity per 10 milliseconds rather than per second?

**Solution of Interview question 22.1.**

Because receivers are sized for bursts: a one-second average hides peaks several times higher, and a switch port or a handler that cannot keep up for a few milliseconds drops or delays data. Even 10 milliseconds hide the millisecond peaks.

*What the interviewer is looking for: Averages against peaks; buffers; the planning window.*

**Interview question 22.2 ★★ developer.**

How would you decide how many links and servers to buy for the full U.S. options feed?

**Solution of Interview question 22.2.**

Take the operator’s capacity notice and metrics, convert to wire bits, double for both streams, add the retransmission allowance; model the millisecond bursts per partition, choose a planning percentile, pack partitions onto links; size handler cores on the peak and check queues; re-run at every notice.

*What the interviewer is looking for: Published capacity; framing; percentiles; partitions; handlers.*

**Interview question 22.3 ★★ developer, researcher.**

What limits how fast a market maker can update all its quotes, and how would you measure it?

**Solution of Interview question 22.3.**

The number of quotes to change, the quotes per message, the ports per engine and the round trip per message (including the risk layer), and the venue’s throttles. Measure by timestamping each bulk message and its acknowledgement per port, and the time from a market event to the last quote updated.

*What the interviewer is looking for: Messages and round trips; ports; risk layer; measurement from event to last quote.*

**Interview question 22.4 ★★ developer.**

A sponsoring broker offers a software risk layer or a hardware gateway. What would you ask, and how would you compare them?

**Solution of Interview question 22.4.**

The latency added each way at the percentiles that matter, with and without load; the checks it performs and how they are configured; failure behaviour; capacity per port; and who operates it. Compare by the full-refresh time and the round trip each implies for the firm’s quoting, not only by one message’s latency.

*What the interviewer is looking for: Latency distribution under load; checks; failure modes; effect on throughput.*

**Interview question 22.5 ★★ trader.**

After a large move, which quotes should be updated first, and why?

**Solution of Interview question 22.5.**

The quotes most likely to be traded against at stale prices: near the money, short-dated, large sizes, and sides the move made too generous; purge what cannot be updated in time rather than leave it.

*What the interviewer is looking for: Adverse selection; ordering by risk; purges.*

**Interview question 22.6 ★★★ developer, researcher.**

Design the connectivity of a new options market-making desk in one U.S. data centre: feed, handlers, ports, risk layer and monitoring.

**Solution of Interview question 22.6.**

Both feed streams on links sized at a chosen millisecond percentile, with switch buffers and drop monitoring; handler cores sized with a queue budget; quoting ports on every engine, purge ports, a drop copy; a risk layer measured for its effect on refresh time; and monitoring of gaps, queue delays, acknowledgement times and port limits, re-planned at every capacity notice.

*What the interviewer is looking for: Both budgets; percentiles and queues; ports per engine; risk layer; monitoring.*
