← Back to blog
Solution 4 min read 炬鲸团队

Millisecond-Level Root-Cause Location for Securities Trading with Full-Trace Tracing

Slow incident location plagues securities trading. This article lays out a full-trace tracing approach — instrumentation, order-number-to-trace lookup, sampling and alerting — that cuts location time from tens of minutes to a few.

The observability pain in trading systems

Securities trading is extremely latency-sensitive. One order travels from the client through the counter and exchange and back, passing through a gateway, risk control, order management, and clearing — a dozen services or more. When a user complains “my order didn't fill” or “the fill came back slow”, the traditional response is to pull a pile of logs and compare them by hand, which takes tens of minutes and may still miss the root cause. Distributed tracing ties the whole transaction together by trace id, showing exactly where it stalls and how many milliseconds each hop costs. It also gives risk and operations teams a single shared picture of a trade, which matters when an incident has to be explained to regulators on a tight clock. During a volatile session the support desk is flooded, and every minute of investigation that pulls in a production engineer is a minute stolen from actual trading.

Instrumenting the full path

Coverage has to be complete or the trace breaks:

  • The gateway generates a trace id at entry and injects it into HTTP headers through every downstream service
  • Database, cache, and message-queue (Kafka/RocketMQ) calls must all be instrumented, or the trace breaks right there
  • Async messages must propagate trace context, and consumers must be able to reconstruct the parent span

Async is where it usually fails: when an order reports back through MQ, if the producer doesn't write the trace context into the message header, the consumer starts a brand-new trace and the chain is severed. If you're already on OpenTelemetry, much of this comes free with auto-instrumentation; the real work is filling the gaps with custom spans around the exchange gateway and the clearing batch jobs.

From order number to trace

  1. Enter the order number or delegate ID and look up the trace id in the logs
  2. Open the trace's flame graph or hydration view to see the time distribution across spans
  3. Locate the slowest or errored span, expand it, and read the associated logs and error details

In practice, support staff don't need to understand spans at all — they paste the order number into a single search box and get back a rendered trace with the slow hop highlighted. That one workflow is what turns tracing from an engineering toy into a support tool. Steps 2 and 3 live or die on hydration speed: a trade trace has many spans and a wide span, and if it takes seconds to render, the debugging experience falls apart. Observe optimizes for exactly this, opening long traces in under a second.

Performance and cost control

Full capture is unrealistic at trading volume:

  • Sampling: sample normal orders at 1%, keep 100% of abnormal ones (errors, timeouts)
  • Storage: hot data in memory/SSD for second-level queries, history archived to cold storage
  • Alerting: alert automatically when a single order's end-to-end latency exceeds a threshold (say 300ms), aggregated by user and channel

Stability under extreme market conditions

In a crash or a sudden rally, volume can double in minutes, and the pressure on your observability system is no less than on the trading system itself. Do two things ahead of time: load-test the ingestion pipeline to confirm it absorbs peak writes, and make the sampling policy dynamic — sample normally, but when a traffic spike is detected, automatically raise the sampling rate or temporarily keep every abnormal order, so you don't lose traces exactly when you need them most.

Results and recommendations

After one broker went live, average time to locate trading failures dropped from 40 minutes to under 5, and incident tickets fell by roughly 30%. Start with the core chain — order, fill, clearing — and expand to quotes and accounts once it's stable. On metrics, watch latency percentiles (P50/P95/P99) rather than averages; averages hide the long tail. Base your alert thresholds on P99 rather than the mean: the mean gets diluted by a flood of fast orders, so it can look perfectly healthy even while a handful of slow orders are wrecking the user experience. The same logic applies to capacity planning — provision for the tail, not the average.