Skip to content

Metric glossary

Org adminManagerDeveloperViewer

These definitions are generated from the same document the dashboards are implemented and tested against, so they cannot drift from what you see in the product.

Throughput
volume of output: commits, prs_opened, prs_merged and reviews_given per day. A commit is attributed to its committed_at day, an opened PR to its created_at day, a merged PR to its merged_at day, a review to its submitted_at day — always the day of the event itself, and always the tenant's local days.
Cycle time
for a merged pull request, merged_at − created_at (seconds), floored at zero. It is attributed to the merge day and belongs to the PR's author. A window's average is Σ cycle_time_seconds_total / Σ cycle_time_count — the counts travel with the sums, so multi-day windows weight correctly.
Review latency
for a pull request, the time from created_at to its first review by a non-bot reviewer (min(submitted_at) − created_at, floored at zero). It is attributed to the day that first review arrived and belongs to the PR's author: it measures how long the author waited for review. Reviews given by bots never start the clock; a PR with no human review contributes no latency. A window's average is Σ review_latency_seconds_total / Σ review_latency_count.
PR size
additions + deletions of a merged pull request. Attributed to the merge day and to the author. A window's average is (Σ merged_additions + Σ merged_deletions) / Σ prs_merged.
Cycle-time percentiles
p10, median and p90 of the cycle time of the PRs merged in the window, so outliers don't hide behind an average. They are estimated from a histogram of fixed, log-scaled buckets (15 minutes doubling to 2,048 hours), so each value is accurate to its bucket: the estimate shown is the middle of the bucket the percentile falls in. Same PRs as cycle time — merged, by a non-bot author, on the merge day.
PR stages
a merged pull request's lead time split into the stages it went through: first commit → open, open → first review, first review → merge and merge → deploy. All four describe the PRs merged that day: each is attributed to the PR's merge day and belongs to the PR's author, exactly like cycle time, so a window's stage chart breaks down the same PRs its cycle time averages. Bot-authored PRs and PRs without an author are left out, as everywhere. Each duration is in whole seconds, floored at zero, and a window's average is Σ stage_…_seconds_total / Σ stage_…_count. A stage counts only the PRs it was measured for, so the stage averages need not add up to the average cycle time. Merge → deploy counts only the PRs linked to a production deploy, and until the workspace has a counted production deploy it reads "not tracked", never zero.
Lead time
for a merged pull request, merged_at − first_commit_at (seconds): from when work on it began, the earliest authored time among its own commits (as in the first commit → open stage), to its merge. When no commit is linked, or the PR was opened before its first commit, it runs from created_at instead — the earlier of the two — so a PR's lead time is never shorter than its cycle time. Floored at zero and attributed to the merge day, like cycle time. It is not rolled up: the PR Workflow report's long-lead-time PRs table reads it per pull request and lists the PRs merged in the window whose lead time is over the target, longest first, with each PR's stages and cycle time beside it.
Deploy frequency
successful production deploys, counted on the local day each finished and shown per week (Monday to Sunday). For the organisation every counted deploy counts once; for a team or group, a deploy counts once when it shipped at least one merged pull request authored by a member — however many members it shipped — so a team's count is not the sum of its people's. A person has no deploy count: a deploy names no one. Until the workspace has a counted production deploy — the GitHub App's Deployments and Actions permissions approved and the production setting matching an environment or workflow — deploy charts read "not connected" rather than zero.
Time to restore
how long production stayed broken after a failed deploy: from a failed production deploy finishing to the next successful production deploy of the same repository finishing in the same environment (for a workflow run, the same workflow). Consecutive failures before that success are one restore, timed from the first of them; cancelled deploys neither fail nor restore, and a failure not yet restored is not counted until it is. A restore is attributed to the day the restoring deploy finished, and a window's mean time to restore is Σ restore_seconds_total / Σ restores. For a repository an incident service is mapped to (an incident-mode repository), each mapped incident resolved is a restore instead, from the incident opening to its resolution, attributed to the day it was resolved; that repository's deploy-based restores are not counted.
Lead time for changes
for a merged pull request linked to a production deploy, the linked deploy's finished_at minus the PR's first commit — the earlier of first_commit_at and created_at, as in lead time — in whole seconds, floored at zero. Like the PR stages it is attributed to the PR's merge day and belongs to its author, bot-authored and AI agent PRs left out, and a window's average is Σ lead_time_for_changes_seconds_total / Σ lead_time_for_changes_count. A PR not deployed yet adds nothing until its deploy lands; until the workspace has a counted production deploy it reads "not connected" rather than zero.
Change failure rate
the share of finished production deploys that were change failures, Σ change_failures / Σ finished_production_deploys over the window. A finished production deploy is one whose status is success or failure, attributed to the local day it finished; cancelled and unfinished deploys count nowhere. A change failure is a failed one, or a successful one followed by a fix pull request — opened in the same repository on the deploy's branch within the tenant's window after the deploy finished, not closed unmerged — when it is the latest successful production deploy of that repository and branch before the fix opened. A fix pull request's title starts with one of the tenant's prefixes or it carries one of the tenant's labels, case-insensitively. Defaults: a 72-hour window, the prefixes Revert, hotfix and [hotfix], the labels revert and hotfix. A team or group counts the deploys that shipped or attempted a member's merged pull request; with no team or group selected the rate is over every repository. For an incident-mode repository, a successful deploy is a change failure instead when an incident on a mapped service opened within the tenant's window after it finished and it is the latest successful production deploy of that repository before the incident opened; the fix pull request rule does not apply there.
AI-authored commit
a commit whose author or co-author is a known AI tool (Claude Code, Codex, GitHub Copilot, Cursor, Devin or another listed agent): the author's GitHub login or git email matches the AI signature catalogue, or a Co-authored-by: trailer of its message does. A commit an AI agent authored itself is counted for the tool, never as a person's commit; a person's commit with an AI co-author stays theirs and also counts for the tool. Commits made with AI help but no trailer, or under a person's own identity, cannot be seen.
AI-assisted PR
a merged PR made with an AI tool: one of its commits is AI-authored (see AI-authored commit; for a squash merge, the squash commit carries the branch's trailers), an AI bot opened it, or its description carries an agent marker such as "Generated with Claude Code". A PR an AI agent opened itself counts as AI-assisted for the agent, never as a person's PR. PRs made with AI help that left none of these traces cannot be seen.
Review depth
how closely a merged PR was reviewed before it merged, compared between AI-assisted and human PRs so a rubber-stamped AI PR shows up. Like the PR stages it describes the PRs merged that day, on the PR's merge day and its author's row, in the three classes of AI-assisted PRs: people's PRs (the merged_* columns, the PRs prs_merged counts, AI-assisted ones included), the AI-assisted PRs (ai_*, AI agents' included) and the AI agents' own (ai_agent_*). Only human (non-bot) reviewers count, and only what they did at or before the merge.
Reverted PR
a merged PR undone afterwards in its own repository by a revert commit or a revert PR.
Bug-linked PR
a merged PR that a bug ticket reported after it merged is linked to.
Incident-linked PR
a merged PR that shipped in an incident's linked deploy.
Cross-team hand-off
review latency split by who gave the PR's first human review: the same PRs, the same wait (first review − created_at, floored at zero), the same day (the first review's) and the same row (the author's). Bots never start the clock, and when two people submit the first review in the same second the wait counts as in-team if either of them is.
Review load
how much reviewing a team or group did over a window and how long its authors waited, as a team: Σ reviews_given (the reviews its members submitted), Σ reviews_given / Σ prs_opened (reviews per pull request opened) and the window's average review latency. It is read from the team's or group's own rollup rows only and is never broken down per person — DevGlimpse ranks no individuals.
Satisfaction
the developer-experience pulse, as a team: a closed monthly pulse's average answer on its 1–5 agreement scale, the mean of its questions' averages (each rounded to 0.1 in the view), from the respondents who belonged to the team or group when they answered. A team or group appears only once the pulse has closed and only with at least the pulse's minimum response count (never fewer than 5). It is hidden when its respondents differ from another team's or group's in the same pulse by fewer than that minimum, or when it has exactly the minimum and everyone gave one question the same answer; a hidden team or group gets no row from Hasura, for every role. Answers are never shown one by one or per person.
Benchmark weekly values
each benchmarked metric for the organisation, a provider team or a custom group over the previous Monday–Sunday week in the tenant's timezone, beside the week before it and the change between the two (the previous week's value minus the week before's). Git metrics come from the subject's contributor rollup rows of those days, by the definitions above: cycle time, the three PR stages (coding time is first commit → open, pickup time open → first review, review time first review → merge) and PR size are the week's averages, in hours or lines, and merge frequency is the week's merged PRs per active contributor — a contributor with a commit, an opened or merged PR, or a review that week. A week with nothing to measure has no value. A metric whose source isn't connected — deploy metrics until deploys are tracked, git metrics without a connected GitHub integration — reads not connected, never zero. Each metric is compared against the tenant's own target when an org_admin has set one, otherwise against its default from published research, cited beside it.
Benchmark history
each benchmarked metric week by week against the target that was in force that week, for the organisation, a provider team or a custom group. The nightly cron copies the view's closed week into benchmark_weekly_history, one row per week, subject and metric with the comparator, target and target_scope in force then, so history survives later target changes and a chart's target line steps when the target did. A week persists once (ON CONFLICT DO NOTHING): a repeated night or a late rollup change rewrites nothing. Only measured values are stored, never a zero: a week with nothing to measure, or a metric whose source isn't connected, has no point that week. contributor_count is the subject's counted members then; the Benchmark History dashboard reads a team or group row only when it reaches the tenant's current minimum group size, as the weekly values do, and every role reads the same tenant-scoped rows.
AI adoption
how many people used an AI tool over a window, from the daily telemetry aggregates (kubeace/devscout issue 102): the active AI users per UTC week (Monday to Sunday) and tool, and per provider team the distinct members with any telemetry in the week. A team's figure counts only the members whose usage the caller may see (the visibility scope), and a team under the tenant's minimum group size, or withheld for differencing, is not shown.
AI spend
the tokens and the reported cost of AI tool usage over a window, from the daily telemetry aggregates: input, output, cache-read and cache-creation tokens and the cost in US dollars, by tool, model and team (a team's figure is the sum of its visible members' rows, withheld like AI adoption). A tool that reports no cost shows tokens and no cost, never a zero.
AI sessions
how long AI coding sessions run and how much they do, from the raw log events (kubeace/devscout issue 104): a session is a session id (Codex: a conversation id) whose first log event falls in the window; its length is its last log event minus its first, inside the window, and its tool calls are its Claude Code and Codex tool_result events and Gemini CLI tool_call events. The mean session length and the tool calls per session are the sums over the sessions the caller may see divided by their count, per UTC week of the session's first event; a team's figure is that of its visible members' sessions, withheld like AI adoption, and a week with no session has none, never a zero. A developer's own AI usage view shows only their own sessions.
Pipeline duration
for a finished run, completed_at − started_at: the time the pipeline took once it began, per attempt, so a re-run is timed on its own. Each UTC day's figures are the mean and the median over its finished runs; the window's mean weights each day by its runs, never an average of daily means. Runs that report no start time count nowhere.
Queue time
for a first attempt, started_at − created_at: how long a run waited for a runner before it began. A re-run attempt has no queue time, because its creation time is the first attempt's. Each UTC day's figures are the mean and the 90th percentile over its finished first attempts; the window's mean weights each day by its runs.
CI failure rate
the share of finished runs that failed, failed runs / (failed runs + succeeded runs), over the window and per UTC week from each week's own counts. Cancelled, skipped and unfinished runs count nowhere, and a week with neither a failed nor a succeeded run has no rate.
Flaky tests
the jobs that both failed and succeeded on the same commit: a job (its workflow, its name and its repository) is flaky for a head sha when finished jobs on that sha include a failed and a succeeded one, whether from a re-run or from separate runs. A job's flaky count is its number of such shas in the window, shown beside the shas it ran on. GitHub's Actions API exposes no test results, so the unit is the CI job, not an individual test case.
CI minutes
the sum of the finished jobs' durations (completed_at − started_at), in minutes: the runner time CI consumed, so jobs that ran in parallel each count. A team's CI minutes are the minutes of the jobs triggered by the members of the team the viewer may see, so a person in several teams counts for each of them and the teams can add up to more than the workspace's total. A team with fewer counted members than the workspace's minimum group size is withheld, as in the team lists.
Time to resolve
for a completed bug, completed_at − created_at (seconds), floored at zero, on the completed day. A window's average is Σ bug_resolution_seconds_total / Σ bug_resolution_count.
Ticket cycle time
for a completed ticket with a start time, completed_at − started_at (seconds), floored at zero, on the completed day; a ticket completed without ever being started has none (ticket_cycle_time_count ≤ tickets_completed). A window's average is Σ ticket_cycle_time_seconds_total / Σ ticket_cycle_time_count. Its histogram uses the cycle-time buckets' fixed edges (Cycle-time percentiles, cycle_time_bucket()), so a refreshed row's buckets add up to its ticket_cycle_time_count and the median is estimated from a window's summed buckets by the same estimator.
Fix vs. find rate
bugs resolved against bugs created over a window, Σ bugs_resolved / Σ bugs_created (Ticket rollups). Above 1 the open bugs shrink, below 1 they pile up; a window without a bug created has none. The two counts are independent: a bug resolved in the window may have been created before it.
Bug workload
the share of completed tickets that were bugs over a window, Σ bugs_resolved / Σ tickets_completed (a completed bug counts in both). The rollups count tickets, not their size, so the share is by ticket; a window without a completed ticket has none.
Rework rate
bugs created against tickets completed over a window, Σ bugs_created / Σ tickets_completed (Ticket rollups). It sets the new bugs that work produced beside the work finished; the two counts are independent, so a bug created in the window may come from work completed before it and the rate can pass 100%. A window without a completed ticket has none. The Bug Creation report shows it next to the change failure rate: that one is read from deploys, this one from tickets.
Sprint completion
points done against points committed over the cycles that ended in a window, Σ points_done / Σ committed_points (Cycle rollups), over the cycles with a committed snapshot. Above 1 the team finished more than it committed (scope added after the start counts as done); a window without a committed point has none.
Rollover ratio
the share of the previous cycle's scope left unfinished when it ended, Σ rollover_points / Σ (committed_points + scope_added_points − scope_removed_points of the previous cycle) over the cycles with a known rollover (Cycle rollups); a cycle with no previous cycle, or one whose previous cycle has no committed snapshot, has none.
Scope creep
the net scope that moved after a cycle started, as a share of what it committed, Σ (scope_added_points − scope_removed_points) / Σ committed_points (Cycle rollups). Positive means scope grew, negative that it shrank; a cycle without committed points has none.
Initiative progress
an initiative's completed tickets against its tickets that are not cancelled, tickets_completed / tickets_total (Initiative rollups), and by points, points_completed / points_total; an initiative without a ticket has none. An initiative holds the tickets of its projects, and a project in several initiatives counts in each. Beside it, its effort: the distinct pull requests linked to those tickets, and the lines the merged ones changed.
Forecast finish
the date an initiative finishes if its last 28 days' completion rate continues, as_of + ⌈remaining × 28 / recent_completed⌉ days, where remaining = tickets_total − tickets_completed and recent_completed counts the tickets completed in the 28 days ending as_of. It is none when nothing remains, or when nothing was completed in the window.