Skip to main content
Bilanc reports all four DORA metrics for every account, plus the supporting stages that explain them. Some start as proxies, or as 0, until the tools that carry the real signal are connected. This page tells you exactly what is measured, how, and what to connect to improve it.

What Bilanc reports

Deployment Frequency

How often you ship to production. Counted from releases, deployment records or production deploy workflow runs, per repository.

Lead Time for Changes

Time from the first commit on a change to that change running in production.

Change Failure Rate

Share of production deployments that led to a failure: a failed deploy, an incident, or a revert or hotfix.

Time to Restore Service

How long production stayed degraded after a failed change, until it was restored.
Supporting stages, shown alongside the four:
  • Merge to Deploy – merge to running in production. The part of lead time that happens after the PR is done.
  • Merge Queue Time – entering a GitHub merge queue to merged.
  • Deployment Success Rate – share of production deploy runs that succeeded.
  • PRs per Deployment – how many pull requests each deployment carried.
Every account sees all four metrics from day one. Deployment Frequency and Lead Time are populated as soon as version control is connected. Change Failure Rate and Time to Restore are populated from reverts, hotfixes and failed deploy runs straight away, and become incident-based once Incident.io is connected. A metric showing 0 usually means the signal is not connected yet, not that nothing happened. See Getting accurate numbers.

How Bilanc detects a production deployment

Bilanc looks for production deployments per repository, using the first signal in this list that the repository emits:
1

Bitbucket Deployments

Bitbucket’s own deployment records, at the production environment.
2

Published releases

GitHub releases. Drafts and pre-releases are excluded. The published time is the deploy time. GitLab releases are not ingested yet (see Coming soon).
3

Production deploy workflow runs

CI/CD runs from GitHub Actions, CircleCI, GitLab CI or Azure DevOps whose workflow name says it deploys to production, for example Deploy to Production, Deploy Container to ECS (Prod) or Prod Continuous Deployment. Runs triggered by pull requests, merge queues or schedules never count, whatever they are called, and names that mention a lower environment (staging, dev, qa, preview, sandbox, test) are excluded. Failed runs are kept so Deployment Success Rate and Time to Restore can use them.
4

Merge to the default branch

If a repository emits none of the above, merging to its default branch counts as a deployment. This is the “trunk is production” proxy and is labelled merge_to_default.
If a repository emits more than one signal, Bilanc uses the one with the most deployments in the last 180 days, with ties broken in the order above. A signal only counts while it is alive: a repository whose last release was more than 180 days ago falls back to merge-to-default instead of waiting for a release that never comes, and a deploy workflow that has not succeeded once in 180 days is ignored (it is almost always a misnamed or abandoned job, and would otherwise read as 0% success and 100% failure). Every deployment carries a deployment_source label (bitbucket_deployment, github_release, workflow_run or merge_to_default) so you can always see which rule applied, and group or filter by it. You can override any of this per repository, see Rules.

How Bilanc reads your branching model

“Merge to the default branch” is only right for repositories that ship from trunk. Bilanc looks at a year of merged pull requests per repository and works out which branches are production and which are integration branches, then uses that everywhere below. The Repositories tab of the Rules page shows what was detected, with the evidence, and lets you override it. Each repository carries a confidence (high, medium, low). Anything below high is worth a glance in the Rules page; a production_branches rule fixes it permanently.

How a pull request gets a deploy time

A pull request merged into a production branch is assumed to ship with the next production deployment of its repository after it merged (itself, under merge-to-default). A pull request merged into an integration branch (dev, develop, release/1.2) ships when that branch is next promoted into production, and then with the promotion’s own deployment; if the repository has not promoted by pull request in the last 180 days, it ships with the next deployment instead. That is what Merge to Deploy and Lead Time for Changes measure. Pull requests merged before Bilanc can see any deployment for that repository are left without a deploy time rather than attributed to a later deployment, so a repository’s first tracked release does not inflate its lead time.

Pull requests without a deploy time

