Jira / JSM Hourly User Peak Analyzer - Data Flow
Activity Signal
User activity is captured through Forge modules in both Jira and JSM.
Jira modules include:
jira:globalBackgroundScript
jira:issueViewBackgroundScript
jira:globalPage
JSM modules include:
jiraServiceManagement:portalHeader
jiraServiceManagement:portalRequestDetail
Activity signals are sent in two cases:
When a page or module loads
Periodically (heartbeat) while the tab remains active, roughly every 60 seconds
In simple terms:
User opens a page or stays active
Forge module sends an activity signal
Backend Processing
The frontend sends each activity event to the backend using the recordActivity resolver.
On the backend:
The product (Jira vs JSM) is determined from the Forge context, not from the frontend
The current accountId is read from the request context
It is immediately converted into an anonymized SHA-256 user key
Raw account IDs are never stored.
Activity Storage
The system keeps only the latest activity per user per product.
Storage keys:
activity:user:{userKey} for Jira
activity:jsm:user:{userKey} for JSM
Each record includes:
activityUserKey
product
lastSeen
source
New activity updates the lastSeen value.
Frequent signals, such as heartbeat events, are deduplicated to avoid excessive writes.
Active User Calculation
A scheduled job runs every 5 minutes.
It:
Scans the latest activity records for each product
Counts users whose lastSeen is within the last 10 minutes
Removes stale records after roughly 20 minutes
Hourly Aggregation
For each hour, the system records the peak number of active users observed during that period.
Data is stored under:
metrics:hourly-history:day:{YYYY-MM-DD}
Each hourly entry contains separate counts for Jira and JSM.
Reporting
The reporting UI is exposed through a jira:adminPage.
From there, administrators can view:
Hourly peak charts
Daily trend charts
Drill-down views for specific days
PDF exports of the current report
Access to reporting is restricted to the admin page context.
End-to-End Flow
User activity (page load or heartbeat)
-> Forge module sends signal
-> Backend hashes user ID
-> Latest activity is stored
-> Scheduled job counts active users
-> Hourly peak is recorded
-> Admin dashboard displays results
Key Design Principles
Privacy-first: raw account IDs are never stored
Backend-driven classification: Jira vs JSM is determined from Forge context
Lightweight model: only the latest activity per user is stored
Stable counting: heartbeat and deduplication balance accuracy and performance
Product separation: Jira and JSM activity are tracked independently
Accuracy Notes
Atlassian Cloud does not provide a native API for real-time “currently active users” in Jira or JSM, so exact concurrency cannot be measured.
This app uses module load events and heartbeat signals as a practical approximation.
As a result, a user may be counted as active while a page remains open and heartbeats continue, even without direct interaction. This can lead to slight overcounting in some cases.
This trade-off is intentional. For peak reporting, it is generally safer to slightly overcount than to undercount, since undercounting can hide real usage spikes.
The reported values should be understood as observed activity-based peaks, not exact Atlassian session counts.