gexbot api
general

latency & diagnostics

Measure the round trip to the gexbot API, read each phase of a request, and tell a slow network apart from a slow response.

A slow call has more than one cause. The request can wait in DNS, in the TCP handshake, in the TLS handshake, at the server, or in the transfer of the body. One total tells you none of this. Measure the phases, and the cause is usually obvious.


Measure a request from the command line

curl reports each phase with -w. Every value is in seconds, and each one is cumulative from the start of the request.

curl -o /dev/null -s -w "dns      %{time_namelookup}\ntcp      %{time_connect}\ntls      %{time_appconnect}\nttfb     %{time_starttransfer}\ntotal    %{time_total}\n" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "User-Agent: my-app/1.0" \
  https://api.gex.bot/v2/SPX/classic/gex_zero

A typical result looks like this:

dns      0.021
tcp      0.089
tls      0.152
ttfb     0.244
total    0.246

Subtract each value from the one above it to get the cost of that phase:

PhaseCalculationWhat it is
DNStime_namelookupThe time to resolve api.gex.bot.
TCPtime_connect less time_namelookupOne round trip to open the connection.
TLStime_appconnect less time_connectThe encryption handshake. It needs one or two more round trips.
Server and waittime_starttransfer less time_appconnectThe request goes out, gexbot answers, the first byte arrives.
Transfertime_total less time_starttransferThe time to read the rest of the body.

Read the result

The distance is the cause

The TCP phase is close to one network round trip. It is set by the distance between you and the gexbot region, and by the quality of the route. No change at gexbot makes it smaller.

Measure it three or four times. A steady value is distance, and it is physics. A value that moves a lot between attempts is congestion or packet loss on the path.

Send the output to support if the value is steady and much larger than you expect for your location.

This phase holds one network round trip and the time gexbot spent. A large value with a small TCP phase means the time went to the server.

The usual cause is a cold start. gexbot adds capacity when load rises, and a request that arrives while a new instance starts waits for it. This is most common in the minutes around the opening bell.

Repeat the call. A first call that is slow and a second that is fast is a cold start. Two slow calls in a row is not, and support wants to know.

Ask for less data. A zero or one category is much smaller than a full category. Accept compression, which curl does with --compressed.

A transfer phase that grows with the size of the body, and only with the size of the body, is your bandwidth.

Your resolver is the cause

gexbot does not control your resolver. A value above about 100 ms points at the DNS server your network uses.

Most HTTP clients cache a resolved address. A DNS cost on every call means your client makes a new connection each time. Read the next section.


Reuse the connection

The DNS, TCP and TLS phases are paid once for each new connection. A client that keeps the connection open pays them once and then reads only the server and transfer phases.

A client that opens a new connection for each call pays all of them every time. On a long route this more than doubles each call, and no change at gexbot corrects it.

  • Python: use one requests.Session() or one httpx.Client for the life of the program. A bare requests.get() opens a new connection each time.
  • Node.js: set keepAlive on the agent. undici and fetch do this for you.
  • Go: reuse one http.Client. Do not build a new one for each call.
  • C#: reuse one HttpClient, or use IHttpClientFactory. A using block around a new HttpClient for each call is the classic mistake.

Compare time_connect on a first call and on a later call to confirm that your client reuses the connection.


Poll at the rate the data changes

Live calculations refresh at most once each second in market hours. A request more often than that returns the same data and adds load that makes every call slower, for you and for everyone else.

Use the Quant WebSocket feed to follow many tickers. It sends each update once, and it removes the poll entirely.


Measure without an API key

Two routes need no key at all, so they are safe to call in a loop while you test a connection.

# The server clock. It does no work, so the total is almost all network.
curl -o /dev/null -s -w "ttfb %{time_starttransfer}  total %{time_total}\n" \
  -H "User-Agent: my-app/1.0" https://api.gex.bot/time

# The diagnostics probe on the API host.
curl -o /dev/null -s -w "ttfb %{time_starttransfer}  total %{time_total}\n" \
  -H "User-Agent: my-app/1.0" https://api.gex.bot/diagnostics/ping

Neither route is cached, so each call measures the network and not a cache. Do not use /tickers for this: it is cached for a day, and a cache can answer it.


Check your clock

/time returns server_time_ms, the gexbot clock in epoch milliseconds. Compare it against your own clock. A machine whose clock is wrong reads correct timestamps as stale data.

Use the value in the body. The HTTP Date header has a resolution of one second, which is too coarse for this.


In a browser

The gexbot web app has a diagnostics page at Portal → Diagnostics. It measures each host, breaks each request into phases, reports the address and country gexbot sees, and gives you a block of text to paste into a support message.


Send this to support

Include this with your message to support@gexbot.com:

  1. The full curl -w output above, from three or more attempts.
  2. Your city and country, and your internet provider.
  3. Whether a VPN or a corporate proxy is in the path.
  4. The time of the slow calls, with the time zone.
  5. The exact route you called.

The phase values are what make the report usable. A message that says only "the API is slow" starts the investigation from nothing.

On this page