-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Low
-
Affects Version/s: 10.4.0, 11.0.0, 11.2.0, 11.3.0, 11.3.7
-
Component/s: App Diagnositcs, JQL
-
10.04
-
4
-
Severity 3 - Minor
-
41
Issue Summary
On Jira Data Center 11.x, running JQL that uses a plugin-provided JQL function (for example, a function that returns a large set of issues) can lead to disproportionate growth of the built-in diagnostics database table AO_C16815_ALERT_AO.
When such a function matches a large number of issues, the JQL diagnostics monitor records a "complex query" alert (diagnostics issue ID 1002) for each qualifying execution. The alert's details are stored in the DETAILS_JSON column (an unlimited-length/CLOB field) and include the full set of query term metrics — which, for these functions, now contains one entry per matched issue. As a result, individual alert rows can become very large, and repeated execution of the same query can cause the diagnostics table to grow more than expected.
This is related to a change in how JQL diagnostics metrics account for term counts between Jira 10.x and 11.x. In Jira 10.x, a set-membership query produced by a JQL function was recorded as a single entry. In Jira 11.x, the equivalent query is recorded per matched issue, which increases both the reported numberOfClausesInQuery value and the size of the stored alert details.
Because the reported clause count for these functions can exceed the diagnostics complexity threshold (jira.diagnostics.thresholds.query-complexity, default 10000), affected queries are recorded as "complex query" alerts (ID 1002) rather than standard slow-query alerts (ID 1001), and a corresponding row is persisted on each qualifying execution.
Note: the jira.clause.count.limit JQL resilience setting (default 65000) generally does not apply here. That check evaluates the JQL clause structure before the query is built and treats a JQL function as a single clause, so it operates independently from the diagnostics term count described above.
Steps to Reproduce
- On a Jira 11.x instance with a large dataset, use a plugin that provides a JQL function capable of returning many issues.
- For example, Scriptrunner's lastComment function can bring millions of issues. In this example, it brings all issues with comments added before 3 days before.
project = KANBAN AND issueFunction in lastComment("before -3d")
Using issueFunction not in lastComment("after -3d") would be much more efficient, as the query will bring fewer clauses to use for comparison.
- Run the query repeatedly over time (for example via dashboards, filters, or saved searches).
- Review the size and row growth of the AO_C16815_ALERT_AO table.
Expected Results
No problems happen except for perhaps a non-optimized JQL being slow.
Actual Results
Each qualifying execution records a "complex query" alert (ID 1002) whose DETAILS_JSON value contains one all term-metric entries, even if it means millions of terms. Individual rows in AO_C16815_ALERT_AO can be very large, and repeated execution can lead to disproportionate growth of this table.
We've observed a case in which each row got to millions of terms, resulting in hundreds of megabytes.
A representative entry is written to the atlassian-jira.log file (the same detail is stored in the alert's DETAILS_JSON column):
2026-06-26 16:14:49,575-0400 pool-39-thread-1 INFO [atlassian-diagnostics-data-logger] 1782504884482 ; INFO ; JQL ; JQL-1002 ; Slow JQL query - query high complexity ; not-detected ; ; ;
{"threadDump":[{"id":1276375,"name":"http-nio-8080-exec-251 url: /rest/greenhopper/1.0/xboard/work/66368/colors.json; user: admin","daemon":true,"state":"RUNNABLE" (stack trace trimmed)
"reason":"QueryExecutionEvent{queryTermMetrics={issue_id:3110534=TermMetric{termCounts=1, isCustomField=false}, issue_id:10123=TermMetric{termCounts=1, isCustomField=false}, issue_id:10124=TermMetric{termCounts=1, isCustomField=false}, issue_id:10125=TermMetric{termCounts=1, isCustomField=false},
(450MB trimmed)
issue_id:98765441=TermMetric{termCounts=1, isCustomField=false}},
numberOfClausesInQuery=7387746, numberOfCustomFieldsUsed=0, executionTime=29121, numberOfResults=-1}"}
For comparison, on Jira 10.3.x the same query records a compact entry, accounting for the function as a single term:
2026-07-07 17:27:26,224+0000 pool-25-thread-1 INFO [atlassian-diagnostics-data-logger] 1783445246214 ; INFO ; JQL ; JQL-1003 ; Slow JQL query - high number of results yielded ; not-detected ; ; ; {"threadDump":[{"id":28,"name":"http-nio-8080-exec-5 url: /jira/issues/, /jira/secure/IssueNavAction!default.jspa; user: admin","daemon":true,"state":"RUNNABLE","stackTrace":(stack trace trimmed)
,"reason":"LuceneQueryExecutionEvent{queryTermMetrics={com.onresolve.jira.groovy.jql.IssueIdsQuery=TermMetric{count=1, isCustomField=false}, projid:10001=TermMetric{count=1, isCustomField=false}}, numberOfClausesInQuery=2, numberOfCustomFieldsUsed=0, executionTime=622, numberOfResults=200267, collectorType='TopDocs'}"}
Workaround
- Truncate the AO_C16815_ALERT_AO table to remove the large entries
TRUNCATE TABLE "AO_C16815_ALERT_AO"
- Optimize the queries so the number of clauses is reduced
- Decrease the DB retention period for the diagnostic entries from the 30-days default by adding the JVM parameter:
-Dcom.atlassian.jira.health.diagnostics.alerts.retention-period-days=7
- Alternatively, increasing jira.diagnostics.thresholds.slow-query-millis reduces how often JQL diagnostics alerts are recorded.
- As a last resort, the JQL diagnostics monitor can be turned off to stop these alerts from being recorded.
As a system administrator, disable the Dark Feature com.atlassian.diagnostics.jql.monitor
- is related to
-
JRASERVER-79469 Atlassian Diagnostics plugin unnecessarily loads DETAILS_JSON CLOBs and can cause OutOfMemory error
-
- Waiting for Release
-
- is cloned by
-
POSSUM-381 Loading...
- mentioned in
-
Page Loading...