Tradovate API

Tradovate WebSocket 'Connection to Remote Host Lost'

The socket runs fine for hours, then dies with Connection to remote host was lost, often right around the 24-hour mark. Here's what's actually failing and the heartbeat, reconnect, and token pattern that keeps a feed alive indefinitely.

Reviewed by the PickMyTrade Trading Systems Team Last updated
· 8 min read
Browser DevTools showing a Tradovate WebSocket connection closed with connection to remote host lost

When your bot is streaming ES or NQ quotes around the clock, nothing kills a strategy faster than a Tradovate WebSocket that quietly dies with “Connection to remote host was lost.” It's one of the most common Tradovate API headaches: the socket runs fine for hours, then drops, very often right around the 24-hour mark, and takes your live market data and order routing down with it. Sometimes you'll see it as a raw WebSocket close (code 1006, “abnormal closure”). Sometimes it looks like a mass disconnection. Sometimes it's just a dead feed that never throws an exception at all.

There's no single magic setting that fixes this. What actually keeps a socket alive is a handful of habits working together: 2.5-second heartbeats, automatic reconnection, token renewal, and cycling the connection before it goes stale. PickMyTrade bakes this reconnect-and-re-auth logic in, so your TradingView alerts keep reaching Tradovate even when a hand-rolled socket would have quietly fallen over.

Quick Checklist for a Lost Tradovate WebSocket

  • Heartbeat every 2.5 seconds, send an empty [] frame so the server never marks your client idle and closes it.
  • Don't trust setInterval in a browser tab, background throttling drops your timer below 2.5s and kills the socket. Use a message-timestamp check instead.
  • Auto-reconnect on every close, when the socket closes, reopen it, re-authorize, and resubscribe to your market-data symbols.
  • Renew the token before it expires, call renewAccessToken roughly 15 minutes before the ~90-minute access-token expiry, and keep sessions within Tradovate's concurrent-session limit.
  • Cycle the connection before ~24 hours, tear down and reopen the socket on a timer instead of waiting for the server to drop it.
  • Back off when you reconnect, space out retries so a reconnect storm doesn't trip Tradovate's rate limits and lock you out.

What "Connection to Remote Host Was Lost" Means

“Connection to remote host was lost” is Tradovate's way of telling you the WebSocket to its servers is closed and no longer usable. It's a transport-level event, not a rejected order, not a bad request. The pipe itself went away. Under the hood this usually shows up as an abnormal WebSocket close (close code 1006), meaning the connection dropped without a clean close handshake, so your client can't always tell you exactly why.

Here's the part that trips people up: a lost connection is normal and expected on a long-lived feed. Networks blip, load balancers recycle, idle sockets get pruned, tokens expire, and very long sessions get cycled server-side. Even a perfectly well-behaved client streaming live data can lose the socket after enough hours of uptime. So the goal isn't a socket that never drops, that's impossible. The goal is a client that notices the drop instantly and recovers on its own, without you babysitting it.

That distinction matters for risk. If your feed dies silently and your code still assumes it's connected, you can miss fills, miss stop triggers, or fire orders into a stale view of the market. Treat every WebSocket as disposable and every disconnect as a routine event to handle, not an emergency.

Top Causes of a Dropped Tradovate WebSocket

1. Missed heartbeats (server idle timeout)

This is the single most common cause. Tradovate's WebSocket protocol requires the client to send a heartbeat every 2.5 seconds, a frame whose text is an empty array, [], to prove it's still alive. If the server goes 2.5 seconds without hearing from you and isn't actively streaming data to you, it treats the client as idle and closes the connection. And here's the catch: while the server is actively pushing messages (say, a busy market-data subscription), it won't send its own heartbeats, so keeping the [] frames flowing is entirely on your client.

Tradovate WebSocket frames view showing empty-array heartbeat messages sent every 2.5 seconds

2. Browser / timer throttling

If you build in the browser and schedule heartbeats with setInterval or setTimeout, you're walking into a subtle trap: browsers throttle timers in background or inactive tabs, stretching your 2.5-second interval out to several seconds. The moment it exceeds the window, the server closes the socket. Don't lean on setInterval, time your heartbeats from the last message you actually received instead.

3. Access token expiry

