Content Understanding (2025-11-01) 429 on ContentAnalyzers_Analyze and GetResult at ~120 concurrent requests

AWTG Maneesh 0 Reputation points
2026-11-05T10:36:17.9766667+00:00

Hi,

We use Azure AI Content Understanding to parse course documents (PDF textbooks and handouts) for an education platform. We hit 429 throttling during upload bursts and want to know the actual limits and how to raise them. We also have support case 2611040050002159 open; this post is to get an engineer's view in parallel.

Setup

  • Resource: AIServices, S0, UK South
  • API: REST, 2025-11-01, analyzer prebuilt-documentSearch, processingLocation=geography (default model deployments)
  • Client: plain HTTPS (Python urllib, no SDK), calling the resource endpoint directly with no gateway or proxy in between
  • Each PDF is split into parts of 25 pages; each part is one :analyze request with the file inline (base64). Up to 24 parts per document run at the same time, and each in-flight part polls analyzerResults/{id} every 2 s.

What we measured (4 Nov 2026, same 2-page PDF per request)

┌─────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────┐

│ Concurrent requests │ Result │

├─────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤

│ 1 │ 202, done in 5 s, no throttling │

├─────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤

│ 24 │ all 202, done in 5 s, no throttling │

├─────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤

│ 120 │ 163 Analyze 429s and 31 GetResult 429s (all Retry-After: 1); all eventually succeeded after 5–65 s │

└─────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────┘

A real 1,610-page book (65 parts, 24 concurrent) completed in 134 s with no errors.

Please help us with a human support engineer as we have raised a ticket already and request if u can help through a call

Azure Content Understanding in Foundry Tools
0 comments No comments

1 answer

Sort by: Most helpful
  1. AI answer

    2026-11-05T10:37:57.4166667+00:00

    Your S0 resource is subject to 1,000 analyzed pages/images per minute and 3,000 operations per minute, so cap aggregate submissions and polling below both limits; Microsoft does not publicly document these Content Understanding quotas as adjustable, so any increase or backend-capacity review must proceed through your existing Azure support case.^1^

    What the measurements indicate

    The published S0 resource limits are:

    Limit S0 value
    Analysis throughput 1,000 pages/images per minute
    Operations 3,000 operations per minute

    Your 120-request test generated both:

    • 120 asynchronous Analyze operations.
    • Up to 120 GetResult requests every two seconds while those analyses remained active.

    At full polling concurrency, the GET traffic alone can reach approximately:

    120 operations × 30 polls/minute = 3,600 GetResult calls/minute
    

    That is above the documented 3,000 operations/minute, before counting Analyze submissions and retries. This is consistent with both Analyze and GetResult returning 429 during the burst. Conversely, 24 active operations polling every two seconds generate about 720 GETs/minute, which is consistent with the successful book run.

    The page limit must be enforced independently:

    submitted parts/minute × pages/part <= 1,000 pages/minute
    

    These calculations are workload planning estimates; the documentation does not define the exact accounting window or whether every rejected attempt is counted identically.

    1. Keep the current 24-analysis concurrency as the initial ceiling. Your real workload already completed successfully at that level.
    2. Use one global limiter for POST and GET traffic. Do not give each document its own independent 24-request pool; otherwise simultaneous books can multiply resource-wide traffic.
    3. Budget below 3,000 operations/minute, leaving capacity for retries and other analyzer operations.
    4. Budget below 1,000 submitted pages/minute.
    5. Honor Retry-After on every 429, adding jitter so all workers do not retry simultaneously. Queue delayed work rather than holding many blocked workers. Microsoft’s resilience guidance recommends respecting retry headers, bounded retries, and gradual traffic recovery.^2^
    6. Poll only operations that are still Running or NotStarted, and stop immediately at a terminal state. The documented normal interval is one to two seconds, so your two-second interval is valid; it is the aggregate number of pollers that needs limiting.^3^

    A minimal urllib wrapper can handle the returned delay:

    import random, time
    from urllib import request, error
    
    def send(req, attempts=8):
        for attempt in range(attempts):
            try:
                return request.urlopen(req, timeout=120)
            except error.HTTPError as exc:
                if exc.code != 429 or attempt == attempts - 1:
                    raise
                retry_after = exc.headers.get("Retry-After")
                delay = float(retry_after) if retry_after else min(2 ** attempt, 30)
                time.sleep(delay + random.uniform(0, 0.25))
    

    Also consider submitting larger PDF ranges instead of fixed 25-page pieces when your processing requirements permit it. Asynchronous PDF analysis now supports up to 2,000 pages and 200 MB, so the 1,610-page book might not require 65 separate Analyze operations if it fits the file-size limit.^1^ Fewer analysis operations also mean fewer independently polled result URLs.

    Capture evidence for the support engineer

    For API 2025-11-01, add this header to every result GET, not merely the Analyze POST:

    x-ms-diagnostics: true
    

    Completed responses can then include result.infos, such as LLMStats latency information. The property is optional and its message should be treated as diagnostic text rather than stable telemetry.^4^

    Add the following to the existing case:

    • Resource ID and UK South region.
    • Exact UTC test windows.
    • API version, analyzer ID, S0 tier, and processingLocation.
    • Concurrency, page size, submission rate, and polling rate.
    • Full 429 response body and x-ms-error-code.
    • Retry-After, request/correlation IDs, and client-generated x-ms-client-request-id.
    • Separate counts for Analyze 429s and GetResult 429s.
    • Azure Monitor total calls, throttled calls, and latency around the test window.
    • A request to confirm whether throttling came from the published resource limits or transient backend capacity.
    • A request to confirm whether the two Content Understanding S0 limits are adjustable for this resource and region.

    Microsoft Q&A cannot attach an engineer or schedule a call on an existing private support case. Request a callback/Teams session in the case communication, include availability and time zone, and ask for escalation to the Azure AI Content Understanding service team if quota accounting or regional capacity must be inspected.

    The REST contract confirms that Analyze is an asynchronous POST returning Operation-Location, followed by result retrieval through the operation URL.^5^


    References

    1. Azure Content Understanding in Foundry Tools service quotas and limits
    2. Design throttling to improve resilience
    3. Quickstart: Use Azure Content Understanding in Foundry Tools (programming-language-rest)
    4. Retrieve diagnostics from Azure Content Understanding in Foundry Tools
    5. Content Analyzers - Analyze - REST API (Azure Azure AI Services)
    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.