Kernel TX Pacing Quantization as a Hidden Slippage Driver (Practical Playbook)
Date: 2026-03-16
Category: research
Audience: execution teams running Linux-based gateways/routers where child-order cadence is sensitive to sub-millisecond timing
Why this matters
Many desks model slippage as a function of market microstructure (spread, queue depth, volatility) plus strategy state (urgency, residual, participation).
But a frequent blind spot sits one layer below: kernel transmit pacing + queue limits.
When child orders are emitted through a paced socket/qdisc path, inter-packet timing can be quantized and state-dependent. The strategy may believe it dispatched smoothly, while the wire sees bursts and stalls. In fast books, that can degrade queue priority and inflate short-horizon markouts.
1) Mechanism: where quantization appears
With Linux fq qdisc, per-flow pacing can be enforced, and applications can cap socket pacing using SO_MAX_PACING_RATE.
Conceptually:
- strategy emits child intents at desired times (\tau_k)
- socket/qdisc applies pacing and queue constraints
- actual wire transmit times become (\tilde{\tau}_k)
- queue-entry timing error (\epsilon_k = \tilde{\tau}_k - \tau_k)
- slippage branch probabilities shift
Even small (\epsilon_k) tails matter near quote fades, queue races, or microburst transitions.
2) Slippage decomposition with transport-path distortion
Start with implementation shortfall decomposition:
[ IS = (P_{fill} - P_{decision})\cdot side ]
Extend with a transport timing term:
[ IS = IS_{market} + IS_{sizing} + IS_{timing},. ]
Model timing cost as:
[ IS_{timing} = f(\epsilon, B, Q, U), ]
where:
- (\epsilon): dispatch-vs-wire delay/jitter,
- (B): burstiness of actual transmit stream,
- (Q): queue-state proxy at venue arrival,
- (U): urgency/residual state.
In practice, you often see this as a tail tax (q95/q99 slippage worsening while median barely moves).
3) Observable signals (what to log now)
3.1 Dispatch-to-wire gap
Per child order:
- app dispatch timestamp,
- kernel/socket handoff timestamp (if available),
- first-byte-on-wire or nearest proxy.
Primary KPI:
[ \Delta_{dw} = t_{wire} - t_{dispatch} ]
Track p50/p95/p99 by symbol × venue × tactic.
3.2 Burstiness index (wire-side)
In window (w) (e.g., 100–500(\mu s)):
[ BI = \frac{\max_w N_w}{\sum_w N_w} ]
Higher BI means pacing/queue interaction is creating microbursts.
3.3 Pacing headroom
From socket telemetry (ss -i):
pacing_rate / max_pacing_rate,send-qandwmem_queuedtrends.
If pacing_rate frequently hits cap during urgency spikes, timing slippage is partly self-inflicted by rate ceilings.
3.4 Queue-loss proxy
Define a simple arrival-quality proxy:
[ QLP = E[\text{fill quality} \mid high; \Delta_{dw}, high; BI] - E[\text{fill quality} \mid low; \Delta_{dw}, low; BI] ]
Negative drift indicates transport distortion is translating into real execution loss.
4) Common failure pattern
A frequent anti-pattern:
- strategy scheduler smooths child orders (looks good in app logs),
- kernel/qdisc pacing + backlog gates actual emission,
- wire pattern becomes lumpy under load,
- venue queue entry misses the intended micro-windows,
- model attributes loss to “market randomness”.
Result: false comfort from clean app-level timelines.
5) Model upgrade: transport-aware branch state
Use a 3-branch execution state model:
- Clean-Flow: low (\Delta_{dw}), low BI
- Pacing-Limited: high cap utilization, moderate (\Delta_{dw})
- Burst-Released: elevated BI + (\Delta_{dw}) tail
Expected cost:
[ E[C] = p_C C_C + p_P C_P + p_B C_B,\quad C_C < C_P < C_B ]
Then optimize not only (C) terms, but transition probabilities (p_P, p_B).
6) Control levers that usually pay off
A) Explicit pacing policy by tactic
Separate caps for:
- passive queue-building tactics,
- urgent residual cleanup.
One static cap across all urgency regimes is usually suboptimal.
B) Anti-phase-lock emission
Inject bounded micro-jitter into child dispatch when BI rises, to avoid deterministic resonance with pacing refill/dequeue cycles.
C) Queue budget guardrail
If wmem_queued or send queue exceeds threshold, temporarily reduce child granularity and prioritize high-value intents only.
D) Regime-aware fallback
When transport state enters Burst-Released:
- down-weight fragile microstructure signals,
- widen acceptable aggression bands,
- optimize for completion reliability over spread capture.
7) Validation protocol (10-day practical plan)
Days 1–2
Add dispatch/wire/pacing telemetry (ss -i sampling, qdisc stats, child-order timeline joins).
Days 3–4
Build dashboards for (\Delta_{dw}), BI, pacing cap utilization, and slippage tails.
Days 5–6
Estimate branch-state transition model and branch-conditional costs.
Days 7–8
Shadow transport-aware controller (no live behavior change), compare projected costs.
Day 9
Canary at 5–10% flow with strict rollback criteria (completion and q95/q99 slippage).
Day 10
Promote if tails improve without completion regression; publish runbook and weekly recalibration schedule.
8) Guardrails / pitfalls
- Mean-only success metrics → hides tail transport tax.
- No wire-proxy timestamping → impossible to separate strategy vs stack delay.
- Single pacing config for all tactics → creates systematic urgency mismatch.
- Assuming app dispatch time equals market arrival time → invalid in paced/backlogged paths.
- Ignoring queue send backlog during volatility bursts → late cleanup snowballs.
Bottom line
Kernel pacing is excellent for stability, but in low-latency execution it can also create timing quantization that leaks directly into slippage.
If you make transport state explicit in your TCA/model loop—rather than treating it as noise—you can often recover tail performance without changing alpha.
References
Linux
fqqdisc manual (SO_MAX_PACING_RATE, pacing behavior, EDT note)
https://man7.org/linux/man-pages/man8/tc-fq.8.htmlLinux kernel networking sysctl docs (
tcp_limit_output_bytes, pacing-related TCP tunables)
https://docs.kernel.org/networking/ip-sysctl.htmlLinux
ssmanual (pacing_rate, queue/memory/socket internals)
https://man7.org/linux/man-pages/man8/ss.8.html