@MaheshPopudesi, ok, just to be double-sure: So we can still check for header X-RateLimit-NearLimit to detect if less than 20% of the hourly quota is left?
@matthias and @scott.dudley Thank you for highlighting this
This is exactly the direction we’re heading. The structured format was designed with this kind of consolidation in mind, unifying rate limit policies into a single set of headers. We’re leading with points-based quota limits first, and will progressively bring other limit types into this format going ahead.
Hi @matthias
The X-RateLimit-* headers will continue to be used for burst rate limits and per-issue rate limits, they’re not going away. For points based quotas we will use the new Beta-RateLimit and Beta-Ratelimit-policy to give you clear view of points usage and tiers (RateLimit and RateLimit-policy at enforcement) And, yes Retry-After will be returned. If your app already respects Retry-After, you’re in good shape for both burst and quota enforcement.
I will circle back on the other questions.
Yes, X-RateLimit-NearLimit will continue to indicate when less than 20% of your hourly quota remains. At enforcement, you’ll also have the new RateLimit header with the r (remaining) parameter which gives you the exact number of points remaining as well when 20% of the hourly quota remains. We recommend planning to migrate to the new headers, but X-RateLimit-NearLimit will keep working and we’ll publish guidance on any future deprecation timeline.
Quick clarification: this statement I’ve seen in multiple places (this is from FAQ)
The Global Pool gives apps a single shared hourly quota across all tenants (65,000 pts/hr).
The word “apps” here means what exactly? i.e. your app has 65000 points across all tenants, or all your apps have 65000 points, or all apps have 65000 points.
My assumption has been “my app” has 65000 points per hour, but I’ve seen different interpretations here. Could you clarify this for everyone, and maybe improve the wording in the doco?
e.g. The Global Pool gives an app a single hourly quota shared across all tenants.
Confirming - 65,000 pts/hr is per app, shared across all tenants for that app in the Global Pool. We will tighten the FAQ wording to be precise.
Calls from the UI do not count, but if they come from the backend, whatever the circumstances, they will count.
After testing the behavior of some Jira APIs I must say I am mostly confused with results rather than comforted.
I observe two very different cost-related rules on different APIs for bulk requests:
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.
These two APIs follow that rule well from what I’ve observed so far:
- project/search
- search/jql
Where the observed cost is always 1 + the number of returned results
However these did not behave as expected from the rule
| API | nb results | observed cost |
|---|---|---|
| project/{projectid}/version | ~500 | 1 |
| permissions/project | ~1000 | 1 |
| issuetype/project?projectId=xxx | ~10 | 1 |
| issue/RLS-1/remotelink | ~50 | 1 |
| user/search?query=term | ~10 | 1 |
Now I could just be happy about these results: it means I’m able to retrieve multiple resources with a single point cost. But I’m not, these tests actually brought more questions than answers:
- Are these discrepancies intended
- Is each API free to compute cost as it wants
- Is any API cost subject to change at any time without any prior notice
We are asked to design our apps for Atlassian to earn badges (so with these specific rate limiting constraints in mind) but how can we do so if the documented rules are applied erratically. We need reliability and predictability in these core mechanisms to plan accordingly how else can we determine what requests need to be throttled.
I expect each App to document clearly the cost of each of its own APIs because it seem we cannot trust the global rule documented so far
I guess I should not be surprised given Atlassian’ track record, but I still did not expect broken promises on such an important topic.
Perhaps next time don’t make these empty statements. We already assume it won’t happen, no need to add insult to injury.
I’ve performed some analysis based on the new rate limiting headers we’ve received and noticed that our Jira app reported that it’s on the global pool and has no points available.
Afterwards, I saw the headers reporting again that our app is based on the per tenant pool again.
Interestingly, this also happened for at least one of our Confluence Cloud apps at the same time.
So, my ask is: Did anyone else see this behavior happening? The timeframe is from 2026-02-24T09:06:32.487Z to 2026-02-24T09:44:14.763Z.
I’ll also open an ECOHELP ticket to ask for clarification.
I tested the new points-based rate limits and observed behaviour that contradicts the Quick Reference Guide.
The guide states:
> **UI → @forgeforge/bridge.requestJira (no resolver / no backend call) (** Log in with Atlassian account )
> Treated as user-initiated UI traffic and not counted toward points-based app rate limits.
Test steps:
- From the backend I warmed up usage with api.asApp().requestJira to ~80%.
Result: 80849/100300 (80.61%), remaining: 19451.
-
From the custom UI only, I sent 50 requests@forgevia @forge/bridge.requestJira(‘/rest/api/3/search/jql’, POST) (no resolver/backend calls in this step).
-
I then read the quota again from the backend.
Result: 81420/100300 (81.18%), @forgeemaining: 18880.
Delta used: 571 points. So 50 UI-only requests reduced tenant-app-quota by 571 points. The documentation says UI traffic is not counted toward this quota; in practice it appears to be counted.
Could you confirm whether this is expected (e.g. a recent change) or a bug/documentation issue? I can provide a screenshot and log snippets if needed.
Thanks.
Atlassian is asking us to be ready for a system that is not yet fully ready on their side.
Yep, kinda expected. We want to know in advance what is happening, and they want feedback and are being agile (put it out. is that going to work. make changes. repeat) Giving us the general direction is all we can expect. It’s not bedded down because of legit complaints. Will they get it right, probably, mostly, eventually, I hope
.
Hey Atlassian,
Now that this change has been rolled out, I see some problems:
Documentation incorrect for “RateLimit-Reason”
The constants described in the docs for the RateLimit-Reason field do not match what is returned in real life, or at least not for Confluence. Can someone please fix the docs to include the production values? And while you are there, maybe someone can also remove the now-irrelevant references to the “Beta” prefixes?
Per-object costs of certain operations destroy quotas in seconds, even on toy-sized sites
I asked a question in the very first post of this thread that (as far as I know) was never answered. Unfortunately, I just stumbled across the answer myself after being unexpectedly rate-limited on my test instance, and the answer is not good.
For reference, that question was:
Do requests that return multiple objects of a type incur a point-based cost for every single object? For example, if I request a group object that contains 15 users, am I billed 15*2=30 points for this request? (If an app inadvertently requests an enterprise group that contains 30,000 users, does that exhaust the app’s token bucket with one request?)
I have a test space on my test instance running Confluence Premium. This space shows a completely trivial set of users in the space permissions configuration:
- 2 real users
- 2 real groups
- 15 app users
The /api/v2/spaces/{spaceId}/permissions endpoint consumes two points. Not per call. Not per principal. Two points per permission.
For whatever reason, Confluence generates 480 permissions for this space with two real users, so invoking this endpoint once consumes nearly 1,000 points (assuming we follow the cursors). I have not configured any permissions manually, nor have I added any users or apps manually to the space, so the site and the space are configured with whatever Confluence does natively.
Is this point cost intentional? For a site with two users?
If so, vendors are effectively prohibited from using a basic product API that has been functional for years, even on a toy-sized test instance.
In this scenario, would it not be more appropriate to add heavy warnings to the docs for this API and to start the process to withdraw this endpoint from service? (And can you please then provide vendors with an alternative, non-expensive API that allows us to fetch the information we need?)
Thank you for sharing this @scott.dudley. Our Confluence apps use the exact same call. It is the only API we are aware of that can determine if a user has space admin permissions.
Maybe Atlassian would consider adding a filter to this API by principal accountId or operation key before counting the cross-product of users and perms against the quota.
Hi @BurakAKTEPE
I will review this with our team and circle back to this thread.
Quick response - We will fix the documentation, and I will review the point costs you highlighted and circle back.
I appreciate your looking into this.
In the meantime, I see some curious behaviour from a Connect-on-Forge app once rate limiting starts. When hitting the 80+% warning threshold and getting the relevant headers from the Connect back end, I noticed that the Forge Remote back end of the same app was still receiving naked responses without any NearLimit headers.
Once I hit the rate limits and started receiving 429s on Connect, Forge continued to work correctly. Digging further, I was also able to push the Forge back end independently into its own rate-limited state by making further requests on that side.
Is it expected that the Connect and Forge back-ends of a CoF app have seemingly-independent quotas?
And importantly, for a production app in tier 2, do vendors need to take any specific steps to ensure that tier 2 escalations are in place for both the Connect and Forge sides of the app?
Can we also expect that the Connect side of such a tier 2 app has 1X of the per-site quota, and that the Forge side also has 1X of the quota, so that there are technically 2X the stated number of points split evenly across both back ends?
@MaheshPopudesi what’s your response to this proving that the claim of “it’s just an accounting boundary” is not accurate: Rate limit abuse (new attack vector)
In looking further:
Front-end calls do consume points
The earlier post from @BurakAKTEPE suggested that front-end traffic is counted against the rate limit.
I can confirm after testing that this is broken, at least for Connect apps. AP.request() calls do indeed eat into the quota, as reported on both the back end and front end. The same AP.request() calls do show the expected rate-limit headers in the network tab while in the 80%+ state.
Once the rate limit is reached, the AP.request() calls start reporting HTTP 429. Some of the rate-limit headers are missing on the Connect side of the AP.request() call (the client gets only Retry-After and X-RateLimit-Reset, despite others being sent across the wire), so it is not easy to detect what type of rate-limiting is being applied.
This is a significant problem because clients that are in a points-based rate-limited state need to know that it is points-limited rather than burst-based, since they need to abort the operation immediately rather than blindly following the Retry-After interval (which can be dozens of minutes).
I am unable to reproduce this behaviour with Forge apps, which is what the OP reported, so perhaps a fix for this is in process. If Atlassian could work to make sure that Connect apps are excluded from the points limits too, that would be appreciated.
No forgiveness for spikes within “accounting boundaries”
Earlier posts from Atlassian suggested that the points-based rate limiting system was designed to be flexible and that it was not intended to block apps that had “occasional hourly spikes”.
I have not seen evidence of any forgiveness or flexibility in my testing. As soon as my global-pool test app meets the 65k threshold, access to all APIs is slammed shut and it does not reset until the next hour. I have repeated this 5-6 times and the behaviour is consistent.
I write this based on clients getting rate-limited after making ~30 calls to the really expensive Confluence API I mentioned in a previous post.
It is starting to feel like vendors need to design assuming that there is zero flexibility for spikes. (The platform makes this really hard to design around though, because the problem is not visible until 80% of the quota is already exhausted.)