We are using the Jira Cloud Bulk Issue Create API (/rest/api/2/issue/bulk) for enterprise IAM provisioning and are hitting the cost-based rate limit.
Our observed behavior:
Confirmed from 429 response headers:
Ratelimit-Reason: jira-cost-based
X-Ratelimit-Limit: 300000
X-Ratelimit-Remaining: 0
X-Ratelimit-Reset: 2026-06-05T06:00ZQuestions:
Worth separating two things up front, because provisioning user accounts and creating issues are different APIs with different limits.
A few details in the report don't line up with Atlassian's documented model, so I'd start there:
So for creating 100k issues, design around the per-second burst limit (enforced per tenant and per endpoint), not a per-ticket cost:
If what you actually need is the user accounts rather than issues, that's a different API: the org-level User Provisioning (SCIM) API, which needs Atlassian Guard Standard and an org admin. You drive it from your identity provider (Okta, Entra, and similar), or call the provisioning API directly if your IdP isn't supported. issue/bulk doesn't create accounts.
Sources:
Rate limiting (reason values, points model, pool FAQ):
https://developer.atlassian.com/cloud/jira/platform/rate-limiting/
Bulk create, "Creates upto 50 issues" (current v3 API reference):
https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-bulk-post
Understand user provisioning (SCIM, Guard requirement):
https://support.atlassian.com/provisioning-users/docs/understand-user-provisioning/
Thank you for your response.
We are building an enterprise IAM (Identity Access Management) provisioning system. Whenever a user is granted access to an application, we create a Jira issue as a tracking and approval ticket. For large organizations with more than 100,000 users being onboarded, we may need to create 100,000+ tickets during a single provisioning run.
I would like to clarify the following points:
Does ?skipNotifications=true actually reduce the cost units per request, or does it only suppress email notifications without affecting the rate-limit cost?
Is there a way to determine the exact cost of a request through response headers (for example, something similar to X-RateLimit-Cost) so that we can measure the impact of any optimizations?
We are using API token authentication (Basic Auth). A community expert mentioned that API tokens are governed only by burst limits and not by cost-based limits. However, we are receiving HTTP 429 responses with RateLimit-Reason: jira-cost-based. Does Jira's cost-based rate limiting also apply to requests authenticated using API tokens?
Using the single issue creation API (POST /issue), we were able to create approximately 500,000 tickets over a 24-hour period without encountering any rate limits. However, when using the bulk issue creation API (POST /issue/bulk) with batches of 50 issues per request, we started receiving jira-cost-based rate limits after processing only about 1,500 tickets per hour.
Could you help us understand why the bulk API appears to consume significantly more cost per ticket than the single-issue creation API?
Thank you for your assistance.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@C_Faysal _CFcon_ ,We implemented ?skipNotifications=true on the bulk issue creation endpoint, and it appears to have helped. Previously, we were hitting rate limits after creating approximately 400 tickets per hour, whereas now we can create around 800 tickets before encountering the same limit. This suggests that the cost per ticket may have been reduced by roughly 50%.
Our current ticket payload is:
{
"fields": {
"project": { "key": "QA" },
"issuetype": { "name": "Task" },
"summary": "Account Creation for johndoe",
"description": "Request Type: ADD\nApplication: TestApp\nName: johndoe\nEmail: john@company.com\nFirst Name: John\nAccount ID: ACC001\nBusiness Justification: Automated Request From Orsus",
"components": [{ "id": "10042" }]
}
}We have a few additional questions:
Which fields in this payload contribute most significantly to Jira's cost-based rate limiting? For example, is the description field more expensive because of indexing or additional processing?
If we remove the description and components fields, is there any expected reduction in cost per ticket? If so, is there any guidance on the magnitude of that reduction?
Is there any way to determine the exact cost consumed by a request? For example, does Jira expose a response header such as X-RateLimit-Cost or any other metric that would allow us to measure request cost directly?
Since enabling skipNotifications=true appears to have doubled our throughput before rate limiting occurs, can you confirm whether this parameter actually reduces the cost units consumed by a request, or whether it simply suppresses email notifications and the observed improvement is due to another factor?
Any guidance on optimizing ticket creation throughput for large-scale provisioning workloads would be greatly appreciated.
Thank you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Satyanarayana,
Good follow-up, and thanks for sharing the actual numbers. The 400 to 800 jump is worth digging into, but I want to separate what the docs actually say from what the before/after sample can tell us, because they point in different directions here. Let me take your questions in an order that builds on itself.
First, the API-token vs cost-model question (your earlier point)
This one is foundational, so it goes first. The rate-limiting page has an explicit carve-out: "API token-based traffic is not affected by this change, and will continue to be governed by existing burst rate limits." If your script authenticates with an API token over Basic Auth, that sentence is the one to read closely, because it suggests the points/quota model may govern your traffic differently than it governs a Connect/Forge app. I'd stop short of saying tokens can never be cost-limited, the docs don't state that either way. The jira-cost-based reason value that's come up in community threads is not in the official rate-limiting documentation that I can find, so treat it as community-reported rather than documented. The cleanest way to know which world you're in is to read the RateLimit-Reason header on your own 429s (more on that below).
Second, skipNotifications on the bulk endpoint (the big one)
Here's where the docs and your observation pull apart, so I'll be precise about each side.
On the documentation side: skipNotifications is not a documented parameter on POST /rest/api/3/issue/bulk. In the current v3 OpenAPI spec, that endpoint (createIssues) declares an empty parameters list, so no query parameters at all, and the string skipNotifications doesn't appear anywhere in the v3 spec. The single-issue POST /rest/api/3/issue declares exactly one query param, updateHistory, which has nothing to do with notifications. So whatever your ?skipNotifications=true is doing, it isn't doing it via a documented v3 parameter. I want to be careful here: an empty parameter list proves the param is undocumented, not that the server ignores it. Older Jira REST surfaces have honored undocumented flags before, so the honest statement is "undocumented, effect-if-sent unspecified." Don't build a production pipeline on it.
On the cost side: the documented write-cost model gives no basis for a "50% cost per ticket" reduction. The page says "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." And "All write operations cost 1 point regardless of object type." A create is 1 point whether notifications fire or not. There is no documented lever by which suppressing notifications lowers the point cost of a write. I'd avoid concluding that skipNotifications cuts cost units, because the docs don't support that claim.
So how do you reconcile a real 2x in throughput-before-429 with a cost model that says nothing changed? A few documented-limiter hypotheses are worth weighing, and I'd label all of them as hypotheses until your own headers confirm one:
- You may be hitting a different limiter than the points quota. Jira documents three: points quota (jira-quota-global-based / jira-quota-tenant-based), burst per-second (jira-burst-based), and per-issue-on-write (jira-per-issue-on-write). A change in throughput-before-429 can mean the wall moved between these, not that any single request got cheaper.
- Shared-pool variance. The points pool is shared and resets at the top of each UTC hour. Two runs at different times, with different burst-bucket state or background tenant load, can differ by a lot without any parameter mattering.
- A single before/after sample is easy to over-fit. One run at 400 and one at 800 is two data points. Time-of-day, concurrency, batch sizing, and retry behavior all move that number.
I'd resist locking in "skipNotifications doubled it" from one pairing. It might hold up, but the docs don't predict it, so it needs more than two runs to be a finding.
Third, per-field cost (description, components, trimming fields)
Same documented model answers this: field content is not a cost factor for writes. A create is base-cost-only, 1 point, "regardless of object type," and the cost scales with the count of objects created, not with how rich any field is. The batch example in the docs makes this concrete: 50 creates is "50 points consumed from the quota (50 issues x 1 point each)," with no term for payload size or field count. So removing the description or the components field has no documented effect on per-request cost. If you measure a throughput change after trimming fields, that magnitude is undocumented, treat it as something to verify on your tenant rather than a known ratio.
Fourth, a cost header (X-RateLimit-Cost)
There's no documented X-RateLimit-Cost header on the REST API. The documented set you can actually read on responses is RateLimit-Reason (which of the three limits you hit), Retry-After, and the X-RateLimit-* family including the reset/interval values. If you want an exact per-operation cost number, GraphQL returns one directly via extensions.cost on the response, and REST has no documented equivalent. Inferring REST cost by watching your remaining-quota deltas across calls is a workaround, not a documented header, so label it as inference if you go that route.
Fifth, bulk vs single per-ticket cost
Whether one bulk call of N issues costs less per ticket than N single calls is not documented as a ratio. The docs encourage bulk mainly to "reduce the number of HTTP calls," and they caution to "check the point cost for your specific use case and ensure batching actually reduces overall quota usage." So the win bulk gives you is fewer requests against the per-second burst bucket, not a documented per-ticket discount. If there's a per-ticket cost difference, it's undocumented, measure it, don't assume a number.
Putting it to work for large-scale provisioning
For a provisioning job at your scale, here's what I'd actually do:
1. Instrument before you optimize. Log RateLimit-Reason on every 429 and watch the X-RateLimit-* deltas across calls. That single header tells you whether you're hitting burst, per-issue-on-write, or the points quota, which is the thing that decides every other tuning choice. Right now you're tuning blind to which wall you're at.
2. Back off honestly. Honor Retry-After and the reset values, and use exponential backoff with jitter so parallel workers don't resynchronize into the next spike.
3. Respect the per-issue write windows (20 writes / 2s and 100 writes / 30s on a single issue) if your flow updates the same issue repeatedly. Creating many distinct issues won't trip that one, but post-create edits can.
4. Treat the per-tenant pool as an app-quota construct. It's documented for app traffic, and given the API-token carve-out above it may not govern a token-auth script the same way, so confirm with your own headers rather than assuming it applies.
5. Take the two real doc gaps to Atlassian. The jira-cost-based reason value on token traffic, and any actual point cost of the bulk endpoint, are genuinely not published. With reproducible evidence (your headers, your timings), those are good questions for Atlassian Developer Support, and the kind of thing they can answer authoritatively where the public docs go quiet.
Net: report the 2x as your observation, because it is one. Just don't pin it to a documented cost reduction, because the write model says a create is base-cost-only and skipNotifications isn't a recognized v3 parameter. Read your RateLimit-Reason headers and you'll likely find the real story is which limiter moved, not which request got cheaper.
Hope that helps untangle it.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @C_Faysal _CFcon_ ,
Thank you for the detailed explanation.
I just wanted to confirm one specific point. Our 429 responses consistently include the header:
RateLimit-Reason: jira-cost-based
Based on the documentation carve-out you referenced, API token-authenticated traffic should be governed by burst limits rather than the cost-based quota model.
Could you please clarify whether the jira-cost-based reason can apply to requests authenticated using API Token + Basic Auth, or if it is intended only for Connect/Forge app traffic?
The reason I ask is that all of our requests are authenticated using API tokens, yet the 429 responses in our tenant consistently report RateLimit-Reason: jira-cost-based.
Any clarification on how jira-cost-based rate limiting interacts with API token-authenticated scripts would be greatly appreciated.
Thank you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Satyanarayana,
I went digging on the jira-cost-based string, and there's an Atlassian ticket that clears up most of this: JRACLOUD-69262. It quotes the rate-limiting doc and lists the reason directly, so the value is real, not something your tenant invented:
- jira-cost-based, which refers to counter and cost based limits being breached
- jira-quota-based, which refers to API rate limits being breached
That's a two-value taxonomy. The catch is that the current live rate-limiting page doesn't use it anymore. The page today lists four different values, and jira-cost-based isn't one of them:
- jira-quota-global-based
- jira-quota-tenant-based
- jira-burst-based
- jira-per-issue-on-write
So Atlassian has two reason-code vocabularies in circulation. The older one, still quoted in JRACLOUD-69262 and in community answers as recently as late 2025, names jira-cost-based. The current page renamed everything into the four-value scheme and dropped that label, but the enforcement layer is still emitting the old string. That mismatch is the real problem, and it sits with Atlassian, not with your code.
Now to your actual question: does jira-cost-based apply to API token plus Basic Auth, or only Connect/Forge?
Nothing in any Atlassian source restricts it by auth type. The only definition that exists for it, the one in JRACLOUD-69262 , is "counter and cost based limits being breached." That's a budget condition, not an app-versus-token condition. No doc, ticket, or staff post says cost-based is Connect/Forge only. So the honest answer: it isn't scoped to apps anywhere I can find, and your tenant hitting it on token traffic is direct evidence it applies to API-token auth too.
The carve-out you quoted earlier is narrower than it reads. "API token-based traffic is not affected by this change, and will continue to be governed by existing burst rate limits" is scoped to one rollout: the March 2026 points-based quota, the jira-quota-* family. It promises token traffic won't be pulled into that new quota system. It does not say token traffic is immune to a cost or counter limit, and given the version mismatch above, you can't read it as a guarantee against jira-cost-based.
What I'd do from here:
1. Open a Developer Support ticket with your repro. Give them the exact request, the auth method, and the full 429 headers (RateLimit-Reason, Retry-After, X-RateLimit-*), and ask them to reconcile the two-value scheme in JRACLOUD-69262 against the four-value scheme on the live page, and to state plainly which limits apply to API-token traffic.
2. Add your case to JRACLOUD-69262. It already documents jira-cost-based, it's still open, and a concrete "we hit this on API token plus Basic Auth, here are the headers" comment is exactly the evidence that ticket lacks.
3. Until they answer, treat it operationally. Honor Retry-After and X-RateLimit-Reset with exponential backoff and jitter on every 429, whatever the reason string says. That keeps your provisioning run correct while the vocabulary stays inconsistent.
Short version: you're not misreading anything. jira-cost-based is real and was documented, just in an older taxonomy the live page has moved away from, and nothing scopes it away from API-token traffic. The contradiction is Atlassian's to resolve.
Best regards
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
While a GET request is a simple read operation and it costs 1 unit, POST requests to create a work item are significantly more expensive as it triggers a chain of backend processes. 🔃
To reduce this a bit, you could try:
Disable Notifications: Use the ?skipNotifications=true parameter to prevent the system from generating and sending emails for every new user provisioned.
👆 I've found this, never used it though, but might be worth a shot.
Can you maybe share the requirement here? How's IAM connected with bulk creation of issues/work items, and why do you need to create so many work items at once?
Cheers,
Tobi
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.