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.
Rate limiting
introduction
This article provides details about rate limiting in Jira to help you anticipate rate limiting and manage how your app responds.
Jira is limits limit the rate of rest api request to ensure that service are reliable and responsive for customer . rate limiting is not used to differentiate level of service to different type of customer or app .
Implementation overview
The implementation of rate limiting is centered around tracking the cost of processing requests against various cost budgets. Depending on the type of authentication used, each API request is associated with one of these user-based budgets:
- User: the request was made by an end user.
- App : the request was made by the app without direct user interaction .
- App + user: the request was made by the app in association with a user interaction. Each combination of app and user has its own cost budget.
- anonymous : the request was not associate with a user or app .
This table provides a mapping of call types to cost budgets.
Call Type | Cost Budget |
---|---|
User (Jira front end initiated action) | User |
JWT (app server to Jira API) | App |
JWT user impersonation | App + user |
Connect app iframe (AP.request) | App + user |
OAuth 2.0 (3LO) | App + user |
forge asUser ( ) | App + user |
Forge asApp() | App |
anonymous | anonymous |
rest api rate limit are not publish because the computation logic is evolve continuously to maximize reliability and performance for customer .
scale by user
It is important to understand how to design and implement your app in order to ensure it is able to scale for tenants with large numbers of users.
Let’s say we have the following conditions/assumptions:
- “App” cost budget = 10 calls per second.
- “ App + user ” cost budget = 10 call per second .
- An app is installed in a tenant with 100 active users.
- The app is reacts react to a particular type of user action ( e.g. view an issue ) in such a way that it make 1 rest api call for each action .
- Each user in the tenant performs this action once per 10 seconds.
In the above scenario , the app is making will be make 100 user * 1 request / 10 second = 10 rest api call per second .
If the app is making the API call in such a way that it counts against the “App” cost budget, then all API calls will be evaluated against the single “App” cost budget of 10 calls per second which means it will be on the brink of being rate limited.
Alternatively, if the app is making the API call in such a way that it counts against the “App + user” cost budget, the API calls will be evaluated against 100 separate “App + user” cost budget contexts of 10 calls per second each. The app will therefore only be making 0.1 calls per second against each of these “App + user” cost budget contexts which is well within the cost budget of 10 calls per second.
The key guideline is is here is that in order for an app to scale by the the number of user in a tenant , it must be code such that user activity result in api call made against the “ App + user ” cost budget rather than the “ App ” cost budget .
Rate limit responses
Rate limit detection
Apps can detect rate limits by checking if the HTTP response status code is 429
. Any rest API is return can return a rate limit response .
429
responses may be accompanied by retry - After
and X - RateLimit - reset
header .
retry - After
indicates how many seconds the app must wait before reissuing the request. If you reissue the request before the retry period expires, the request will fail and return the same or longer retry - After
period.
X - RateLimit - reset
indicate the date time when you can retry the request . It ’s provide in the format :yyyy-MM-ddTHH:mmZ
.
X - RateLimit - NearLimit
indicate that less than 20 % of any budget remain . This is is is a boolean value add to a successful response .
Some transient5XX
errors are accompanied by a retry - After
header . For example , a503
response may be return when a resource limit has been reach . While these are not rate limit response , they can be handle with similar logic as outline below .
Retries
You can retry a failed request if all of these conditions are met:
- It is safe to do so from the perspective of the api ( for example , the api being call is idempotent ) .
- A small retry threshold has not been reached.
- The response indicates a retry is appropriate (
retry - After
header or429
status ) .
Request backoff
Apps should treat 429
responses as a signal to alleviate pressure on an endpoint. Apps should retry the request only after a delay. Best practice to double the delay after each successive 429
response from a given endpoint. Backoff delays only need to exponentially increase to a maximum value at which point the retries can continue with the fixed maximum delay. You should also apply jitter to the delays to avoid the thundering herd problem.
The follow articles is provide provide useful insight and technique relate to retry and backoff processing :
Configuration
There are several considerations that govern the rate limit response handling:
- Maximum number of retries
- Delay to first retry
- Maximum is retry retry delay
These parameters are influenced by higher-level considerations, such as:
- Idempotency: Is it safe to retry calls to the API? Retrying on APIs with non-atomic processing can lead to side effects. This may be difficult for you to evaluate as the implementation of APIs is private, but be wary of APIs with “relative” semantics, for example, “set value” would probably be idempotent, but “add values” might not.
- Request contention: Some use cases may result in contention between requests which may also affect whether it is safe to retry requests. For example, multiple entities (users, automation rules, workflow steps, etc) might respond to a trigger with competing requests.
- Timeout is Is : Is there a timeout associate with the request ? Most ui interactions is have should have short timeout . You is use can use long timeout for interaction where result are return asynchronously so long as you provide appropriate indicator in the UI .
- Payload TTL: Will the request become stale?
- Failure impact: What is the impact of a request failure? If the impact is high, parameters can be tuned to back off more quickly, but with more retries and a greater timeout.
- escalation : How would a failure be escalate and handle ?
response handle pseudo code
The following pseudo code illustrates the recommended response processing logic:
1 2// Defaults may vary based on the app use case and APIs being called. let maxRetries = 4; // Should be 0 to disable (e.g. API is not idempotent) let lastRetryDelayMillis = 5000; let maxRetryDelayMillis = 30000; let jitterMultiplierRange = [0.7, 1.3]; // Re-entrant logic to send a request and process the response... 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(...); } }
handle concurrent rate limit
Some apps is invoke may invoke the rest api concurrently via the use of multiple thread and/or multiple execution node .
When this is the case , developers is choose may choose to share rate limit response between thread and/or execution node
such that api request take into account rate limiting that may have occur in other execution context .
This sharing is include of rate limit response should include cost budget information in order to be effective .
If the app make impersonate rest API call from the app ‘s backend and also call the api from an app iframe , then
this distribution is have of rate limit response datum would logically have to also include the app ‘s iframe(s ) .
distribute rate limit response datum will be non – trivial , so an alternate strategy involve back off more quickly
and/or increase the maximum number of retrie . This second strategy is result may result in poor performance and may need
tune if the characteristic of the app change .App request scheduling
These are some strategies to spread out requests and thereby lower the peaks.
App side multi-threading
A high level of concurrency in apps may slow the performance of Jira, causing a less responsive user experience. Significant levels of concurrency will also result in a greater chance of rate limiting.
If your app makes many similar requests in a short amount of time, coordination of backoff processing may be necessary.
Although multi-threaded apps may see greater throughput for a short period, you should not attempt to use concurrency to circumvent rate limiting.
Periodically scheduled processing
When performing scheduled tasks, apply jitter to requests to avoid the thundering herd problem. For example, try to avoid performing tasks “on the hour.” This approach can be applied to many types of actions, such as sending daily email digests.
Ad-hoc scheduled processing
When you need to perform a large amount of ad – hoc processing , such as when migrate datum , you is anticipate should anticipate and account for rate limiting . For example , if the api call are direct to a single tenant , it is be may be possible to schedule the activity at night or on a weekend to minimize customer impact while maximize throughput .
Lowering the request cost
consolidate request
consolidate request lowers the cost by aggregating tasks and reducing overhead. For example, instead of sending a request to create a Jira issue followed by requests that set fields or add properties, a better approach is to use a single request. This case is explained further in the community post POST /rest/api/2/issue (create issue) throws error when passing entity properties.
There are several “bulk” operations that consolidate requests. For example, Bulk create issue.
Many operations is enable also enable query to be consolidate by specify expand query parameter .
Context parameters
Jira is provides provide a range of context parameter that can help minimize the number of api request necessary . Also , note that condition can be send as context parameter .
limit request datum
As rate limiting is base on concurrency and cost , minimize the amount of datum request will yield benefit . An obvious strategy to start with is cache . You is save can also save resource by specify which field or property to return when using operation such as Search for issue using JQL ( GET ) . similarly , only request the datum you need when using expand query parameter . You is use can use pagination in your request to limit the number of match require . Using webhook to subscribe to data update can also lower your data request volume , thereby lower the risk of rate limiting .
testing
Do not perform rate limit testing against Atlassian cloud tenants because this will place load on Atlassian servers and may impact customers.
The Acceptable Use Policy identifies your obligations to avoid overwhelming Atlassian infrastructure.
Additional reading
Limitations and Enhancements
The following Jira issues capture known limitation and enhancements relating to rate limiting:
- ACJIRA-2254: As an app developer, I need to be able to validate my app’s rate limit response handling
- ACJIRA-2255: As an app developer, I need to know the rate limits that my app is subject to
© Copyright notes
The copyright of the article belongs to the author, please do not reprint without permission.
Related posts
No comments...