Skip to content

Connection security

Two clocks for exchange API requests

A backward clock adjustment can extend a local deadline while making a signed request stale. Follow both clocks through a checked incident worksheet.

An ivory clock with an offset rim connects by a lime rod to a straight pegged rail carrying a lime carriage on a black background.
Illustration for connection security; examples in this article are educational.

Use a monotonic clock for elapsed request budgets and a synchronized wall clock for authenticated epoch timestamps. A monotonic reading has a local origin; it is not the UTC time an exchange expects. Keep both measurements because a clock adjustment can make a request appear young locally while its signed timestamp is already stale at the exchange.

A client needs to answer two different questions: how long has this attempt been waiting, and what time does the signed request claim it was created? Recording only one clock makes those questions harder to separate during an incident.

Assign each clock a job

A wall clock supplies calendar time, commonly represented as milliseconds since the Unix epoch. It can be corrected when the computer's time is wrong. A monotonic clock measures progression without moving backward because of a wall-clock correction. The W3C High Resolution Time working draft describes this distinction and the limited contexts within which its monotonic readings can be compared.

Client operationClock or evidence to useReason
Measure one request's round tripSame monotonic source at both endsA calendar correction should not distort elapsed time
Enforce an in-process attempt budgetMonotonic deadline, rechecked before workWaiting consumes the budget even if UTC moves backward
Populate an exchange authentication timestampSynchronized epoch time in the documented unitThe exchange compares against its own time
Correlate an incident across servicesUTC records plus request identity and synchronization statusDifferent processes do not necessarily share a monotonic origin
Recover after a restartDurable request/order records and fresh clock stateAn old local timer is not automatically meaningful in the new process

In Node.js, performance.now() reports milliseconds relative to the current process's start. Sending that value directly as an exchange timestamp would confuse elapsed process time with an epoch instant. The Node.js performance API reference also defines performance.timeOrigin, the process's epoch-related starting point.

Adding those two values can produce an estimate in epoch units, but it does not establish current synchronization with the exchange. Keep the distinction between a convenient time representation and a verified current clock.

Authentication checks do not measure your timer

Binance Spot requires a current timestamp on signed requests and documents a receive window for request validity. Its logic checks both excessive age and a timestamp too far ahead, with another age check during processing. Those are exchange acceptance conditions; a client-side stopwatch cannot satisfy them by itself. Units and rules remain specific to the API. Binance Spot timing security.

Bybit's V5 guidance separately specifies a UTC millisecond header and recommends keeping local device time synchronized with NTP. That is a useful reminder to inspect the actual signing machine, which may be a remote backend rather than the user's laptop. Bybit authenticated request timing.

Generate the timestamp close to transmission, after any application queue, using the venue's supported approach. Once the timestamp enters the signed representation, keep the transmitted representation consistent. Changing its timestamp afterward requires reconstructing authentication correctly; the URL encoding and signature guide explains why the exact request bytes matter.

For error-code diagnosis and receive-window boundaries, use the existing timestamp versus signature troubleshooting guide. The issue here is which clock produced the evidence, rather than another recipe for replacing credentials.

A backward jump can break two checks differently

Consider this hypothetical incident. The exchange and client initially agree on UTC. A request attempt has an invented 800 ms local budget. After 600 ms of actual elapsed time, the client wall clock is stepped backward by 2,000 ms. The monotonic clock continues normally. These values illustrate arithmetic, not a measured outage or recommended budget.

ObservationClient wall time, UTCMonotonic reading
Attempt begins12:00:00.00050,000 ms
Timestamp created after the adjustment11:59:58.60050,600 ms

The same two observations produce very different results:

CalculationResultInterpretation
Monotonic difference50,600 − 50,000 = 600 msThe attempt has used 600 ms
Wall-clock difference11:59:58.600 − 12:00:00.000 = −1,400 msThis cannot represent the actual wait
Monotonic budget remaining800 − 600 = 200 msOnly 200 ms remains
Wall deadline minus current wall time12:00:00.800 − 11:59:58.600 = 2,200 msA wall-based deadline wrongly appears much farther away

Now suppose the client signs with 11:59:58.600 and transmission takes 150 ms. The exchange evaluates it at 12:00:00.750. The signed timestamp is 2,150 ms old at the exchange even though only 150 ms passed since signing.

Under a hypothetical 2,000 ms receive window, that request fails the modeled age comparison by 150 ms. Its modeled arrival occurs 50 ms before the local duration deadline. The two checks disagree because they answer different questions. A forward clock step can produce the opposite timing symptom: a future-dated authentication timestamp and an apparently exhausted wall deadline.

Keep a small clock ledger

A useful diagnostic records paired wall and monotonic observations near the beginning and end of an operation. Their difference of differences estimates the wall-clock change relative to elapsed time over that interval:

w = wall1 - wall0
m = mono1 - mono0
change = w - m

In the incident, change = -1400 - 600 = -2000 milliseconds. This exposes the backward adjustment. It does not identify the clock service responsible, prove the exchange clock correct or estimate one-way network latency. Separate clock reads also introduce a small sampling gap; avoid presenting the result as infinitely precise.

Use this worksheet when reviewing a client or incident:

RecordWhat to retain
Clock scopeHost, process generation, runtime and monotonic source
Attempt identityRequest ID and original order identity, where applicable
Duration evidenceStart/end monotonic readings and budget used
Signing evidenceTimestamp unit, UTC value and delay from signing to send
Synchronization evidenceLast supported time check, its age and observed uncertainty
Discontinuity evidencePaired clock differences and any restart or resume event
Outcome evidenceProvider response or an explicitly unresolved exchange state

Keep the identifiers exact when attaching this ledger to an order. The large integer identifier guide covers why converting a long exchange ID to an imprecise number can detach otherwise useful timing evidence from the correct order.

Revalidate after resume, restart or a bad time sample

Do not persist a process-relative deadline and subtract a new process's timer from it. Do not assume all runtimes count suspended time identically. Python, for example, documents the platform clock implementations behind time.monotonic() and exposes information about adjustability and resolution. Verify the selected runtime and operating system rather than inferring behavior from the name alone. Python clock documentation.

For a client that caches a server-time correction or maps an epoch sample onto monotonic elapsed time, give that state an explicit expiry and scope. Refresh it after a detected discontinuity, restart or resume under the client's defined policy. A one-time server-time response contains network uncertainty and cannot prove the mapping stays accurate indefinitely.

A timer callback can also run late because the process was busy or paused. Recheck the deadline and clock readiness when execution resumes, before sending work. Market observations also need a separate source-time comparison; the market-data freshness guide distinguishes that age from time spent waiting locally. An elapsed-time budget limits willingness to continue; it cannot undo an order already sent.

If the response to that order is missing, preserve its unresolved status and follow order timeout reconciliation. Correcting the clock gives subsequent requests a better timing basis. It does not reveal what the previous request did at the exchange.

This AI-assisted educational article uses official API and runtime documentation reviewed on 23 October 2026. The incident and worksheet are original constructions. They describe client design and diagnostic choices, without claiming that KLINEO exposes these controls or implements every policy shown.

Keep the context with the example.

Each worked example is illustrative, with its sources and assumptions in the article. Read our editorial standards for authorship, verification and corrections.