One of the challenges that Jira admins face is monitoring the health of their Jira instance. While there are some built-in tools for doing this, it’s useful to know how to perform routine maintenance using ScriptRunner.
One such routine maintenance task is the monitoring of Jira Project sizes.   There’s no direct method or way of doing this; instead we get all of the issues for a given project, and sum up the size of the attachments on each issue.  In this way, we get an idea of which Jira Projects are becoming unwieldy.

The code required to perform this calculation isn’t complicated. However, if the script runs too long it’ll simply time out. This is especially true if you’re calculating the size of multiple Projects.  Here’s the code to calculate the size of a single project:

 import org.ofbiz.core.entity.GenericValue;
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.project.ProjectManager

def totalSize = 0
def attachmentManager = ComponentAccessor.getAttachmentManager()

ProjectManager projectManager = ComponentAccessor.getProjectManager()

def projectName = "<projectName>"

Project proj = projectManager.getProjectByCurrentKey(projectName)

IssueManager issueManager = ComponentAccessor.getIssueManager()

for (GenericValue issueValue: issueManager.getProjectIssues(proj.genericValue)) {
    Issue issue = issueManager.getIssueObject(
    attachmentManager.getAttachments(issue).each {
      attachment ->
        totalSize += attachment.filesize
  log.warn("Total size of attachments for ${} is ${totalSize / 1024} 

Here’s a relatively simple one for you. Say you had a Jira Cloud instance with hundreds or thousands of projects, and you wanted to swap them all over to using a new notification scheme.  How would you go about it?

Well you could certainly do it by hand. That’s an option.  Or you could write a little script and us an API endpoint that I’ve only just discovered.

The script below fetches all of the projects in the system that use a notification scheme. We then filter out only the ones we want to adjust, and update each of those projects to use the target notification scheme.

This script is a great example of the kind of thing that ScriptRunner excels at, and it’s a great script to use to start learning the REST API.


 import groovy.json.JsonSlurper
// Notification scheme ID to search for
def searchSchemeId = "10000"
// Notification scheme ID to use for update
def updateSchemeId = 10002
def response = get("/rest/api/3/notificationscheme/project")
  .header('Content-Type', 'application/json')
// Parse the JSON response
def jsonSlurper = new JsonSlurper()
def json = jsonSlurper.parseText(response.getBody().toString())
// Access the nodes in the JSON
json.values.each {
  project ->
//We need to account for -1, 

I admit, this one is a very specific use case.  But I had a reason to create the script, so maybe someone will find it useful.  I also got to use the .collect method in a useful way!

This script identifies all of the pages that are linked from a target page.  It then compares that list of links to a list of all the pages in the Space.

By doing this, it identifies any pages in the Space that aren’t linked on the target page.  This could be useful if you had a wiki or something, and wanted to know which pages weren’t linked on the front page.

One interesting thing I discovered while doing this is the outgoingLinks method of the page class.   Instead of having to use regex to find the URLs on a page, I simply had to call this method and all of the urls were returned for me.


 import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator

def pageManager = ComponentLocator.getComponent(PageManager)
def spaceManager = ComponentLocator.getComponent(SpaceManager)

def targetSpace = spaceManager.getSpace("<Space Key>")
def spacePages = pageManager.getPages(targetSpace, true)
def targetPage = pageManager.getPage(<page ID as Long>)

def outgoingLinks = targetPage.outgoingLinks.collect { link -> 


spacePages.each {
  page ->