When teams evaluate a market data API, the first number they look at is usually the unit price: how much per million requests. But for real-time market data, the billing model matters far more than the unit price. The reason is simple — live market data is a push workload, not a query workload. Force a query-based billing model onto a push-based workload, and your costs grow along two axes at once: number of symbols and time.
Two billing models, two very different outcomes
Pricing in this space falls into two buckets:
- Per-request billing — every HTTP call consumes quota. Well suited to historical pulls, scheduled snapshots, and low-frequency queries.
- Per-message billing — every tick pushed over a WebSocket is billed. The more symbols you track and the more active the market, the steeper the curve gets.
The problem: many platforms apply per-message billing to streaming too. And live market data generates an astronomically large message volume by nature.
Run the numbers: REST polling for 500 symbols
Say you need to monitor 500 symbols with one-second refresh.
TIQEX's multi-market quote endpoint accepts up to 50 codes per call, so one full polling cycle takes 10 requests:
- 10 requests/sec × 86,400 sec = 864,000 requests/day
- Roughly 25.9 million requests/month
What does that mean against plan quotas? Growth allows 500,000 calls per month; Pro allows 5,000,000. Polling 500 symbols every second exceeds even the Pro quota.
The same 500 symbols over WebSocket
- One WebSocket connection subscribes to all 500 symbols
- At an average of 2 ticks per symbol per second → 1,000 messages/sec
- Roughly 2.59 billion messages/month
Now multiply that by your vendor's per-message rate. Even at an aggressive $0.5 per million messages, the monthly bill exceeds $1,300. At $5 per million, it lands at $12,960 — for 500 symbols. Scale to a thousand symbols and the cost structure collapses entirely.
The key point: symbol count is a product requirement. It will not shrink to fit your budget. Per-message billing is therefore a cost structure that only gets worse over time.
Handshake billing: the only structure that stays flat
This is exactly why TIQEX bills the handshake rather than the messages:
- Establishing a WebSocket connection counts toward your daily quota and per-minute rate limit (RPM)
- Ticks pushed after the handshake are not metered per message
- As a result, streaming costs stay nearly constant whether you subscribe to 500 symbols or 5,000
In other words: symbols scale, cost doesn't.
When to use which
| Scenario | Recommended model | Why |
|---|---|---|
| Live monitoring, trading terminals, alerting | WebSocket streaming | Continuous push; flat cost after handshake billing |
| Historical candle backfill, backtest data prep | REST queries | One-off batch pulls with predictable request counts |
| Low-frequency snapshots (minute / hourly) | REST queries | Small request volume, simple to implement |
| Portfolio monitoring across 1,000+ symbols | WebSocket streaming | REST polling breaks any quota tier |
TIQEX states the principle plainly on its pricing page: Use WebSocket for live ticks; REST for queries and backfill.
Latency: the other overlooked difference
Beyond cost, the two models differ sharply on latency.
REST polling latency has two components: the polling interval plus network round-trip time. One-second polling means an average delay of 500ms (1,000ms worst case) on top of each request's RTT. For minute-scale decisions that is fine. For market making, arbitrage, or real-time alerting, 500ms is enough to invalidate the signal entirely.
WebSocket inverts the direction: the server pushes the moment a quote changes, so latency is governed by the network path alone, with no penalty for waiting on the next poll cycle. TIQEX documents 78ms data latency.
So streaming is not just cheaper — it is faster, and both advantages come from the same design decision.
Verify your own usage profile in Python first
Before picking a plan, work out your real request volume. This script derives monthly consumption from the documented batch limit:
import math
symbols = 500
batch_size = 50 # /api/v1/market/quote accepts up to 50 codes per call
interval_sec = 1 # one-second refresh
requests_per_poll = math.ceil(symbols / batch_size)
per_day = requests_per_poll * (86400 // interval_sec)
per_month = per_day * 30
print(f"requests per poll: {requests_per_poll}")
print(f"requests per day: {per_day:,}")
print(f"requests/month: {per_month:,}")
# requests per poll: 10
# requests per day: 864,000
# requests/month: 25,920,000
Swap in your real symbol count and you will immediately see whether REST polling is viable. If your monthly volume already exceeds your plan quota, the right fix is not a bigger plan — it is switching to a streaming subscription.
Migrating from REST polling to streaming: three steps
The migration is simpler than it sounds. In Python, subscribe to the TIQEX streaming endpoint with websockets:
import asyncio, json, os
import websockets
API_KEY = os.environ["TIQEX_API_KEY"]
SYMBOLS = ["BTCUSDT", "ETHUSDT", "AAPL", "EURUSD"]
async def main():
async with websockets.connect(
"wss://api.tiqex.io/api/v1/market/stream",
additional_headers={"X-API-Key": API_KEY}, # use extra_headers on websockets < 14
) as ws:
await ws.send(json.dumps({
"action": "subscribe", # first message must be subscribe
"market": "crypto",
"symbols": SYMBOLS,
}))
async for raw in ws:
frame = json.loads(raw)
if not frame.get("succ"):
print("error:", frame.get("code"), frame.get("msg"))
continue
data = frame["data"]
if data.get("type") == "subscribed":
print("subscribed:", data.get("symbols"))
elif data.get("type") == "tick":
tick = data["tick"]
print(tick["symbol"], tick["last"], tick["at"])
asyncio.run(main())
Three things matter here:
- The first message must be
subscribe, carryingmarketandsymbols. Symbol count is capped by your plan. - You receive a
type=subscribedacknowledgement frame first, then a continuous stream oftype=tickframes. Production code should wait for the acknowledgement before processing business logic. - Authentication uses the
X-API-Keyheader (orAuthorization: Bearer). WebSocket and REST share the same key.
The full subscription protocol, field definitions, and error codes live in the WebSocket streaming docs; for the semantic differences between the two styles, see polling vs streaming compared.
Migration checklist
- Confirm plan entitlements. Markets differ by plan. Live data requires the matching tier, otherwise you get
MARKET_NOT_ENABLED(403). - Check the delayed flag. A
delayedfield of true in a REST response means that market is currently serving delayed data. Always validate it in production. - Implement heartbeat and reconnect. Long-lived connections need reconnect logic with backoff — see the live quotes over WebSocket guide.
- Separate handshake cost from push cost. Handshakes consume quota, so do not "refresh" a connection by reconnecting frequently.
- Handle 429 correctly.
DAILY_LIMIT_EXCEEDED,MONTHLY_LIMIT_EXCEEDED, andRATE_LIMIT_EXCEEDEDall return 429 and need distinct handling. - Estimate with a tool. The quota calculator lets you model quota needs at different symbol scales.
Confirming the migration worked
After switching, validate with three signals:
- Quota consumption flattens out. Under handshake billing, daily quota use should track connection count — not market volatility.
- End-to-end latency drops. Compare the tick's
atfield (an RFC3339 timestamp) against your local receive time. - 429s disappear. If
DAILY_LIMIT_EXCEEDEDstill fires after migration, a residual REST poller is still running somewhere.
FAQ
Do WebSocket pushes count against my REST quota?
Not per message. The connection handshake counts toward daily quota and RPM; ticks pushed after the handshake are not metered. That is precisely why streaming cost stays flat.
Why does one-second polling of 500 symbols exceed the quota?
Because the batch limit is 50 codes per call, so a full cycle needs 10 requests. Ten requests per second × 86,400 seconds is 864,000 requests/day — about 25.9 million per month, well past the Pro plan's 5,000,000 monthly allowance.
Can I use REST and WebSocket together?
Yes, and you should. Use WebSocket for live pushes and REST for historical backfill and low-frequency queries. That is TIQEX's documented recommendation.
How do costs change as I add symbols?
With streaming, barely at all — handshake billing is independent of symbol count. With REST polling, growth is linear: double the symbols, double the cost.
How do I confirm I am getting live data rather than delayed data?
Check the delayed field in REST responses and your plan's market entitlements. On Growth, crypto and metals are live while US stocks, A-shares, and Hong Kong are delayed; Pro covers all markets live.
Next steps
Work out your real request volume first, then choose a billing model. The free tier includes delayed crypto, US stocks, and metals with no credit card required — enough to validate your integration end to end. The Python market data guide gets your first request running in about ten minutes.
Check live versus delayed entitlements by market: crypto, US stocks, and forex.