Skip to content

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:

TierConcurrent requests
Free1
Value2
Standard4
Pro8

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:

python
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.

Released under the Apache-2.0 License.