Your WebSocket is authorized once with an access token, and that token has a limited lifespan, around 90 minutes from creation per Tradovate's API docs. When the token behind an active connection expires, the connection is no longer authenticated and can be dropped. A long-running client that never renews its token will watch the socket die on a predictable cadence.

4. Long-lived connections over ~24 hours

Maintaining a connection for more than 24 hours is a recognized cause of drops on its own. Even with perfect heartbeats and a fresh token, a socket that's been open for roughly a day is a prime candidate to get recycled server-side. That's why a raw connection that “worked all afternoon” mysteriously dies overnight.

5. Reconnect storms and the session limit

When a socket drops, naive code often hammers the server with immediate, back-to-back reconnect attempts. That can trip Tradovate's request rate limits and make things worse, and repeatedly re-authenticating (instead of renewing) can bump you against the concurrent-session cap. The result is a client stuck in a reconnect loop that never stabilizes.

How to Fix a Lost Tradovate WebSocket Connection: Step-by-Step

Send a Heartbeat Every 2.5 Seconds, the Right Way

1

Timestamp every incoming message

On every message you receive over the socket, record a timestamp (a plain new Date() is fine).

2

Compare against the last heartbeat

On a short cadence, compare “now” against the timestamp of the last message received.

3

Send the heartbeat when needed

If more than 2500 ms have elapsed since the last message, send a single heartbeat frame containing exactly [] using the socket's send method.

4

Avoid a fixed setInterval

Drive this from a message-based check rather than a fixed setInterval, so browser throttling can't silently stretch the gap and disconnect you.

This one habit resolves the majority of “connection to remote host was lost” reports, because it directly satisfies the server's idle-timeout rule.

Add Automatic Reconnect and Resubscribe Logic

1

Detect the drop immediately

Attach a handler to the socket's close (and error) event so a drop is detected immediately.

2

Open a fresh socket

On close, assume the connection was lost in error and open a fresh WebSocket to the same endpoint.

3

Re-send the authorize request

Re-send the authorize request with a currently valid access token, a new socket isn't authorized just because your previous one was.

4

Resubscribe to everything

Resubscribe to every market-data symbol and every user/order sync you were listening to before, since subscriptions don't survive a reconnect.

5

Back off exponentially

Wrap reconnect attempts in an exponential backoff (for example, wait 1s, then 2s, then 4s, capped) so a prolonged outage doesn't turn into a rate-limit lockout.

Renew the Access Token and Re-Authorize the Socket

1

Schedule a renewal ahead of expiry

When you first authenticate, read the token's expiration time from the auth response and schedule a renewal ahead of it.

2

Call renewAccessToken early

Call renewAccessToken roughly 15 minutes before the token expires. Renewing (rather than re-authorizing from scratch) extends your current session instead of opening a new one, which keeps you under Tradovate's concurrent-session limit.

3

Re-authorize the active socket

After renewing, make sure the active socket is authorized with the fresh token. The safest approach is to reconnect and send a new authorize frame with the renewed token, because renewing the token alone doesn't always keep an already-open socket authenticated.

Tradovate renewAccessToken API response showing a new access token and its expiration time

Confirm API Access Is Enabled and You're Within the Session Limit

1

Confirm API Access is enabled

In the Tradovate web trader, open Application Settings and confirm API Access (the API add-on) is enabled for your account, a socket can't stay authorized against an account that isn't entitled for API use.

2

Check your concurrent-session count

Check that you aren't running more concurrent sessions than Tradovate allows across your bot, the desktop app, TradingView, and any other connections; extra sessions can knock your API connection offline.

3

Confirm your market-data entitlement

If you need real-time API market data specifically, confirm your market-data entitlements are in place, since an unauthorized data subscription can cause the feed to close.

Tradovate Application Settings showing the API Access add-on enabled

Proactively Cycle the Connection Before 24 Hours

Rather than waiting for the server to drop a day-old socket, get ahead of it. On a timer, comfortably under the ~24-hour ceiling, close your existing WebSocket cleanly and open a new one with a freshly renewed token, then re-authorize and resubscribe. Since your reconnect path already exists (you built it in the step above), a scheduled cycle is just a controlled version of the same routine. It turns a surprise 3 a.m. disconnect into a planned, invisible refresh.

