Concurrent Requests
Your requests are not rate-limited, but the number of concurrent market-data requests is capped by your subscription tier. Concurrency is account-wide and set by your highest subscription tier across asset classes:
| Tier | Concurrent requests |
|---|---|
| Free | 1 |
| Value | 2 |
| Standard | 4 |
| Pro | 8 |
Fire your whole batch
You can issue more requests than your tier allows. The extra requests are queued and run in order, so a burst completes as fast as your tier permits without you managing anything. There is nothing to configure. The idiomatic pattern is to launch the whole batch and let it run at your tier's rate:
import asyncio
from thetadatadx import AsyncClient
client = AsyncClient.from_file("creds.txt")
async def pull(day):
return await client.stock_history_trade_async("AAPL", day)
results = asyncio.run(asyncio.gather(*(pull(d) for d in days)))With a Pro subscription, eight of those requests run concurrently and the rest wait their turn. On Free, they run one at a time. Same code either way.
One giant request, split for you
The pattern above parallelizes work you have already split into many requests. The SDK also does the reverse for you: a single large history request has its time or date range split into equal pieces, run in parallel across your tier's concurrent-request budget, and reassembled into exactly the rows one request would have returned. You write one ordinary query and it runs at your tier's concurrency. This is on by default.
See Bulk Downloads for the full picture: how the split works, buffered versus streaming delivery, the bulk_fetch and shard_concurrency knobs, API examples, and measured performance.
When parallelism pays
Concurrency multiplies throughput on multi-request workloads: per-day backfills, per-contract chain pulls, anything you can split with split_date_range. For a single large request you no longer have to split it yourself, since bulk_fetch does it automatically (above); splitting manually still works when you want direct control over the pieces.
If the service reports exhaustion during peak hours, the SDK retries with backoff before surfacing an error. Long-running bulk jobs should expect occasional retries at peak; see Data Issues? if a job stalls beyond that.