Every merged pull request carries a deployment_attribution_status in Data Explorer and Data Studio, and the DORA dashboard shows the share of merged pull requests with a deploy time. The reasons a PR has none:
Excluding a promotion PR (for example devmain) with a PR exclusion rule removes it from Bilanc entirely, so it can no longer serve as the deployment event for the pull requests it carried. Prefer leaving promotions in and filtering on is_promotion_pr in Data Explorer.

Metric definitions

Time metrics are returned in seconds. Rates are returned as a fraction between 0 and 1. The dashboard shows medians for the time metrics: lead time and time to restore are heavy-tailed (one change that waited a month for a release will double an average), and the DORA report’s own thresholds are stated as typical values.

How confident should I be in each number?

Each card on the DORA dashboard carries one of three labels, computed from your data, and the same logic applies to the API: What each connection unlocks:

Performance bands

The dashboard colours each of the four metrics with the band from the 2023 State of DevOps report. They are indicative: a repository on merge-to-default will look Elite on frequency by construction, so read the band together with the confidence label.

Change Failure Rate and Time to Restore: how the proxies work

DORA defines a failed change as a deployment that degrades service and needs remediation. Bilanc has no direct view of your production health, so it infers failures from the signals it does have. A deployment counts as a failed change when any of these is true:
  1. The deploy run itself failed. Only possible for the workflow_run source. failure_reason = failed_deployment.
  2. An incident opened within 48 hours and this was the most recent deployment before it (Incident.io connected). failure_reason = incident.
  3. A revert names a change it shipped. A GitHub-style Revert "…" pull request whose title names a pull request that shipped in this deployment, within 30 days. failure_reason = revert_pr.
  4. A revert, hotfix or rollback landed shortly after. Any other PR with revert, hotfix or rollback in its title or branch, merged to the same repository within 48 hours, attributed only to the single most recent deployment before it. failure_reason = revert_pr or hotfix_pr.
A deployment that is itself a revert or hotfix is a remediation. It is never counted as a failure and is left out of the Change Failure Rate denominator, because it is the fix rather than a change. Time to Restore runs from the moment the bad change was live to the moment production was restored: For reverts and hotfixes the deployments table also carries remediation_merged_at, so you can split Time to Restore into time-to-notice (deployed → fix merged) and time-to-ship-the-fix (fix merged → fix deployed) in Data Explorer. A revert that lands before the reverted change ever reached production is not counted as a failure.
Rules 3 and 4 are proxies. They will miss failures that were fixed forward without a revert or hotfix, and they can occasionally flag a routine revert that was not a production problem. Connecting Incident.io gives Bilanc the most faithful Change Failure Rate and Time to Restore, because real incidents replace inferred ones.

Getting accurate numbers

Work through this list in order. Each step improves the metrics above it.
1

Connect version control (required)

GitHub, GitLab, Bitbucket or Azure DevOps. This alone gives you Deployment Frequency and Lead Time via releases, or via the merge-to-default proxy. See Version Control.
2

Connect CI/CD

GitHub Actions comes with your GitHub connection. CircleCI is connected with a personal API token, see CircleCI. GitLab CI and Azure Pipelines come with their version control connections.
3

Publish releases, or name your production deploy workflows clearly

If you cut releases for production, keep publishing them and mark release candidates as pre-releases. If you deploy from CI, make sure the production workflow name contains prod or production and one of deploy, release, rollout or ship, and does not contain staging, dev, qa, test or preview. “Deploy to Production” is ideal. “CD” alone, or a name that also runs against staging, will not be picked up.
4

Check what Bilanc detected, accept its suggestions

Open the Rules page, Repositories tab. Repositories with medium or low confidence, and any pending suggestions (a production branch Bilanc could not confirm, a deploy workflow that does not say “prod”, a sandbox repository counted as production), are listed with the evidence. Accepting takes effect on the next hourly refresh. See Rules.
5

Connect Incident.io (beta)

Turns Change Failure Rate and Time to Restore from revert-based proxies into incident-based measurements. See Incident.io. The incident path is in beta while we finish validating it end to end with a customer.

If you deploy with a tool Bilanc cannot see yet

