Developing for Atlassian Government Cloud?
This content is written with standard cloud development in mind. To learn about developing for Atlassian Government Cloud, go to our Atlassian Government Cloud developer portal.
Effective February 2, 2026, Atlassian will begin enforcement of new points-based API rate limits and tiered quota rate limits for Jira and Confluence Cloud apps.
This change is designed to ensure consistent performance and fair usage. The new rate limits will apply to all Forge, Connect, and OAuth 2.0 (3LO) apps. If your app integrates with Jira or Confluence Cloud, we recommend reviewing the updated documentation on rate limits and best practices for optimizing API usage.
See the Jira Cloud Platform changelog for more details.
Rate limiting controls how many API requests your app can make to Jira Cloud within a given time period. This ensures platform stability, fair resource allocation, and a reliable experience for all users.
Without rate limits, a single app could consume excessive resources, slowing down the platform for everyone. Rate limiting protects against:
If your app exceeds its rate limit, Jira returns an HTTP 429 Too Many Requests response. Your app should handle this gracefully by pausing requests and retrying after the specified delay.
Jira Cloud uses a points-based model to measure API usage. Instead of simply counting requests, each API call consumes points based on the work it performs—such as the amount of data returned or the complexity of the operation.
This approach offers several benefits:
Most apps operate comfortably within the default quota. If your app exceeds limits, follow the optimization guidance below or reach out for a quota review.
Points are calculated based on the type of API request and the objects affected. Each request starts with a base cost of 1 point, and additional points are added for each object involved. Write requests are charged only the base cost, with no additional points.
This straightforward model applies to both REST and GraphQL APIs. This table provides the object costs break down:
| Operation type | Cost (points) | Applies to | Examples |
|---|---|---|---|
Core domain objects (GET, GraphQL query) | 1 point | Standard read operations on primary content | Issues, Projects, Dashboards, Attachments |
Identity & access (GET, GraphQL query) | 2 points | Reads involving authentication or permissions | Users, Groups, Project Roles, Permissions |
Write / modify / delete (POST, PUT, PATCH, DELETE, GraphQL mutation) | 1 point | Operations that create, update, or remove data | Create or edit issues |
| Others | 1 point | Read operations on uncategorized objects | Endpoints or fields not listed above (default cost applies) |
Note: We plan to expand our catalog in the future to provide more detail on object costs. Most requests are dominated by object costs.
All quotas are measured in points per hour and reset at the top of each UTC hour.
Your app's hourly quota depends on two factors:
Your app shares a single 65,000 point hourly quota across all tenants. This is the default tier for all apps. Most apps operate comfortably within the Global Pool.
Your app receives a separate hourly quota for each tenant, with limits varying by their edition. Only apps with exceptionally high or concentrated usage patterns may be assigned to the Per-Tenant Pool after review.
| Tier | Free | Standard | Premium | Enterprise |
|---|---|---|---|---|
| Tier 1 – Global Pool | 65,000 points/hour — single shared quota across all tenants | |||
| Tier 2 – Per-Tenant Pool | 65,000 points/hour | 100,000 + 10 × users points/hour | 130,000 + 20 × users points/hour | 150,000 + 30 × users points/hour |
How Tier 2 limits are calculated (for apps assigned to this tier): For apps operating in the Per-Tenant Pool, each tenant receives a quota based on their edition and user count:
Per-tenant rate limits are capped at 500,000 points per hour for Standard, Premium, and Enterprise editions.
Standard tenant with 2,000 users:
100,000 + (10 × 2,000) = 120,000 → 120,000 points/hour
Enterprise tenant with 15,000 users:
150,000 + (30 × 15,000) = 600,000 → 500,000 points/hour (capped)
The following examples show how points are calculated for common Jira REST API operations.
Scenario:
Amy is building an integration that syncs Jira issues to an external dashboard, she fetches a single issue:
1 2GET /rest/api/3/issue/ABC-123
Cost calculation
1 21 (base) + 1 Issue = 2 points
Later, Amy’s integration fetches all members of a group using the group membership API. Since each user object costs 2 points, the request is more expensive:
1 2GET /rest/api/3/group/member?groupname=my-group
Cost calculation
1 21 (base) + 8 users = 17 points (1 + 8 × 2)`
Scenario:
Alex is automating issue creation for a support workflow. All write operations cost 1 point regardless of object type:
1 2POST /rest/api/3/issue → 1 point
If Alex's script creates 50 issues in a batch, that's 50 points consumed from the quota (50 issues × 1 point each).
Quota and burst rate limits are enforced independently. Burst limits are evaluated over short time windows (typically seconds) to prevent traffic spikes, while quota limits are evaluated hourly. Even if you remain within your hourly quota, a rapid surge of requests can trigger burst limiting. Burst limits reset quickly, allowing normal operations to resume within seconds. Certain high-impact endpoints (Permissions, Search, Admin operations) enforce additional burst protections for system stability.
In addition to the standard rate limiting mechanisms, Jira implements per-issue rate limiting on write operations to protect against scenarios where a single issue receives an excessive number of updates in a short time frame. This rate limiting is designed to prevent system instability and to provide reliable service for all customers.
Per-issue rate limiting restricts the number of write operations (create, update, delete) that can be performed on a single Jira issue within specific time windows.
Per-issue rate limiting operates with two time windows:
When per-issue rate limiting is triggered, you'll receive:
429 Too Many Requestsjira-per-issue-on-writeImplement exponential backoff and distribute write operations over time: When you receive a 429 response with RateLimit-Reason: jira-per-issue-on-write, use exponential backoff with jitter before retrying the write operation. You do not need to delay writes for other issues—it is only needed for the specific issue that triggered the rate limit.
Batch operations when possible: Use bulk operations or combine multiple changes into a single request to reduce the number of operations counted against per-issue rate limits:
Design for distributed operations: In distributed systems, multiple automated processes or users may simultaneously modify the same issue. Implement resilient patterns to handle concurrent operations gracefully:
Atlassian enforces API rate limits by tracking your usage in hourly intervals, measured in points. Each app or token has a set quota of points per hour, which resets at the top of each hour (UTC). If your usage exceeds the quota, further requests are denied with an HTTP 429 response until the next window begins. There is no partial throttling once the quota is reached, all requests are blocked until reset.
Key points:
Quotas are measured in points per hour and reset at the start of each UTC hour.
There is no carry-over between hours; unused quota does not accumulate.
When the quota is reached, all further requests are denied until the next reset.
This model provides predictable enforcement and makes it easy for developers to monitor usage and reset times.
Apps can detect rate limits by checking for HTTP 429 responses. Any REST API can return a rate limit response.
Apps can detect rate limits by checking if the HTTP response status code is 429. Any REST API can return a rate limit response.
| Header | Description |
|---|---|
X-RateLimit-Limit | The maximum request rate enforced for the current rate-limit scope. For burst rate limits, this reflects the allowed requests per second. |
X-RateLimit-Remaining | The remaining request capacity within the current rate-limit window. For burst rate limits, this represents remaining requests in the current second. |
X-RateLimit-Reset | ISO 8601 timestamp when the current window resets |
X-RateLimit-NearLimit | Returns true when less than 20% of the quota remains |
RateLimit-Reason | The reason for throttling - jira-quota-global-based, which refers to the Global pool limits being breached.- jira-quota-tenant-based, which refers to the Per Tenant pool limits being breached.- jira-burst-based, which refers to API burst rate limits being breached.- jira-cost-based, which refers to counter and cost based limits being breached.- jira-per-issue-on-write, which refers to per-issue write rate limits being breached. |
Retry-After | Only returned with 429 responses. Indicates how many seconds to wait before retrying |
Responses will get beta- prefixed headers if they would have breached the upcoming quota and burst rate limits:
Beta-Retry-AfterX-Beta-RateLimit-LimitX-Beta-RateLimit-RemainingX-Beta-RateLimit-NearLimitX-Beta-RateLimit-ReasonX-Beta-RateLimit-ResetHowever, if you receive headers without the beta- prefix, you are facing actual rate limits. Some transient 5XX errors (like 503) may also include a Retry-After header. While these are not rate limit responses, you can handle them with similar retry logic.
1 2HTTP/1.1 429 Too Many Requests Retry-After: 1847 X-RateLimit-Limit: 100000 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 2025-10-08T15:00:00Z RateLimit-Reason: jira-quota-global-based
Retry-After headerPseudocode for retry logic:
1 2let maxRetries = 4; let lastRetryDelayMillis = 5000; let maxRetryDelayMillis = 30000; let jitterMultiplierRange = [0.7, 1.3]; let response = await fetch(...); if (response is OK) { handleSuccess(...); } else { let retryDelayMillis = -1; if (hasHeader('Retry-After')) { retryDelayMillis = 1000 * headerValue('Retry-After'); } else if (statusCode == 429) { retryDelayMillis = min(2 * lastRetryDelayMillis, maxRetryDelayMillis); } if (retryDelayMillis > 0 && retryCount < maxRetries) { retryDelayMillis += retryDelayMillis * randomInRange(jitterMultiplierRange); delay(retryDelayMillis); retryCount++; retryRequest(...); } else { handleFailure(...); } }
The following articles provide useful insights and techniques related to retry and backoff processing:
Efficiently scheduling your app’s API requests is essential for staying within your hourly points quota and ensuring reliable performance for your users. Whether you’re running batch jobs, automations, or large data migrations, thoughtful scheduling helps you avoid rate limit errors and make the most of your available quota.
Best practices for scheduling API requests:
Distribute requests over time: Spread your requests evenly throughout the hour, rather than sending large bursts at predictable intervals.
Apply random jitter: Add a random delay ("jitter") to scheduled jobs to avoid many apps hitting the API at the same time.
Coordinate across threads and nodes: Share rate limit status between threads or servers to prevent accidental quota exhaustion.
Avoid using concurrency to bypass limits: Excessive parallelism can lead to more frequent 429 responses and degraded performance.
Schedule heavy jobs during off-peak hours: For large, ad-hoc operations, consider running them during periods of lower user activity.
Example: Instead of scheduling all batch jobs to run at 00:00 UTC, stagger them with random delays or intervals (e.g., every 5–10 minutes) to smooth out traffic and reduce the risk of hitting your hourly quota early in the window.
Request only the data you need: Limit fields, use pagination, and avoid fetching unnecessary objects.
Cache stable responses: Use ETags and conditional headers to avoid re-fetching unchanged data.
Use bulk operations thoughtfully: Bulk operations may consume more points per request, but can reduce the number of HTTP calls and improve efficiency. Always check the point cost and consider whether batching is optimal for your use case.
Leverage webhooks and context parameters: Use webhooks for updates and context parameters to minimize the number of API requests.
These rate limits are designed to provide generous capacity for our developer community. However, to ensure platform stability and protect against abuse, these limits and the policies governing them are subject to change. We will strive to provide notice of significant changes, but we reserve the right to make adjustments as needed to protect the service.
| Question | Answer |
|---|---|
| What's the difference between the Global Pool and Per-Tenant Pool? |
The Global Pool gives apps a single shared hourly quota across all tenants (65,000 pts/hr). The Per-Tenant Pool provides a separate hourly quota per tenant, assigned only after Atlassian review for apps with sustained high or concentrated usage. Most apps remain in the Global Pool. |
| Why is Atlassian moving to a points-based rate-limiting model? |
To make limits fairer and more predictable by measuring actual "work" objects, nesting, permissions instead of raw request count. This protects platform stability and ensures heavy operations consume more quota than simple ones. |
| Will this change affect my existing integrations? |
Most apps already operate comfortably within the Global Pool. You may need to update error handling to respect the new rate-limit headers and retry behavior. |
| REST vs GraphQL — Are there differences? |
The model is the same for both:
|
| How do I know if my app is approaching or exceeding its limits? |
REST: Monitor GraphQL: Monitor the When a limit is exceeded, you will receive HTTP 429 Too Many Requests with a |
| How are object costs determined? |
Each object type has a published point value (e.g., Issues = 1, Users = 2). Unlisted objects default to 1 point. The catalog will expand over time. |
| What happens if I exceed my allocation? |
You will receive a 429 Too Many Requests response with a All requests are denied until the next hourly reset. There is no gradual throttling. |
| What are the best practices for staying within limits? |
|
| How do I know which tier is right for my app? |
Global Pool: Default for most apps. Per-Tenant Pool: Only available after Atlassian review and meant for apps with sustained, high, or concentrated usage. |
| Can limits be increased if needed? |
No, not on demand. Quota increases require a review by Atlassian for Tier 2 Per-Tenant Pool eligibility. |
| What is the scope of the rollout? |
Jira and Confluence APIs. REST enforcement comes first, followed by GraphQL at a future date which will be announced. |
| Who can I contact for support? |
Use the Partner Portal for documentation and app quota increase requests, or please contact your Atlassian representative. |
Rate this page: