SharePoint Online throttles API calls to protect service stability. Every bulk operation - migration jobs, permission scans, and storage reports - hits these limits eventually. Here's what matters most for admins running large-scale jobs.
What triggers SharePoint throttling
SharePoint Online applies throttling based on resource consumption, not a simple request count. Microsoft uses a resource unit model: each API call consumes a number of resource units proportional to its cost. A simple item read is cheap; a complex search query, a large file upload, or a list enumeration across thousands of items costs significantly more. Exceed that budget within the rolling window and SharePoint returns HTTP status 429 Too Many Requests.
Two authentication contexts can trigger throttling independently:
- Per-user throttling: applies when requests use a delegated user token (the signed-in account's identity). The budget is tied to the user account. Running a scan or migration as a regular user will exhaust that user's resource budget faster than expected.
- Per-application throttling: applies when requests use app-only authentication (a registered Entra ID application with application permissions). App-only tokens carry a larger resource budget, but the tenant still has an aggregate cap shared across all applications.
SharePoint throttling limits at a glance
| Limit type | Threshold | Auth context | Notes |
|---|---|---|---|
| User-mode sustained call rate | Approximately 1 request per second (sustained average) | Delegated user token | Short bursts above this are tolerated; sustained high rates trigger 429 responses |
| App-only call rate | Higher than user-mode; varies by tenant size and load | App-only token | Microsoft does not publish an exact number; the threshold is monitored dynamically |
| Tenant-level aggregate cap | Shared across all users and applications in the tenant | Both | A heavy scripted operation by one admin can briefly reduce available headroom for other tenant users |
| Large file upload | Triggered by bandwidth and concurrent session count, not API request rate | Both | Uploading many large files simultaneously saturates SharePoint's ingest resources and triggers back-pressure responses |
| Search query rate | Lower budget than direct REST reads | Both | Content-search-based scans are throttled more aggressively than direct list item reads; prefer direct enumeration for bulk scans |
| Throttle window duration | Seconds to minutes, indicated by Retry-After header | Both | Aggressive retries during the throttle window extend its duration; honour Retry-After exactly |
Microsoft does not publish exact numeric thresholds for most of these limits. The system is intentionally dynamic: thresholds adjust based on current tenant load, time of day, and the resource profile of the operations in flight.
Reading the Retry-After response header
Every 429 response from SharePoint includes a Retry-After HTTP header. The value is an integer number of seconds. A well-behaved tool or script reads this header, pauses for the indicated duration, and then retries the exact same request.
| Response | Meaning | Correct action |
|---|---|---|
HTTP 429 with Retry-After: 30 |
Throttled; wait 30 seconds before retrying this call | Sleep 30 seconds, then retry the same request with full backoff logic |
HTTP 429 with no Retry-After header |
Throttled; retry interval not specified | Apply exponential backoff starting at 15 to 30 seconds |
HTTP 503 Service Unavailable |
SharePoint temporarily overloaded or unavailable | Treat identically to 429; apply exponential backoff and retry |
| Repeated 429 across multiple retries | Sustained overload; throttle window not yet cleared | Increase backoff interval; consider pausing the job entirely and resuming off-peak |
A script or tool that ignores Retry-After and retries immediately continues to be throttled and makes no forward progress. Aggressive retries during the throttle window signal continued high load and extend the throttle window further. Honour the header - it is the fastest path through.
Strategies to reduce throttling impact on migration jobs
| Strategy | Effect | Implementation note |
|---|---|---|
| Use app-only authentication | Larger resource budget than delegated user tokens | Register a dedicated Entra ID application with Sites.ReadWrite.All and use client credentials flow for migration jobs |
| Schedule operations off-peak | Tenant aggregate load is lower outside business hours | Late evening or early morning in the tenant's primary time zone typically yields the most headroom |
| Honour Retry-After precisely | Prevents extended throttle windows from rapid-retry behaviour | Required in any custom PowerShell script; built into well-designed migration tools automatically |
| Reduce transfer concurrency | Fewer parallel threads reduce simultaneous API call volume | Slightly slower throughput per hour, but more consistent progress and fewer throttle events on busy tenants |
| Trim version history before migrating | Fewer items to read, write, and transfer means fewer total API calls | See the version history trim guide; trimming before migration is one of the highest-return preparation steps available |
| Avoid search-based enumeration | Direct list reads are cheaper per item than search queries | Prefer /_api/web/lists/getbytitle/... style enumeration over SharePoint Search REST queries for inventory scans |
For context on the broader storage and capacity limits that migration planning needs to account for, see the SharePoint Online Limits and Quotas Reference.
Frequently Asked Questions
Why does SharePoint return a 429 error?
HTTP 429 means the resource unit budget for your user account or application has been exceeded in the current rolling window. SharePoint uses a dynamic resource model rather than a fixed request-per-second counter. The 429 response always includes a Retry-After header specifying how long to wait before retrying.
How long should you wait after a 429 response?
Read the Retry-After header value and wait exactly that many seconds. Do not retry immediately and do not use a fixed sleep that ignores the header. Aggressive immediate retries extend the throttle window and slow overall progress.
Does app-only authentication prevent throttling?
App-only tokens have a larger resource budget than user-mode delegated tokens and will handle higher sustained call rates before triggering throttling. They do not eliminate throttling entirely. The tenant still has an aggregate cap, and app-only jobs still need to honour 429 Retry-After responses when they occur.