ArgoCD, Spinnaker, Flux, Harness, Octopus, Vercel, Netlify and similar tools promote to production inside themselves, and Bilanc only sees what reaches your version control system or CI. Until native integrations land (below), the fastest way to get measured numbers is to leave a trace where Bilanc looks:
Coming soon. Native deployment events from the GitHub Deployments API and GitHub Environments, GitLab Releases and Deployments, and incident sources beyond Incident.io: PagerDuty, Opsgenie and FireHydrant. We are also adding a custom deployment webhook for tools that do not leave a trace in your version control system, such as ArgoCD, Spinnaker or Vercel. Email sam@bilanc.co to be first in line, and tell us which deployment tool you use so we prioritise it.

Where to see them

  • DORA Metrics dashboard in the Bilanc app. The strip at the top shows the mix of deployment sources, the share of merged pull requests with a deploy time and whether incidents are connected; each card carries its Measured / Partial / Proxy label and performance band; the Repositories, Teams and Sources tabs break every metric down; the deployments explorer lists each deployment with the pull requests it carried and why it counted as a failure.
  • Rules page (Admin tools → Rules), Repositories tab: what Bilanc detected per repository, with confidence and evidence, and the rules and suggestions that change it.
  • Data Explorer and Data Studio, on the pull_requests table (deployed_at, deployment_source, deployment_attribution_status, branching_model, is_production_merge, is_promotion_pr, merge_to_deploy, lead_time_for_changes, open_to_deploy, queue_time) and the deployments table (one row per deployment, with status, workflow_name, is_failed_change, failure_reason, failure_detected_at, remediation_merged_at, restored_at and the pull requests it carried).
  • Metrics API, see Deployment & DORA Metrics.

FAQ

Because lead time includes waiting. A pipeline that takes an hour to build, test and deploy is often a small part of the total: a change merged in the afternoon waits for tomorrow’s release train, a weekly release, or the next time someone runs the deploy. Merge to Deploy shows you that wait on its own. If it dominates, deploying more often moves lead time far more than speeding up CI does.
Bilanc found no live releases, deployment records or production-named deploy workflows for that repository (nothing in the last 180 days), so merging into its production branch is being treated as the deployment. For repositories that genuinely deploy on merge this is accurate. Otherwise, publish releases or rename the production deploy workflow as described above and the repository will switch automatically, or add a deploy_workflow_include rule naming the workflow.
Its last release is more than 180 days old, so Bilanc stopped waiting for the next one. Pull requests merged since are counted as deployed on merge instead of sitting without a deploy time forever. If releases resume, the repository switches back on the next refresh. To pin a repository to one signal regardless, add a deployment_source rule.
Lead time and time to restore are heavy-tailed. A handful of changes that waited weeks for a release train (or one revert matched to a month-old deployment) pull the average far above what most changes experience. The dashboard shows medians (-p50 metrics) for that reason; the API offers both. When they disagree a lot, look at the distribution by repository in the Repositories tab.
Open Rules → Repositories, find the repository and press Override, or accept the suggestion if one is waiting. A production_branches rule replaces the inference for that repository from the next refresh. Common cases: gitflow repositories that promote develop into main outside pull requests, repositories whose production branch is release, k8s-main or staging, and infrastructure repositories that should be ignored (deployment_source = ignore).
No failed deploy runs, incidents, reverts or hotfixes were found for the period. That can be true, but check two things first: production deploy workflows are being detected (a repository on merge_to_default never has a failed deploy run), and Incident.io is connected if you run incidents there. Time to Restore also stays empty until a failed change has actually been restored.
Today, yes if the promotion leaves a trace in version control: a published release, a production deploy workflow, or a merge to a deployment branch. Bilanc cannot yet see a promotion that happens only inside those tools. Native deployment events and a custom webhook are on the way, so tell us which tool you use.
Use the -p50 metrics (lead-time-for-changes-p50, merge-to-deploy-p50, time-to-restore-p50) for a headline figure; they take no aggregation parameter. The base metrics accept AVG, MIN, MAX and SUM when you need them.