Kanban boards are slow to load in Jira Software
Platform notice: Server and Data Center only. This article only applies to Atlassian products on the Server and Data Center platforms.
Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Except Fisheye and Crucible
Problem
Kanban board takes a lot of time to load, specifically on the rest call http://<JIRA>/rest/greenhopper/1.0/xboard/work/allData.json?rapidViewId=<ID>&selectedProjectKey=<PROJ>
Diagnosis
Most of the time can be spent on following actions:
Calculating Card colors:
at com.atlassian.greenhopper.service.rapid.view.color.CardColorQueryServiceImpl.getCustomStrategyIssueCardColors(CardColorQueryServiceImpl.java:179)
at com.atlassian.greenhopper.service.rapid.view.color.CardColorQueryServiceImpl.getCardColorsForQuery(CardColorQueryServiceImpl.java:108)
Calculating Days in column:
at com.atlassian.greenhopper.service.charts.IssueStatusHistoryServiceImpl.collectStatusHistory(IssueStatusHistoryServiceImpl.java:74)
at com.atlassian.greenhopper.web.rapid.list.RapidIssueEntryQueryServiceImpl.loadDaysInColumn(RapidIssueEntryQueryServiceImpl.java:846)
at com.atlassian.greenhopper.web.rapid.list.RapidIssueEntryQueryServiceImpl.collectIssues(RapidIssueEntryQueryServiceImpl.java:744)
Calculating Swimlanes:
at com.atlassian.greenhopper.service.issue.IssueDataServiceImpl.findImpl(IssueDataServiceImpl.java:166)
at com.atlassian.greenhopper.service.issue.IssueDataServiceImpl.find(IssueDataServiceImpl.java:41)
at com.atlassian.greenhopper.web.rapid.work.PoolServiceImpl.getSwimlaneIssueIds(PoolServiceImpl.java:240)
at com.atlassian.greenhopper.web.rapid.work.PoolServiceImpl.getCustomSwimlanes(PoolServiceImpl.java:99)
at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.loadSwimlanesData(WorkDataFactory.java:382)
at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:178)
The following appears in Java thread-dump, this is one thread over-time:
jstack-2015-12-24_023408-6.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:126)
jstack-2015-12-24_023413-7.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:145)
jstack-2015-12-24_023417-8.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:162)
jstack-2015-12-24_023421-9.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:162)
jstack-2015-12-24_023426-10.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:162)
jstack-2015-12-24_023431-11.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:162)
jstack-2015-12-24_023435-12.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:178)
jstack-2015-12-24_023440-13.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:178)
jstack-2015-12-24_023444-14.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:178)
jstack-2015-12-24_023449-15.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:178)
jstack-2015-12-24_023453-16.txt- at com.atlassian.greenhopper.web.rapid.work.WorkDataFactory.getAllData(WorkDataFactory.java:178)
In the end, all actions are always related to very active Lucene activity::
"ajp-bio-127.0.0.1-19041-exec-172, unique_id=X, time=1450942446655, uri=/rest/greenhopper/1.0/xboard/work/allData.json" daemon prio=10 tid=0x00002afb30a93000 nid=0x98a runnable [x]
java.lang.Thread.State: RUNNABLE
at org.apache.lucene.store.DataInput.readVInt(DataInput.java:106)
at org.apache.lucene.index.TermBuffer.read(TermBuffer.java:65)
at org.apache.lucene.index.SegmentTermEnum.next(SegmentTermEnum.java:131)
at org.apache.lucene.index.SegmentTermEnum.scanTo(SegmentTermEnum.java:166)
at org.apache.lucene.index.TermInfosReader.get(TermInfosReader.java:273)
at org.apache.lucene.index.TermInfosReader.get(TermInfosReader.java:209)
at org.apache.lucene.index.SegmentReader.docFreq(SegmentReader.java:503)
at org.apache.lucene.search.TermQuery$TermWeight$1.add(TermQuery.java:56)
at org.apache.lucene.util.ReaderUtil$Gather.run(ReaderUtil.java:77)
at org.apache.lucene.util.ReaderUtil$Gather.run(ReaderUtil.java:82)
at org.apache.lucene.util.ReaderUtil$Gather.run(ReaderUtil.java:66)
...
Diagnosis
Environment
- Large environment with large amount of Issues per project (more than 20k).
Custom-Fields: 326
Issues: 512512
Projects: 512
Cause
- Slow disk performance, test it with Testing Disk Access Speed
- Very large number of issues at the board. Having more then 1000 issues will be slow to generate and to render and made board not practical to read. Please pay attention to "Done" column (In some cases the "Done" column had 7000 issues.)
- Complex JQL queries in Swimlanes, Card Colors and Board configuration
- Let say: there are 5 Swimlanes and 5 Card Colors. Agile will run the entire board query again for every Card colour or Swimlane that is defined using board JQL with the additional JQL appended.
- So in this case board will take at least 11*N seconds to open (N - time required to load JQL for board).
- see related bug JSWSERVER-13211 - Slow Kanban response and performance after upgrade to Jira 6.4.
- A third-party plugin such as Scriptrunner for Jira (version 7.2.0). Due to the new version of the scriptrunner add-on, 'import com.atlassian.jira.component.pico.ComponentAccessor' was no longer applicable for some scripted fields, as a result of which the boards with regard to the fields in which this occurred no longer loaded.
Workaround
None
Resolution
List of possible resolutions related to cause:
- Improve disk performance
- Reduce number of issues at the board, a list of possible suggestions (including but not limited to):
- You can use Kanban Backlog (Kanplan), see JSWSERVER-15236 - Kanban Backlog (Kanplan) for JIRA Software Server.
- Remove "Done" column from mapping.
- Move issues from Done state to another state not mapped to Done column.
- Modify JQL to exclude issues resolved older than X days (reduce number of issues in Done)
- You can also check new feature JSWSERVER-16512 - Add option to hide old done issues from Kanban board.
- Modify JQL to only include issues at defined column (reduce work for mapping)
- Reduce number of Swimlanes (use simple JQL)
- Reduce number of Card Colors (use simple JQL)
- Disable 'Days in Column'
- Change Kanban board sub-filter:
- Either delete work sub-filter if you don't need versions
- Or define the project key in the board filter to reduce the search scope: unreleasedVersions("PROJ") OR project="PROJ" AND fixVersion is EMPTY"
- see bug: JSWSERVER-13194 - UnreleasedVersions() is slow on large instances.
- Reduce size of Lucene index by removing unused Custom fields
- Use simple JQL for Board configuration
- Remove any Scripted Field from using the package "import com.atlassian.jira.component.pico.ComponentAccessor"