Troubleshooting Table

Error / State What it means Fix
Connection to remote host was lostThe WebSocket to Tradovate was closed and is unusableAuto-reconnect, re-authorize, and resubscribe; make sure heartbeats are flowing
WebSocket closed with code 1006Abnormal closure, dropped without a clean handshakeHandle it as a normal disconnect; reopen the socket with backoff
Socket dies every ~90 minutesThe access token behind the connection expiredCall renewAccessToken ~15 min before expiry and re-authorize the socket
Feed drops after many hours / overnightLong-lived connection recycled (often around 24 hours)Proactively cycle the connection on a timer under ~24 hours
Disconnects only when the tab is in the backgroundBrowser throttled your setInterval heartbeat below 2.5sTime heartbeats from the last received message, not a fixed interval
Reconnect loop / new drops after reconnectingReconnect storm tripping rate limits or the session capAdd exponential backoff; renew tokens instead of re-authing new sessions
Data feed silent but no error thrownSocket half-open; server stopped sending, client didn't noticeEnforce the 2.5s heartbeat and treat missed heartbeats as a disconnect

Prevent This with PickMyTrade

If your goal is simply to get TradingView alerts into Tradovate reliably, you don't have to hand-build and babysit all of this socket plumbing yourself. PickMyTrade sits between TradingView and Tradovate and keeps the connection healthy for you.

  • Managed Reconnect Logic, automatic reconnect, re-authorization, and resubscription on every drop, so a lost socket recovers without you writing or maintaining the code.
  • Token Renewal Built In, sessions are refreshed before they expire, keeping the connection authenticated instead of dying on the ~90-minute token clock.
  • Connection Cycling, long-lived connections are recycled proactively, so the ~24-hour drop never catches your automation offline.
  • Rate-Limit-Safe Routing, reconnects and order flow are spaced out to respect Tradovate's limits, avoiding the reconnect-storm lockouts that plague raw sockets.

Stop Babysitting Your Socket

Ready to stop babysitting your socket? Start your free 5-day trial, link alerts today and trade rejection-free.

Start Your Free 5-Day Trial

Frequently Asked Questions

Almost always because the client stopped sending its 2.5-second heartbeat, the access token expired, or the connection simply aged out (long sessions past ~24 hours get recycled). Add heartbeats, token renewal, and auto-reconnect and the drops become a non-event.

Every 2.5 seconds. Send a frame whose text is an empty array, []. If the server goes 2.5 seconds without hearing from you while it isn't streaming data to you, it closes the socket for inactivity.

Browsers throttle setInterval/setTimeout in inactive tabs, so your interval stretches past 2.5 seconds. Instead of a fixed interval, timestamp each received message and send a heartbeat only when more than 2500 ms have passed since the last one.

An access token lasts around 90 minutes per Tradovate's API docs. Call renewAccessToken about 15 minutes before it expires to extend the session, then make sure the socket is authorized with the renewed token, reconnecting and re-sending an authorize frame is the safest way to keep it authenticated.

Yes. A new socket starts with no subscriptions, so after you reopen and re-authorize you must resubscribe to every symbol and sync you were listening to before the drop.

No. It's an expected characteristic of very long-lived connections. The reliable answer is to proactively cycle the connection before it reaches that age rather than waiting for the server to drop it.

Immediate, back-to-back reconnect attempts hammer the server and can trip Tradovate's request limits, and repeatedly re-authenticating can bump the concurrent-session cap. Add exponential backoff between attempts and renew tokens instead of spawning new sessions.

If you only need TradingView alerts to reach Tradovate, yes, PickMyTrade manages the heartbeat, token renewal, reconnection, and connection cycling for you, so you don't maintain a resilient WebSocket client yourself.

This guide is for educational and informational purposes only and is not financial, investment, or trading advice. Trading futures and other leveraged products carries a substantial risk of loss and is not suitable for every investor. PickMyTrade is an independent third-party automation platform and is not affiliated with, endorsed by, or sponsored by Tradovate, Inc. "Tradovate" and all related names, logos, and trademarks are the property of their respective owners. Platform features and steps change over time, so always confirm the current process in the official Tradovate platform and documentation before acting.