Set up delivery performance scorecards
If you signed up for Port on or after May 1, 2026, these scorecards are already set up in your portal. You can follow this guide to customize the thresholds and rules to match your organization's standards.
Scorecards let you define maturity levels for your services and teams, giving engineering leaders a clear view of which areas meet delivery standards and which need attention.
This guide demonstrates how to set up Delivery Performance scorecards at different levels of the organization:
- Service: PR/MR throughput, cycle time, stale PR/MR management for individual services.
- Team: Same metrics normalized per-service so teams are compared fairly.
- Group: Executive-level delivery health for business units.
- Organization: Top-level delivery view across the entire org.
Each scorecard evaluates entities against progressive maturity levels: Bronze, Silver, and Gold. Thresholds are informed by DORA benchmarks and industry engineering data.
Common use cases
- Set clear, measurable delivery expectations across engineering teams.
- Identify services that are falling behind on cycle time, throughput, or stale PR/MR hygiene.
- Compare team and group delivery maturity at a glance and drive improvement initiatives.
- Gate deployments or trigger alerts when services drop below a minimum scorecard level.
Prerequisites
This guide assumes the following:
- You have a Port account and have completed the onboarding process.
- You have completed the Create foundational Engineering Intelligence data model guide, which provisions the core Organization, Team, and Service blueprints (with team ownership on services) for GitHub, GitLab, and Azure DevOps.
- GitHub (Ocean)
- GitLab
- Azure DevOps
- You have completed the Set up PR delivery metrics guide, which configures the required
github_*properties on theservice,_team, andorganizationblueprints.
- You have completed the Set up MR delivery metrics guide, which configures the required
gitlab_*properties on theserviceand_teamblueprints using the GitLab Ocean integration.
- You have completed the Set up PR delivery metrics guide, which configures the required
ado_*properties on theservice,_team, andorganizationblueprints using the Azure DevOps integration.
Maturity levels
Port scorecards use four fixed maturity levels. An entity must pass all rules at a given level (and all levels below it) to achieve that level.
| Level | Progression | Description |
|---|---|---|
| Basic | 0 (default) | Entity exists but meets no scorecard criteria |
| Bronze | 1 | Foundational hygiene and minimum viable standards |
| Silver | 2 | Good practices - actively maintained, reasonable thresholds |
| Gold | 3 | Excellence - elite-tier metrics |
Create the scorecards
PR/MR throughput and cycle time targets aligned with DORA benchmarks and industry engineering data. Select the level you want to configure:
- Service
- Team
- Group
- Organization
Blueprint: Service
- GitHub (Ocean)
- GitLab
- Azure DevOps
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Merged PRs >= 2/week | Bronze | github_merged_prs_last_month | >= 8 |
| 2 | Open PRs <= 8 | Bronze | github_open_prs | <= 8 |
| 3 | Stale PR share <= 10% | Bronze | github_stale_pr_share_percent | <= 10 |
| 4 | MR cycle time < 7 days | Bronze | github_pr_cycle_time | < 168 hours |
| 5 | Open PRs <= 5 | Silver | github_open_prs | <= 5 |
| 6 | Stale PRs <= 1 | Silver | github_stale_prs_7d | <= 1 |
| 7 | PR cycle time < 24h | Silver | github_pr_cycle_time | < 24 hours |
| 8 | Throughput not degrading | Silver | github_throughput_trend | != "Degrading" |
| 9 | Merged PRs >= 5/week | Silver | github_merged_prs_last_month | >= 20 |
| 10 | Open PRs <= 3 | Gold | github_open_prs | <= 3 |
| 11 | Stale PRs = 0 | Gold | github_stale_prs_7d | = 0 |
| 12 | PR cycle time < 1h | Gold | github_pr_cycle_time | < 1 hour |
| 13 | PR cycle time not degrading | Gold | github_cycle_time_trend | != "Degrading" |
| 14 | Merged PRs >= 10/week | Gold | github_merged_prs_last_month | >= 40 |
Create the delivery performance scorecard on the service blueprint
-
Go to the Builder page of your portal.
-
Search for the Service blueprint and select it.
-
Click on the Scorecards tab.
-
If the
delivery_performancescorecard does not exist, click + New Scorecard. If it already exists, open it instead. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Paste the following JSON configuration:
Service Delivery Performance scorecard - GitHub (click to expand)
{"identifier": "delivery_performance","title": "Delivery Performance","levels": [{"color": "paleBlue","title": "Basic"},{"color": "bronze","title": "Bronze"},{"color": "silver","title": "Silver"},{"color": "gold","title": "Gold"}],"rules": [{"identifier": "github_has_merged_prs","title": "Merged PRs >= 2/week","description": "Service merges at least 8 PRs per month, indicating active development.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_last_month","value": 8}]}},{"identifier": "github_manageable_open_prs","title": "Open PRs <= 8","description": "Keeps the number of open PRs manageable to avoid review overload.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_open_prs","value": 8}]}},{"identifier": "github_low_stale_prs","title": "Stale PR share <= 10%","description": "No more than 10% of open PRs are older than 7 days.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_stale_pr_share_percent","value": 10}]}},{"identifier": "github_cycle_time_under_7d","title": "MR cycle time < 7 days","description": "Average time from PR creation to merge is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 168}]}},{"identifier": "github_good_open_pr_management","title": "Open PRs <= 5","description": "Tighter open PR limit indicating strong review discipline.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_open_prs","value": 5}]}},{"identifier": "github_minimal_stale_prs","title": "Stale PRs <= 1","description": "At most one PR has been open longer than 7 days.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_stale_prs_7d","value": 1}]}},{"identifier": "github_cycle_time_under_24h","title": "PR cycle time < 24h","description": "PRs are merged within a day on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 24}]}},{"identifier": "github_throughput_not_degrading","title": "Throughput not degrading","description": "Weekly merge rate is not declining compared to the monthly average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "github_throughput_trend","value": "Degrading"}]}},{"identifier": "github_good_throughput","title": "Merged PRs >= 5/week","description": "Service merges at least 20 PRs per month, showing strong delivery pace.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_last_month","value": 20}]}},{"identifier": "github_excellent_open_pr_management","title": "Open PRs <= 3","description": "Very few PRs are open at any time, indicating rapid review cycles.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_open_prs","value": 3}]}},{"identifier": "github_no_stale_prs","title": "Stale PRs = 0","description": "No open PRs have been sitting for more than 7 days.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "=","property": "github_stale_prs_7d","value": 0}]}},{"identifier": "github_cycle_time_under_1h","title": "PR cycle time < 1h","description": "PRs are merged in under an hour on average - elite performance.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 1}]}},{"identifier": "github_cycle_time_not_degrading","title": "PR cycle time not degrading","description": "Weekly cycle time is not increasing compared to the monthly average.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "github_cycle_time_trend","value": "Degrading"}]}},{"identifier": "github_excellent_throughput","title": "Merged PRs >= 10/week","description": "Service merges at least 40 PRs per month - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_last_month","value": 40}]}}]} -
Click Save to create the scorecard.
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Merged MRs >= 2/week | Bronze | gitlab_merged_mrs_last_month | >= 8 |
| 2 | Open MRs <= 8 | Bronze | gitlab_open_mrs | <= 8 |
| 3 | Stale MR share <= 10% | Bronze | gitlab_stale_mr_share_percent | <= 10 |
| 4 | MR cycle time < 7 days | Bronze | gitlab_mr_cycle_time | < 168 hours |
| 5 | Open MRs <= 5 | Silver | gitlab_open_mrs | <= 5 |
| 6 | Stale MRs <= 1 | Silver | gitlab_stale_mrs_7d | <= 1 |
| 7 | MR cycle time < 24h | Silver | gitlab_mr_cycle_time | < 24 hours |
| 8 | Throughput not degrading | Silver | gitlab_throughput_trend | != "Degrading" |
| 9 | Merged MRs >= 5/week | Silver | gitlab_merged_mrs_last_month | >= 20 |
| 10 | Open MRs <= 3 | Gold | gitlab_open_mrs | <= 3 |
| 11 | Stale MRs = 0 | Gold | gitlab_stale_mrs_7d | = 0 |
| 12 | MR cycle time < 1h | Gold | gitlab_mr_cycle_time | < 1 hour |
| 13 | MR cycle time not degrading | Gold | gitlab_cycle_time_trend | != "Degrading" |
| 14 | Merged MRs >= 10/week | Gold | gitlab_merged_mrs_last_month | >= 40 |
Add GitLab rules to the delivery performance scorecard on the service blueprint
-
Go to the Builder page of your portal.
-
Search for the Service blueprint and select it.
-
Click on the Scorecards tab.
-
Open the existing
delivery_performancescorecard. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Append the following rules to the
rulesarray:Rules to append to existing scorecard - GitLab (click to expand)
[{"identifier": "gitlab_has_merged_mrs","title": "Merged MRs >= 2/week","description": "Service merges at least 8 MRs per month, indicating active development.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 8}]}},{"identifier": "gitlab_manageable_open_mrs","title": "Open MRs <= 8","description": "Keeps the number of open MRs manageable to avoid review overload.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_open_mrs","value": 8}]}},{"identifier": "gitlab_low_stale_mrs","title": "Stale MR share <= 10%","description": "No more than 10% of open MRs are older than 7 days.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_stale_mr_share_percent","value": 10}]}},{"identifier": "gitlab_cycle_time_under_7d","title": "MR cycle time < 7 days","description": "Average time from MR creation to merge is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 168}]}},{"identifier": "gitlab_good_open_mr_management","title": "Open MRs <= 5","description": "Tighter open MR limit indicating strong review discipline.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_open_mrs","value": 5}]}},{"identifier": "gitlab_minimal_stale_mrs","title": "Stale MRs <= 1","description": "At most one MR has been open longer than 7 days.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_stale_mrs_7d","value": 1}]}},{"identifier": "gitlab_cycle_time_under_24h","title": "MR cycle time < 24h","description": "MRs are merged within a day on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 24}]}},{"identifier": "gitlab_throughput_not_degrading","title": "Throughput not degrading","description": "Weekly merge rate is not declining compared to the monthly average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "gitlab_throughput_trend","value": "Degrading"}]}},{"identifier": "gitlab_good_throughput","title": "Merged MRs >= 5/week","description": "Service merges at least 20 MRs per month, showing strong delivery pace.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 20}]}},{"identifier": "gitlab_excellent_open_mr_management","title": "Open MRs <= 3","description": "Very few MRs are open at any time, indicating rapid review cycles.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_open_mrs","value": 3}]}},{"identifier": "gitlab_no_stale_mrs","title": "Stale MRs = 0","description": "No open MRs have been sitting for more than 7 days.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "=","property": "gitlab_stale_mrs_7d","value": 0}]}},{"identifier": "gitlab_cycle_time_under_1h","title": "MR cycle time < 1h","description": "MRs are merged in under an hour on average - elite performance.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 1}]}},{"identifier": "gitlab_cycle_time_not_degrading","title": "MR cycle time not degrading","description": "Weekly cycle time is not increasing compared to the monthly average.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "gitlab_cycle_time_trend","value": "Degrading"}]}},{"identifier": "gitlab_excellent_throughput","title": "Merged MRs >= 10/week","description": "Service merges at least 40 MRs per month - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 40}]}}] -
Click Save to update the scorecard.
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Merged PRs >= 2/week | Bronze | ado_merged_prs_last_month | >= 8 |
| 2 | Open PRs <= 8 | Bronze | ado_open_prs | <= 8 |
| 3 | Stale PR share <= 10% | Bronze | ado_stale_pr_share_percent | <= 10 |
| 4 | PR cycle time < 7 days | Bronze | ado_pr_cycle_time | < 168 hours |
| 5 | Open PRs <= 5 | Silver | ado_open_prs | <= 5 |
| 6 | Stale PRs <= 1 | Silver | ado_stale_prs_7d | <= 1 |
| 7 | PR cycle time < 24h | Silver | ado_pr_cycle_time | < 24 hours |
| 8 | Throughput not degrading | Silver | ado_throughput_trend | != "Degrading" |
| 9 | Merged PRs >= 5/week | Silver | ado_merged_prs_last_month | >= 20 |
| 10 | Open PRs <= 3 | Gold | ado_open_prs | <= 3 |
| 11 | Stale PRs = 0 | Gold | ado_stale_prs_7d | = 0 |
| 12 | PR cycle time < 1h | Gold | ado_pr_cycle_time | < 1 hour |
| 13 | PR cycle time not degrading | Gold | ado_cycle_time_trend | != "Degrading" |
| 14 | Merged PRs >= 10/week | Gold | ado_merged_prs_last_month | >= 40 |
Add Azure DevOps rules to the delivery performance scorecard on the service blueprint
-
Go to the Builder page of your portal.
-
Search for the Service blueprint and select it.
-
Click on the Scorecards tab.
-
Open the existing
delivery_performancescorecard. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Append the following rules to the
rulesarray:Rules to append to existing scorecard - Azure DevOps (click to expand)
[{"identifier": "ado_has_merged_prs","title": "Merged PRs >= 2/week","description": "Service merges at least 8 PRs per month, indicating active development.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "ado_merged_prs_last_month","value": 8}]}},{"identifier": "ado_manageable_open_prs","title": "Open PRs <= 8","description": "Keeps the number of open PRs manageable to avoid review overload.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_open_prs","value": 8}]}},{"identifier": "ado_low_stale_prs","title": "Stale PR share <= 10%","description": "No more than 10% of open PRs are older than 7 days.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_stale_pr_share_percent","value": 10}]}},{"identifier": "ado_cycle_time_under_7d","title": "PR cycle time < 7 days","description": "Average time from PR creation to completion is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 168}]}},{"identifier": "ado_good_open_pr_management","title": "Open PRs <= 5","description": "Tighter open PR limit indicating strong review discipline.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_open_prs","value": 5}]}},{"identifier": "ado_minimal_stale_prs","title": "Stale PRs <= 1","description": "At most one PR has been open longer than 7 days.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_stale_prs_7d","value": 1}]}},{"identifier": "ado_cycle_time_under_24h","title": "PR cycle time < 24h","description": "PRs are completed within a day on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 24}]}},{"identifier": "ado_throughput_not_degrading","title": "Throughput not degrading","description": "Weekly merge rate is not declining compared to the monthly average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "ado_throughput_trend","value": "Degrading"}]}},{"identifier": "ado_good_throughput","title": "Merged PRs >= 5/week","description": "Service merges at least 20 PRs per month, showing strong delivery pace.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "ado_merged_prs_last_month","value": 20}]}},{"identifier": "ado_excellent_open_pr_management","title": "Open PRs <= 3","description": "Very few PRs are open at any time, indicating rapid review cycles.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_open_prs","value": 3}]}},{"identifier": "ado_no_stale_prs","title": "Stale PRs = 0","description": "No open PRs have been sitting for more than 7 days.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "=","property": "ado_stale_prs_7d","value": 0}]}},{"identifier": "ado_cycle_time_under_1h","title": "PR cycle time < 1h","description": "PRs are completed in under an hour on average - elite performance.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 1}]}},{"identifier": "ado_cycle_time_not_degrading","title": "PR cycle time not degrading","description": "Weekly cycle time is not increasing compared to the monthly average.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "ado_cycle_time_trend","value": "Degrading"}]}},{"identifier": "ado_excellent_throughput","title": "Merged PRs >= 10/week","description": "Service merges at least 40 PRs per month - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "ado_merged_prs_last_month","value": 40}]}}] -
Click Save to update the scorecard.
The ado_* properties are populated by the Azure DevOps integration configured in the Set up PR delivery metrics guide. Ensure the integration has run at least once before checking scorecard results.
Blueprint: Team
Same thresholds as service-level, but absolute count rules use per-service normalized metrics so that teams are evaluated fairly regardless of how many services they own. Rate, trend, and cycle-time rules are unchanged since they already scale naturally.
- GitHub (Ocean)
- GitLab
- Azure DevOps
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Merged PRs >= 2/week per service | Bronze | github_merged_prs_per_service_last_month | >= 8 |
| 2 | Open PRs <= 8 per service | Bronze | github_open_prs_per_service | <= 8 |
| 3 | Stale PR share <= 10% | Bronze | github_stale_pr_share_percent | <= 10 |
| 4 | PR cycle time < 7 days | Bronze | github_pr_cycle_time | < 168 hours |
| 5 | Open PRs <= 5 per service | Silver | github_open_prs_per_service | <= 5 |
| 6 | Stale PRs <= 1 per service | Silver | github_stale_prs_per_service_7d | <= 1 |
| 7 | PR cycle time < 24h | Silver | github_pr_cycle_time | < 24 hours |
| 8 | Throughput not degrading | Silver | github_throughput_trend | != "Degrading" |
| 9 | Merged PRs >= 5/week per service | Silver | github_merged_prs_per_service_last_month | >= 20 |
| 10 | Open PRs <= 3 per service | Gold | github_open_prs_per_service | <= 3 |
| 11 | Stale PRs = 0 per service | Gold | github_stale_prs_per_service_7d | = 0 |
| 12 | PR cycle time < 1h | Gold | github_pr_cycle_time | < 1 hour |
| 13 | PR cycle time not degrading | Gold | github_cycle_time_trend | != "Degrading" |
| 14 | Merged PRs >= 10/week per service | Gold | github_merged_prs_per_service_last_month | >= 40 |
Create the delivery performance scorecard on the team blueprint
-
Go to the Builder page.
-
Search for the Team blueprint and select it.
-
Click on the Scorecards tab.
-
If the
team_delivery_performancescorecard does not exist, click + New Scorecard. If it already exists, open it instead. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Paste the following JSON configuration:
Team Delivery Performance scorecard - GitHub (click to expand)
{"identifier": "team_delivery_performance","title": "Delivery Performance","filter": {"combinator": "and","conditions": [{"operator": "=","property": "type","value": "team"}]},"levels": [{"color": "paleBlue","title": "Basic"},{"color": "bronze","title": "Bronze"},{"color": "silver","title": "Silver"},{"color": "gold","title": "Gold"}],"rules": [{"identifier": "github_has_merged_prs","title": "Merged PRs >= 2/week per service","description": "Each service in the team merges at least 8 PRs per month on average.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 8}]}},{"identifier": "github_manageable_open_prs","title": "Open PRs <= 8 per service","description": "Open PR count per service stays manageable.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_open_prs_per_service","value": 8}]}},{"identifier": "github_low_stale_prs","title": "Stale PR share <= 10%","description": "No more than 10% of the team's open PRs are older than 7 days.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_stale_pr_share_percent","value": 10}]}},{"identifier": "github_cycle_time_under_7d","title": "PR cycle time < 7 days","description": "Average PR cycle time across team services is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 168}]}},{"identifier": "github_good_open_pr_management","title": "Open PRs <= 5 per service","description": "Tighter open PR limit per service.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_open_prs_per_service","value": 5}]}},{"identifier": "github_minimal_stale_prs","title": "Stale PRs <= 1 per service","description": "At most one stale PR per service on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_stale_prs_per_service_7d","value": 1}]}},{"identifier": "github_cycle_time_under_24h","title": "PR cycle time < 24h","description": "Team-wide PR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 24}]}},{"identifier": "github_throughput_not_degrading","title": "Throughput not degrading","description": "Team's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "github_throughput_trend","value": "Degrading"}]}},{"identifier": "github_good_throughput","title": "Merged PRs >= 5/week per service","description": "Each service in the team merges at least 20 PRs per month on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 20}]}},{"identifier": "github_excellent_open_pr_management","title": "Open PRs <= 3 per service","description": "Very few open PRs per service.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_open_prs_per_service","value": 3}]}},{"identifier": "github_no_stale_prs","title": "Stale PRs = 0 per service","description": "No stale PRs across any of the team's services.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "=","property": "github_stale_prs_per_service_7d","value": 0}]}},{"identifier": "github_cycle_time_under_1h","title": "PR cycle time < 1h","description": "Team-wide PR cycle time is under one hour - elite performance.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 1}]}},{"identifier": "github_cycle_time_not_degrading","title": "PR cycle time not degrading","description": "Team's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "github_cycle_time_trend","value": "Degrading"}]}},{"identifier": "github_excellent_throughput","title": "Merged PRs >= 10/week per service","description": "Each service merges at least 40 PRs per month on average - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 40}]}}]} -
Click Save to create the scorecard.
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Merged MRs >= 2/week per service | Bronze | gitlab_merged_mrs_last_month | >= 8 |
| 2 | Open MRs <= 8 per service | Bronze | gitlab_open_mrs | <= 8 |
| 3 | Stale MR share <= 10% | Bronze | gitlab_stale_mr_share_percent | <= 10 |
| 4 | MR cycle time < 7 days | Bronze | gitlab_mr_cycle_time | < 168 hours |
| 5 | Open MRs <= 5 per service | Silver | gitlab_open_mrs | <= 5 |
| 6 | Stale MRs <= 1 per service | Silver | gitlab_stale_mrs_7d | <= 1 |
| 7 | MR cycle time < 24h | Silver | gitlab_mr_cycle_time | < 24 hours |
| 8 | Throughput not degrading | Silver | gitlab_throughput_trend | != "Degrading" |
| 9 | Merged MRs >= 5/week per service | Silver | gitlab_merged_mrs_last_month | >= 20 |
| 10 | Open MRs <= 3 per service | Gold | gitlab_open_mrs | <= 3 |
| 11 | Stale MRs = 0 per service | Gold | gitlab_stale_mrs_7d | = 0 |
| 12 | MR cycle time < 1h | Gold | gitlab_mr_cycle_time | < 1 hour |
| 13 | MR cycle time not degrading | Gold | gitlab_cycle_time_trend | != "Degrading" |
| 14 | Merged MRs >= 10/week per service | Gold | gitlab_merged_mrs_last_month | >= 40 |
The GitLab _team blueprint aggregates MR metrics across all services owned by the team. The rules above use the team-level gitlab_* properties directly (e.g. gitlab_open_mrs, gitlab_mr_cycle_time), which are already calculated as team-wide aggregates on the _team blueprint.
Add GitLab rules to the delivery performance scorecard on the team blueprint
-
Go to the Builder page.
-
Search for the Team blueprint and select it.
-
Click on the Scorecards tab.
-
Open the existing
team_delivery_performancescorecard. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Append the following rules to the
rulesarray:Rules to append to existing scorecard - GitLab (click to expand)
[{"identifier": "gitlab_has_merged_mrs","title": "Merged MRs >= 2/week","description": "Team merges at least 8 MRs per month on average, indicating active development.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 8}]}},{"identifier": "gitlab_manageable_open_mrs","title": "Open MRs <= 8","description": "Open MR count stays manageable to avoid review overload.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_open_mrs","value": 8}]}},{"identifier": "gitlab_low_stale_mrs","title": "Stale MR share <= 10%","description": "No more than 10% of the team's open MRs are older than 7 days.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_stale_mr_share_percent","value": 10}]}},{"identifier": "gitlab_cycle_time_under_7d","title": "MR cycle time < 7 days","description": "Average MR cycle time across team services is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 168}]}},{"identifier": "gitlab_good_open_mr_management","title": "Open MRs <= 5","description": "Tighter open MR limit indicating strong review discipline.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_open_mrs","value": 5}]}},{"identifier": "gitlab_minimal_stale_mrs","title": "Stale MRs <= 1","description": "At most one stale MR on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_stale_mrs_7d","value": 1}]}},{"identifier": "gitlab_cycle_time_under_24h","title": "MR cycle time < 24h","description": "Team-wide MR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 24}]}},{"identifier": "gitlab_throughput_not_degrading","title": "Throughput not degrading","description": "Team's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "gitlab_throughput_trend","value": "Degrading"}]}},{"identifier": "gitlab_good_throughput","title": "Merged MRs >= 5/week","description": "Team merges at least 20 MRs per month on average, showing strong delivery pace.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 20}]}},{"identifier": "gitlab_excellent_open_mr_management","title": "Open MRs <= 3","description": "Very few open MRs at any time, indicating rapid review cycles.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_open_mrs","value": 3}]}},{"identifier": "gitlab_no_stale_mrs","title": "Stale MRs = 0","description": "No open MRs have been sitting for more than 7 days.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "=","property": "gitlab_stale_mrs_7d","value": 0}]}},{"identifier": "gitlab_cycle_time_under_1h","title": "MR cycle time < 1h","description": "Team-wide MR cycle time is under one hour - elite performance.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 1}]}},{"identifier": "gitlab_cycle_time_not_degrading","title": "MR cycle time not degrading","description": "Team's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "gitlab_cycle_time_trend","value": "Degrading"}]}},{"identifier": "gitlab_excellent_throughput","title": "Merged MRs >= 10/week","description": "Team merges at least 40 MRs per month on average - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 40}]}}] -
Click Save to update the scorecard.
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Merged PRs >= 2/week per service | Bronze | ado_merged_prs_per_service_last_month | >= 8 |
| 2 | Open PRs <= 8 per service | Bronze | ado_open_prs_per_service | <= 8 |
| 3 | Stale PR share <= 10% | Bronze | ado_stale_pr_share_percent | <= 10 |
| 4 | PR cycle time < 7 days | Bronze | ado_pr_cycle_time | < 168 hours |
| 5 | Open PRs <= 5 per service | Silver | ado_open_prs_per_service | <= 5 |
| 6 | Stale PRs <= 1 per service | Silver | ado_stale_prs_per_service_7d | <= 1 |
| 7 | PR cycle time < 24h | Silver | ado_pr_cycle_time | < 24 hours |
| 8 | Throughput not degrading | Silver | ado_throughput_trend | != "Degrading" |
| 9 | Merged PRs >= 5/week per service | Silver | ado_merged_prs_per_service_last_month | >= 20 |
| 10 | Open PRs <= 3 per service | Gold | ado_open_prs_per_service | <= 3 |
| 11 | Stale PRs = 0 per service | Gold | ado_stale_prs_per_service_7d | = 0 |
| 12 | PR cycle time < 1h | Gold | ado_pr_cycle_time | < 1 hour |
| 13 | PR cycle time not degrading | Gold | ado_cycle_time_trend | != "Degrading" |
| 14 | Merged PRs >= 10/week per service | Gold | ado_merged_prs_per_service_last_month | >= 40 |
Add Azure DevOps rules to the delivery performance scorecard on the team blueprint
-
Go to the Builder page.
-
Search for the Team blueprint and select it.
-
Click on the Scorecards tab.
-
Open the existing
team_delivery_performancescorecard. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Append the following rules to the
rulesarray:Rules to append to existing scorecard - Azure DevOps (click to expand)
[{"identifier": "ado_has_merged_prs","title": "Merged PRs >= 2/week per service","description": "Each service in the team merges at least 8 PRs per month on average.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "ado_merged_prs_per_service_last_month","value": 8}]}},{"identifier": "ado_manageable_open_prs","title": "Open PRs <= 8 per service","description": "Open PR count per service stays manageable.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_open_prs_per_service","value": 8}]}},{"identifier": "ado_low_stale_prs","title": "Stale PR share <= 10%","description": "No more than 10% of the team's open PRs are older than 7 days.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_stale_pr_share_percent","value": 10}]}},{"identifier": "ado_cycle_time_under_7d","title": "PR cycle time < 7 days","description": "Average PR cycle time across team services is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 168}]}},{"identifier": "ado_good_open_pr_management","title": "Open PRs <= 5 per service","description": "Tighter open PR limit per service.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_open_prs_per_service","value": 5}]}},{"identifier": "ado_minimal_stale_prs","title": "Stale PRs <= 1 per service","description": "At most one stale PR per service on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_stale_prs_per_service_7d","value": 1}]}},{"identifier": "ado_cycle_time_under_24h","title": "PR cycle time < 24h","description": "Team-wide PR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 24}]}},{"identifier": "ado_throughput_not_degrading","title": "Throughput not degrading","description": "Team's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "ado_throughput_trend","value": "Degrading"}]}},{"identifier": "ado_good_throughput","title": "Merged PRs >= 5/week per service","description": "Each service in the team merges at least 20 PRs per month on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "ado_merged_prs_per_service_last_month","value": 20}]}},{"identifier": "ado_excellent_open_pr_management","title": "Open PRs <= 3 per service","description": "Very few open PRs per service.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_open_prs_per_service","value": 3}]}},{"identifier": "ado_no_stale_prs","title": "Stale PRs = 0 per service","description": "No stale PRs across any of the team's services.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "=","property": "ado_stale_prs_per_service_7d","value": 0}]}},{"identifier": "ado_cycle_time_under_1h","title": "PR cycle time < 1h","description": "Team-wide PR cycle time is under one hour - elite performance.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 1}]}},{"identifier": "ado_cycle_time_not_degrading","title": "PR cycle time not degrading","description": "Team's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "ado_cycle_time_trend","value": "Degrading"}]}},{"identifier": "ado_excellent_throughput","title": "Merged PRs >= 10/week per service","description": "Each service merges at least 40 PRs per month on average - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "ado_merged_prs_per_service_last_month","value": 40}]}}] -
Click Save to update the scorecard.
The ado_* properties are populated by the Azure DevOps integration configured in the Set up PR delivery metrics guide. Ensure the integration has run at least once before checking scorecard results.
Blueprint: Team (filtered to type = "group")
Executive-level delivery health for business units. Uses rate, trend, and per-service normalized throughput metrics since groups aggregate multiple teams.
- GitHub (Ocean)
- GitLab
- Azure DevOps
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Stale PR share <= 10% | Bronze | github_stale_pr_share_percent | <= 10 |
| 2 | Avg PR cycle time < 7 days | Bronze | github_pr_cycle_time | < 168 hours |
| 3 | Merged PRs >= 2/week per service | Bronze | github_merged_prs_per_service_last_month | >= 8 |
| 4 | Avg PR cycle time < 24h | Silver | github_pr_cycle_time | < 24 hours |
| 5 | Throughput not degrading | Silver | github_throughput_trend | != "Degrading" |
| 6 | Merged PRs >= 5/week per service | Silver | github_merged_prs_per_service_last_month | >= 20 |
| 7 | Avg PR cycle time < 1h | Gold | github_pr_cycle_time | < 1 hour |
| 8 | PR cycle time not degrading | Gold | github_cycle_time_trend | != "Degrading" |
| 9 | Merged PRs >= 10/week per service | Gold | github_merged_prs_per_service_last_month | >= 40 |
Create the delivery performance scorecard for groups
-
Go to the Builder page.
-
Search for the Team blueprint and select it.
-
Click on the Scorecards tab.
-
If the
group_delivery_performancescorecard does not exist, click + New Scorecard. If it already exists, open it instead. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Paste the following JSON configuration:
Group Delivery Performance scorecard - GitHub (click to expand)
{"identifier": "group_delivery_performance","title": "Delivery Performance (Group)","filter": {"combinator": "and","conditions": [{"operator": "=","property": "type","value": "group"}]},"levels": [{"color": "paleBlue","title": "Basic"},{"color": "bronze","title": "Bronze"},{"color": "silver","title": "Silver"},{"color": "gold","title": "Gold"}],"rules": [{"identifier": "github_low_stale_prs","title": "Stale PR share <= 10%","description": "No more than 10% of open PRs across the group are stale.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_stale_pr_share_percent","value": 10}]}},{"identifier": "github_cycle_time_under_7d","title": "Avg PR cycle time < 7 days","description": "Group-wide average PR cycle time is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 168}]}},{"identifier": "github_has_merged_prs","title": "Merged PRs >= 2/week per service","description": "Each service in the group merges at least 8 PRs per month on average.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 8}]}},{"identifier": "github_cycle_time_under_24h","title": "Avg PR cycle time < 24h","description": "Group-wide PR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 24}]}},{"identifier": "github_throughput_not_degrading","title": "Throughput not degrading","description": "Group's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "github_throughput_trend","value": "Degrading"}]}},{"identifier": "github_good_throughput","title": "Merged PRs >= 5/week per service","description": "Each service merges at least 20 PRs per month on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 20}]}},{"identifier": "github_cycle_time_under_1h","title": "Avg PR cycle time < 1h","description": "Group-wide PR cycle time is under one hour.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 1}]}},{"identifier": "github_cycle_time_not_degrading","title": "PR cycle time not degrading","description": "Group's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "github_cycle_time_trend","value": "Degrading"}]}},{"identifier": "github_excellent_throughput","title": "Merged PRs >= 10/week per service","description": "Each service merges at least 40 PRs per month on average - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 40}]}}]} -
Click Save to create the scorecard.
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Stale MR share <= 10% | Bronze | gitlab_stale_mr_share_percent | <= 10 |
| 2 | Avg MR cycle time < 7 days | Bronze | gitlab_mr_cycle_time | < 168 hours |
| 3 | Merged MRs >= 2/week | Bronze | gitlab_merged_mrs_last_month | >= 8 |
| 4 | Avg MR cycle time < 24h | Silver | gitlab_mr_cycle_time | < 24 hours |
| 5 | Throughput not degrading | Silver | gitlab_throughput_trend | != "Degrading" |
| 6 | Merged MRs >= 5/week | Silver | gitlab_merged_mrs_last_month | >= 20 |
| 7 | Avg MR cycle time < 1h | Gold | gitlab_mr_cycle_time | < 1 hour |
| 8 | MR cycle time not degrading | Gold | gitlab_cycle_time_trend | != "Degrading" |
| 9 | Merged MRs >= 10/week | Gold | gitlab_merged_mrs_last_month | >= 40 |
Add GitLab rules to the delivery performance scorecard for groups
-
Go to the Builder page.
-
Search for the Team blueprint and select it.
-
Click on the Scorecards tab.
-
Open the existing
group_delivery_performancescorecard. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Append the following rules to the
rulesarray:Rules to append to existing scorecard - GitLab (click to expand)
[{"identifier": "gitlab_low_stale_mrs","title": "Stale MR share <= 10%","description": "No more than 10% of open MRs across the group are stale.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_stale_mr_share_percent","value": 10}]}},{"identifier": "gitlab_cycle_time_under_7d","title": "Avg MR cycle time < 7 days","description": "Group-wide average MR cycle time is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 168}]}},{"identifier": "gitlab_has_merged_mrs","title": "Merged MRs >= 2/week","description": "Group merges at least 8 MRs per month on average.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 8}]}},{"identifier": "gitlab_cycle_time_under_24h","title": "Avg MR cycle time < 24h","description": "Group-wide MR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 24}]}},{"identifier": "gitlab_throughput_not_degrading","title": "Throughput not degrading","description": "Group's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "gitlab_throughput_trend","value": "Degrading"}]}},{"identifier": "gitlab_good_throughput","title": "Merged MRs >= 5/week","description": "Group merges at least 20 MRs per month on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 20}]}},{"identifier": "gitlab_cycle_time_under_1h","title": "Avg MR cycle time < 1h","description": "Group-wide MR cycle time is under one hour.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 1}]}},{"identifier": "gitlab_cycle_time_not_degrading","title": "MR cycle time not degrading","description": "Group's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "gitlab_cycle_time_trend","value": "Degrading"}]}},{"identifier": "gitlab_excellent_throughput","title": "Merged MRs >= 10/week","description": "Group merges at least 40 MRs per month on average - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 40}]}}] -
Click Save to update the scorecard.
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Stale PR share <= 10% | Bronze | ado_stale_pr_share_percent | <= 10 |
| 2 | Avg PR cycle time < 7 days | Bronze | ado_pr_cycle_time | < 168 hours |
| 3 | Avg PR cycle time < 24h | Silver | ado_pr_cycle_time | < 24 hours |
| 4 | Throughput not degrading | Silver | ado_throughput_trend | != "Degrading" |
| 5 | Avg PR cycle time < 1h | Gold | ado_pr_cycle_time | < 1 hour |
| 6 | PR cycle time not degrading | Gold | ado_cycle_time_trend | != "Degrading" |
Add Azure DevOps rules to the delivery performance scorecard for groups
-
Go to the Builder page.
-
Search for the Team blueprint and select it.
-
Click on the Scorecards tab.
-
Open the existing
group_delivery_performancescorecard. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Append the following rules to the
rulesarray:Rules to append to existing scorecard - Azure DevOps (click to expand)
[{"identifier": "ado_low_stale_prs","title": "Stale PR share <= 10%","description": "No more than 10% of open PRs across the group are stale.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_stale_pr_share_percent","value": 10}]}},{"identifier": "ado_cycle_time_under_7d","title": "Avg PR cycle time < 7 days","description": "Group-wide average PR cycle time is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 168}]}},{"identifier": "ado_cycle_time_under_24h","title": "Avg PR cycle time < 24h","description": "Group-wide PR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 24}]}},{"identifier": "ado_throughput_not_degrading","title": "Throughput not degrading","description": "Group's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "ado_throughput_trend","value": "Degrading"}]}},{"identifier": "ado_cycle_time_under_1h","title": "Avg PR cycle time < 1h","description": "Group-wide PR cycle time is under one hour.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 1}]}},{"identifier": "ado_cycle_time_not_degrading","title": "PR cycle time not degrading","description": "Group's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "ado_cycle_time_trend","value": "Degrading"}]}}] -
Click Save to update the scorecard.
The ado_* properties are populated by the Azure DevOps integration configured in the Set up PR delivery metrics guide. Ensure the integration has run at least once before checking scorecard results.
Blueprint: Organization
Executive-level delivery health for the entire organization. Uses rate, trend, and per-service normalized throughput metrics since the org aggregates all teams and services.
The GitLab integration does not populate an organization blueprint by default. If your setup does not include an organization blueprint with GitLab metrics, use the Group-level scorecard on your top-level group entity as an equivalent org-wide view.
- GitHub (Ocean)
- GitLab
- Azure DevOps
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Stale PR share <= 10% | Bronze | github_stale_pr_share_percent | <= 10 |
| 2 | Avg PR cycle time < 7 days | Bronze | github_pr_cycle_time | < 168 hours |
| 3 | Merged PRs >= 2/week per service | Bronze | github_merged_prs_per_service_last_month | >= 8 |
| 4 | Avg PR cycle time < 24h | Silver | github_pr_cycle_time | < 24 hours |
| 5 | Throughput not degrading | Silver | github_throughput_trend | != "Degrading" |
| 6 | Merged PRs >= 5/week per service | Silver | github_merged_prs_per_service_last_month | >= 20 |
| 7 | Avg PR cycle time < 1h | Gold | github_pr_cycle_time | < 1 hour |
| 8 | PR cycle time not degrading | Gold | github_cycle_time_trend | != "Degrading" |
| 9 | Merged PRs >= 10/week per service | Gold | github_merged_prs_per_service_last_month | >= 40 |
Create the delivery performance scorecard on the organization blueprint
-
Go to the Builder page.
-
Search for the Organization blueprint and select it.
-
Click on the Scorecards tab.
-
If the
org_delivery_performancescorecard does not exist, click + New Scorecard. If it already exists, open it instead. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Paste the following JSON configuration:
Organization Delivery Performance scorecard - GitHub (click to expand)
{"identifier": "org_delivery_performance","title": "Delivery Performance","levels": [{"color": "paleBlue","title": "Basic"},{"color": "bronze","title": "Bronze"},{"color": "silver","title": "Silver"},{"color": "gold","title": "Gold"}],"rules": [{"identifier": "github_low_stale_prs","title": "Stale PR share <= 10%","description": "No more than 10% of open PRs across the organization are stale.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "github_stale_pr_share_percent","value": 10}]}},{"identifier": "github_cycle_time_under_7d","title": "Avg PR cycle time < 7 days","description": "Organization-wide average PR cycle time is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 168}]}},{"identifier": "github_has_merged_prs","title": "Merged PRs >= 2/week per service","description": "Each service merges at least 8 PRs per month on average.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 8}]}},{"identifier": "github_cycle_time_under_24h","title": "Avg PR cycle time < 24h","description": "Organization-wide PR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 24}]}},{"identifier": "github_throughput_not_degrading","title": "Throughput not degrading","description": "Organization's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "github_throughput_trend","value": "Degrading"}]}},{"identifier": "github_good_throughput","title": "Merged PRs >= 5/week per service","description": "Each service merges at least 20 PRs per month on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 20}]}},{"identifier": "github_cycle_time_under_1h","title": "Avg PR cycle time < 1h","description": "Organization-wide PR cycle time is under one hour.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "github_pr_cycle_time","value": 1}]}},{"identifier": "github_cycle_time_not_degrading","title": "PR cycle time not degrading","description": "Organization's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "github_cycle_time_trend","value": "Degrading"}]}},{"identifier": "github_excellent_throughput","title": "Merged PRs >= 10/week per service","description": "Each service merges at least 40 PRs per month on average - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "github_merged_prs_per_service_last_month","value": 40}]}}]} -
Click Save to create the scorecard.
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Stale MR share <= 10% | Bronze | gitlab_stale_mr_share_percent | <= 10 |
| 2 | Avg MR cycle time < 7 days | Bronze | gitlab_mr_cycle_time | < 168 hours |
| 3 | Merged MRs >= 2/week | Bronze | gitlab_merged_mrs_last_month | >= 8 |
| 4 | Avg MR cycle time < 24h | Silver | gitlab_mr_cycle_time | < 24 hours |
| 5 | Throughput not degrading | Silver | gitlab_throughput_trend | != "Degrading" |
| 6 | Merged MRs >= 5/week | Silver | gitlab_merged_mrs_last_month | >= 20 |
| 7 | Avg MR cycle time < 1h | Gold | gitlab_mr_cycle_time | < 1 hour |
| 8 | MR cycle time not degrading | Gold | gitlab_cycle_time_trend | != "Degrading" |
| 9 | Merged MRs >= 10/week | Gold | gitlab_merged_mrs_last_month | >= 40 |
Apply this scorecard to your top-level group entity on the _team blueprint (filtered to type = "group"). Use the scorecard identifier org_delivery_performance to match the dashboard widgets.
Add GitLab rules to the delivery performance scorecard for the top-level group
-
Go to the Builder page.
-
Search for the Team blueprint and select it.
-
Click on the Scorecards tab.
-
Open the existing
org_delivery_performancescorecard. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Append the following rules to the
rulesarray:Rules to append to existing scorecard - GitLab (click to expand)
[{"identifier": "gitlab_low_stale_mrs","title": "Stale MR share <= 10%","description": "No more than 10% of open MRs across the organization are stale.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "gitlab_stale_mr_share_percent","value": 10}]}},{"identifier": "gitlab_cycle_time_under_7d","title": "Avg MR cycle time < 7 days","description": "Organization-wide average MR cycle time is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 168}]}},{"identifier": "gitlab_has_merged_mrs","title": "Merged MRs >= 2/week","description": "Organization merges at least 8 MRs per month on average.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 8}]}},{"identifier": "gitlab_cycle_time_under_24h","title": "Avg MR cycle time < 24h","description": "Organization-wide MR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 24}]}},{"identifier": "gitlab_throughput_not_degrading","title": "Throughput not degrading","description": "Organization's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "gitlab_throughput_trend","value": "Degrading"}]}},{"identifier": "gitlab_good_throughput","title": "Merged MRs >= 5/week","description": "Organization merges at least 20 MRs per month on average.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 20}]}},{"identifier": "gitlab_cycle_time_under_1h","title": "Avg MR cycle time < 1h","description": "Organization-wide MR cycle time is under one hour.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "gitlab_mr_cycle_time","value": 1}]}},{"identifier": "gitlab_cycle_time_not_degrading","title": "MR cycle time not degrading","description": "Organization's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "gitlab_cycle_time_trend","value": "Degrading"}]}},{"identifier": "gitlab_excellent_throughput","title": "Merged MRs >= 10/week","description": "Organization merges at least 40 MRs per month on average - top-tier throughput.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": ">=","property": "gitlab_merged_mrs_last_month","value": 40}]}}] -
Click Save to update the scorecard.
| # | Rule | Level | Property | Condition |
|---|---|---|---|---|
| 1 | Stale PR share <= 10% | Bronze | ado_stale_pr_share_percent | <= 10 |
| 2 | Avg PR cycle time < 7 days | Bronze | ado_pr_cycle_time | < 168 hours |
| 3 | Avg PR cycle time < 24h | Silver | ado_pr_cycle_time | < 24 hours |
| 4 | Throughput not degrading | Silver | ado_throughput_trend | != "Degrading" |
| 5 | Avg PR cycle time < 1h | Gold | ado_pr_cycle_time | < 1 hour |
| 6 | PR cycle time not degrading | Gold | ado_cycle_time_trend | != "Degrading" |
Add Azure DevOps rules to the delivery performance scorecard on the organization blueprint
-
Go to the Builder page.
-
Search for the Organization blueprint and select it.
-
Click on the Scorecards tab.
-
Open the existing
org_delivery_performancescorecard. -
Click on the
{...}button in the top right corner, and choose Edit JSON. -
Append the following rules to the
rulesarray:Rules to append to existing scorecard - Azure DevOps (click to expand)
[{"identifier": "ado_low_stale_prs","title": "Stale PR share <= 10%","description": "No more than 10% of open PRs across the organization are stale.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<=","property": "ado_stale_pr_share_percent","value": 10}]}},{"identifier": "ado_cycle_time_under_7d","title": "Avg PR cycle time < 7 days","description": "Organization-wide average PR cycle time is under one week.","level": "Bronze","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 168}]}},{"identifier": "ado_cycle_time_under_24h","title": "Avg PR cycle time < 24h","description": "Organization-wide PR cycle time is under 24 hours.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 24}]}},{"identifier": "ado_throughput_not_degrading","title": "Throughput not degrading","description": "Organization's weekly merge rate is not declining.","level": "Silver","query": {"combinator": "and","conditions": [{"operator": "!=","property": "ado_throughput_trend","value": "Degrading"}]}},{"identifier": "ado_cycle_time_under_1h","title": "Avg PR cycle time < 1h","description": "Organization-wide PR cycle time is under one hour.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "<","property": "ado_pr_cycle_time","value": 1}]}},{"identifier": "ado_cycle_time_not_degrading","title": "PR cycle time not degrading","description": "Organization's weekly cycle time is not increasing.","level": "Gold","query": {"combinator": "and","conditions": [{"operator": "!=","property": "ado_cycle_time_trend","value": "Degrading"}]}}] -
Click Save to update the scorecard.
The ado_* properties are populated by the Azure DevOps integration configured in the Set up PR delivery metrics guide. Ensure the integration has run at least once before checking scorecard results.
Visualize scorecard results
Once the scorecards are in place, create a dashboard to monitor delivery maturity across services and teams.
The dashboard JSON below uses github_* property identifiers for column configuration. If you are using the GitLab integration, the dashboard still works for scorecard-level widgets (pie charts and number charts). For table columns, replace any github_* property identifiers with the equivalent gitlab_* property identifiers (for example, replace github_pr_cycle_time with gitlab_mr_cycle_time) when editing the table widget columns in the Port UI after creation.
If you are using Azure DevOps, replace github_* property identifiers with the equivalent ado_* identifiers (for example, github_pr_cycle_time becomes ado_pr_cycle_time).
Create the dashboard
- Navigate to your software catalog.
- Click on the
+ Newbutton in the left sidebar. - Select New folder.
- Name the folder Engineering Intelligence and click Create.
- Inside the Engineering Intelligence folder, click
+ Newagain. - Select New dashboard.
- Name the dashboard Delivery Performance Scorecards and click Create.
Add widgets
You can populate the dashboard using either an API script or by manually creating each widget through the UI.
- API script
- Manual setup
The fastest way to set up the dashboard is by using Port's API to create all widgets at once.
Get your Port API token
-
In your Port portal, click on your profile picture in the top right corner.
-
Select Credentials.
-
Click Generate API token.
-
Copy the generated token and store it as an environment variable:
export PORT_ACCESS_TOKEN="YOUR_GENERATED_TOKEN"
If your portal is hosted in the EU region, replace api.port.io with api.port-eu.io in the dashboard creation command below.
Create the dashboard with widgets
Save the following JSON to a file named dp_scorecards_dashboard.json:Dashboard JSON payload (click to expand)
Then run the following command to create the dashboard with all widgets:
curl -s -X POST "https://api.port.io/v1/pages" \
-H "Authorization: Bearer $PORT_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @dp_scorecards_dashboard.json | python3 -m json.tool
The script assumes an engineering_intelligence folder already exists in your catalog. If you haven't created it yet, follow steps 1-4 in the create the dashboard section first.
Scorecard level distribution
Service delivery performance levels - pie chart (click to expand)
- Click
+ Widgetand select Pie Chart. - Title:
Service Delivery Performance Levels. - Description:
Distribution of delivery performance scorecard levels across services. - Choose Service as the Blueprint.
- Select
Delivery Performancefrom the Breakdown by property dropdown (this is thescorecard#delivery_performanceproperty). - Click Save.
Team delivery performance levels - pie chart (click to expand)
-
Click
+ Widgetand select Pie Chart. -
Title:
Team Delivery Performance Levels. -
Description:
Distribution of delivery performance scorecard levels across teams. -
Choose Team as the Blueprint.
-
Select
Delivery Performancefrom the Breakdown by property dropdown (this is thescorecard#team_delivery_performanceproperty). -
Add this JSON to the Additional filters editor:
{"combinator": "and","rules": [{"operator": "=","property": "type","value": "team"}]} -
Click Save.
Attention metrics
Services below Bronze - number chart (click to expand)
-
Click
+ Widgetand select Number Chart. -
Title:
Services Below Bronze. -
Description:
Number of services that have not reached Bronze level. -
Select
Count EntitiesChart type and choose Service as the Blueprint. -
Add this JSON to the Additional filters editor:
{"combinator": "and","rules": [{"operator": "=","property": "scorecard#delivery_performance","value": "Basic"}]} -
Click Save.
Scorecard tables
Service delivery scorecard overview - table (click to expand)
- Click
+ Widgetand select Table. - Title:
Service Delivery Scorecard Overview. - Description:
Services with their delivery performance scorecard level and key metrics. - Choose Service as the Blueprint.
- Group by Team.
- Configure the displayed columns to show: title, team, delivery performance level, PR cycle time, cycle time trend, merged PRs last month, throughput trend, open PRs, stale PRs (7d), and stale PR share.
- Click Save.
Team delivery scorecard overview - table (click to expand)
- Click
+ Widgetand select Table. - Title:
Team Delivery Scorecard Overview. - Description:
Teams with their delivery performance scorecard level and key metrics. - Choose Team as the Blueprint.
- Group by Parent Team.
- Add a filter for
type = teamto exclude groups and organizations. - Configure the displayed columns to show: title, delivery performance level, PR cycle time, cycle time trend, merged PRs per service, throughput trend, open PRs per service, stale PRs per service (7d), stale PR share, and services count.
- Click Save.
Group delivery scorecard overview - table (click to expand)
- Click
+ Widgetand select Table. - Title:
Group Delivery Scorecard Overview. - Description:
Business units with their delivery performance scorecard level and key metrics. - Choose Team as the Blueprint.
- Add a filter for
type = group. - Configure the displayed columns to show: title, delivery performance level, PR cycle time, cycle time trend, merged PRs per service, throughput trend, and stale PR share.
- Click Save.
Organization delivery scorecard overview - table (click to expand)
- Click
+ Widgetand select Table. - Title:
Organization Delivery Scorecard Overview. - Description:
Organization with its delivery performance scorecard level and key metrics. - Choose Organization as the Blueprint.
- Configure the displayed columns to show: title, delivery performance level, PR cycle time, cycle time trend, merged PRs per service, throughput trend, and stale PR share.
- Click Save.
Design decisions
Team-level normalization
Team-level scorecards use per-service normalized metrics for absolute count rules (open PRs/MRs, merged PRs/MRs, stale PRs/MRs). This ensures teams are evaluated fairly regardless of how many services they own. For example, a team with 5 services and 40 open PRs is evaluated as 8 open PRs per service, the same threshold as a single service with 8.
Rate metrics (stale PR/MR share), trend metrics (throughput, cycle time), and time-based metrics (PR/MR cycle time) are not normalized as they already scale naturally across any number of services.
Executive-level scorecards (Group and Organization)
Group and Organization scorecards use rate, trend, and per-service normalized throughput metrics only. Absolute count rules are omitted because groups and organizations span varying numbers of teams and services, making raw counts misleading.
Threshold sources
- DORA: Industry-standard DevOps Research and Assessment benchmarks for software delivery performance.
Next steps
- Add automations: Use Port automations to send Slack notifications when a service drops below Bronze, or create Jira tickets for teams with degrading trends.
- Customize thresholds: Adjust the numeric values in the scorecard rules to match your organization's delivery standards. For example, if your teams typically merge fewer PRs/MRs, lower the throughput thresholds.
Related guides
- Measure PR delivery metrics : Set up the underlying data model these scorecards depend on.
- Gain visibility into delivery performance : A broader delivery performance guide covering dashboards and AI agents.