JMeter is the undisputed king of load testing. It’s powerful, flexible, and handles massive scale. But let’s be honest: sharing JMeter results with your team feels like it’s still 2010.
Usually, the workflow goes like this: The test finishes. You generate an HTML Dashboard. You zip the folder. You open Jira, find the right ticket, and attach a heavy .zip file or a massive .jtl CSV. Your developers and Product Managers then have to download it, unzip it, and try to understand what went wrong.
Performance testing shouldn’t create data silos. When your team is working on a Jira ticket, they need the core performance metrics (Pass/Fail, Response Times, Error Rates) right there on the screen.
Let’s look at how to stop context-switching and push JMeter results directly into Atlassian Jira.
The Hard Way: Custom Plugins and CI/CD Scripts
Many QA teams try to automate this by writing complex bash scripts in Jenkins or GitHub Actions. They use tools to parse the .jtl file, authenticate with Jira's REST API, and post a messy text comment into the issue.
It takes days to set up, tokens expire, and the formatting is always hard to read.
The Smart Way: Direct Webhooks via tearDown Thread Group
Instead of reinventing the wheel, our team at Orbit A released the JMeter Performance Analytics for Jira. It’s a zero-config Atlassian Forge app that allows you to push JMeter metrics directly into the Jira Issue Panel using a simple Webhook.
No custom plugins to install. No Java coding required. Just a native JMeter HTTP Request. Here is how to set it up in 2 minutes.
Step-by-Step Guide
Step 1: Install the App
Head over to the Atlassian Marketplace and install the JMeter Performance Analytics for Jira.
Step 2: Generate Your Webhook
Go to your Jira Apps menu and open the JMeter to Jira Config page. The app will instantly generate your unique Webhook URL and Secret Token.
Step 3: Add a tearDown Thread Group in JMeter
JMeter has a special feature called the tearDown Thread Group, which executes after your main load test finishes. This is the perfect place to send your results!
- Right-click your Test Plan -> Add -> Threads (Users) -> tearDown Thread Group.
- Inside it, add an JSR223 Sampler paste this script:
import groovy.json.JsonBuilder
def stats = props.get("MY_DETAILED_STATS")
if (stats == null) {
log.error("No stats found in MY_DETAILED_STATS! Check your Listener.")
return
}
def reportList = []
long grandTotalTime = 0
int grandTotalCount = 0
int grandTotalErrors = 0
boolean stepFailed = false
stats.each { label, data ->
def avg = data.totalTime / data.count
def errRate = (data.errors / data.count) * 100
errRate = Math.round(errRate * 100.0) / 100.0
reportList.add([
label: label,
avg: avg,
errorRate: errRate,
count: data.count
])
if (errRate > 3) {
stepFailed = true
log.warn("Step [${label}] failed with ${errRate}% errors")
}
grandTotalTime += data.totalTime
grandTotalCount += data.count
grandTotalErrors += data.errors
}
long finalAvg = grandTotalCount > 0 ? (grandTotalTime / grandTotalCount) : 0
double finalErr = grandTotalCount > 0 ? ((grandTotalErrors / grandTotalCount) * 100) : 0
finalErr = Math.round(finalErr * 100.0) / 100.0
String finalStatus = "PASS"
if (finalErr > 3 || finalAvg > 3000 || stepFailed) {
finalStatus = "FAIL"
}
def jsonBuilder = new JsonBuilder(reportList)
props.put("JSON_DETAILS_STRING", jsonBuilder.toString())
props.put("FINAL_AVG", String.valueOf(finalAvg))
props.put("FINAL_ERR", String.valueOf(finalErr))
props.put("FINAL_STATUS", finalStatus)
log.info("Final Stats: Avg=${finalAvg}ms, TotalErr=${finalErr}%, Status=${finalStatus}")
log.info("Detailed report prepared for ${reportList.size()} items.")
Also in tearDown Thread Group add HTTP Request Sampler.
- Set the Method to POST and paste your Jira Webhook URL.
- Add an HTTP Header Manager and set Content-Type to application/json.
- In the Body Data of your HTTP Request, paste this JSON payload:
{
"token": "${__P(token, YOUR_TOKEN)}",
"issueId": "${__P(issueId, ISSUE_ID)}",
"avgResponseTime": ${__P(FINAL_AVG, 0)},
"errorRate": ${__P(FINAL_ERR, 0)},
"status": "${__P(FINAL_STATUS, PASS)}",
"details": ${__P(JSON_DETAILS_STRING, [])}
}
Also, don’t forget to fill in:
- Server name or IP field with your url like ‘{uuid-from-jira-config-page}.hello.atlassian-dev.net
- Path filed with your url’s path part, like : ‘/x1/Z-U7s9ZwttETBesD2ri07HJYBU’
How to find the Numeric Issue ID:
Open the Jira Issue you are testing.
Look at the URL in your browser.
— If you are on a Board: You will see ...&selectedIssue=10023. The number is the ID.
— If you are in the direct issue view: You can navigate to Jira ticket → click ‘Actions’ button → click ‘Export XML’ → copy value of ‘key_id’, i.e. KAN-7 (here you’ll need to copy 10134)
Note: You can trigger this script in your GitHub Actions, GitLab CI, or Jenkins pipeline dynamically passing the current Jira Issue ID based on the branch name!
The Result: Performance at a Glance
The moment your JMeter test finishes, the HTTP request fires, and your developers will instantly see the core metrics right on the Jira issue panel:
They can also click to expand the details and see the exact breakdown of your HTTP Samplers:
Conclusion
By pushing JMeter results directly into Jira, you eliminate ZIP files, reduce manual reporting, and give developers immediate feedback exactly where they track their work.
👉 Try JMeter Performance Analytics for Jira on the Atlassian Marketplace!
If you found this helpful, follow Orbit A on LinkedIn. We are building a suite of native Atlassian apps for QA and DevOps teams!




Top comments (0)