Skip to content

fix: throttle Azure OpenAI embedding calls and back off on rate limits - #49

Open
janton10 wants to merge 1 commit into
i-dot-ai:mainfrom
janton10:fix/embed-rate-limit
Open

fix: throttle Azure OpenAI embedding calls and back off on rate limits#49
janton10 wants to merge 1 commit into
i-dot-ai:mainfrom
janton10:fix/embed-rate-limit

Conversation

@janton10

@janton10 janton10 commented Apr 25, 2026

Copy link
Copy Markdown

make load-data hansard reliably 429s on the default Azure S0 tier. load_all_contributions fans out 4 contribution types in parallel x N pages each, batch_size=100 puts ~30k tokens per call (well over 350k TPM in bursts), and @retry(stop_after_attempt(3)) retries instantly with no backoff and ignores Retry-After.

Patch:

  • Throttle every embeddings.create with an aiolimiter + semaphore. Tune via OPENAI_EMBED_RATE_PER_SECOND / OPENAI_EMBED_MAX_CONCURRENCY / OPENAI_EMBED_BATCH_SIZE. Defaults sized for S0; raise on larger quotas.
  • Tenacity now uses wait_random_exponential(2, 60), retries only on RateLimitError / APITimeoutError / APIConnectionError, up to 8 attempts.
  • max_retries=6 on the Azure client so the SDK honours Retry-After first.
  • Default batch_size 100 to 32.
  • load_all_contributions runs types sequentially; pages still parallelise within each type.

No new deps. 90-day Hansard load completes on S0 with these defaults.

@janton10 janton10 closed this Apr 25, 2026
@janton10 janton10 reopened this Apr 25, 2026
The data loader previously fanned out all 4 contribution types
("Spoken", "Written", "Corrections", "Petitions") concurrently in a
TaskGroup, with each type spawning one task per page. With nothing
limiting concurrent embed_batch calls, the loader could trivially
exceed Azure's TPM quota at lower tiers. The retry decorator
stop_after_attempt(3) had no wait, so it ignored the Retry-After header.

Changes:
- Add an aiolimiter + semaphore around every embeddings.create call,
  configurable via OPENAI_EMBED_RATE_PER_SECOND, OPENAI_EMBED_MAX_CONCURRENCY,
  OPENAI_EMBED_BATCH_SIZE env vars.
- Switch tenacity to wait_random_exponential with jitter, retry only on
  RateLimitError / APITimeoutError / APIConnectionError, up to 8 attempts.
- Pass max_retries=6 to AsyncAzureOpenAI so the SDK honours Retry-After
  before tenacity takes over for longer waits.
- Reduce default batch_size from 100 to 32 (~10k tokens/call) to fit
  the per-minute quota.
- Run load_all_contributions sequentially; pages within each type still
  parallelise.
@janton10
janton10 force-pushed the fix/embed-rate-limit branch from e92ced3 to 5078f8b Compare April 25, 2026 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants