Available since 1.16.2 (EE)

The “DORA metrics” report measures the delivery of a group or a project over the selected period: how often successful deployments to production environments happen, how long a merged change waits for its deployment, how long incidents stay open and how many incidents come per deployment. The report of a group covers the projects of the group and its subgroups.

Report availability

The report of a project is available to members with the “Reporter” role and above, including those who hold that role in a parent group, and to administrators. Members with the “Guest” role do not see the “DORA metrics” item in the project menu, and the direct address answers with 404. The visibility level of the project does not extend this access: in a public or an internal project, a user who is not a member does not see the report. A visitor who has not signed in gets 404 in a public project or group and the sign-in page in a private or an internal one. A personal project, one in the namespace of a user, has the report too. Turning the “Analytics” feature of the project off closes the report for everyone, the administrator and the “Owner” role included: the menu item disappears, the direct address answers with 404, and the REST API answers with 403. The report of a parent group keeps counting such a project.

The report of a group is available to members with the “Reporter” role and above, including those who hold that role in a parent group, to administrators and to users of the “Auditor” type. Members with the “Guest” role do not see the item in the group menu, and the direct address answers with 404. For the report of a project, a user of the “Auditor” type needs the “Reporter” role and above in the project or in its parent group; without it the page answers with 404 and the REST API with 403.

Viewing the report

To view the report of a group:

  1. In the top bar, select “Search or go to…” and pick the group.
  2. In the group menu, go to “Analyze” → “DORA metrics”.

To view the report of a project:

  1. In the top bar, select “Search or go to…” and pick the project.
  2. In the project menu, go to “Analyze” → “DORA metrics”.

The report is also available at a direct address:

ReportAddress
Grouphttps://<HOST>/groups/<GROUP>/-/analytics/dashboards/dora_metrics
Projecthttps://<HOST>/<GROUP>/<PROJECT>/-/analytics/dashboards/dora_metrics

The page holds the period list, a row of cards with the value of each metric over the period and a chart per metric with the values by day.

Metrics

MetricCard subtitleValue
“Deployment frequency”“Successful deployments per day.”Number of successful deployments finished within the period, divided by the number of days of the period
“Lead time for changes”“Median time from merge to deployment.”Median of the daily medians of the time from the merge of a merge request to the end of the successful deployment that brought it to the environment
“Time to restore service”“Median time incidents remain open.”Median of the daily medians of the time from the creation of an incident to its closing, over the incidents closed within the period
“Change failure rate”“Incidents divided by deployments.”Number of incidents created within the period, divided by the number of successful deployments finished within it

The report counts the deployments to production environments, the environments of the production deployment tier. A deployment is linked to the merge requests whose commits it brought to the environment since the previous successful deployment of the same environment; the first deployment of an environment is linked to every merge request merged into the deployed branch. A merge request whose merge is recorded after the deployment finished is left out of the lead time.

Incidents are issues of the “Incident” type. An incident belongs to the project as a whole and is counted as an incident of a production environment, so “Time to restore service” and “Change failure rate” have values only in a project with a production environment. An incident marked as a duplicate of another issue is left out of both metrics; an incident that is reopened stops counting as closed.

The values are kept per environment and per day; a day starts and ends by the time zone configured for the instance, UTC by default. With another time zone, a day of the report follows that zone, while the period selects the days by their date: with UTC+3, a deployment finished at 23:30 UTC on 10 March is counted on 11 March.

A day is counted again from scratch when an event of that day occurs: 5 minutes after a deployment succeeds and once more if linking the merge requests it brought finishes later than that, and at once when an incident is created, closed, reopened, deleted, marked as a duplicate or changes its type to or from “Incident”. An incident usually appears within seconds; when a recount of a deployment of the same day to the oldest production environment, the one that holds the incidents of the project, is already pending, the incident appears with that recount, up to 5 minutes later. Over the period, the deployments and the incidents of its days are summed, and the lead time and the time to restore are the medians of the daily medians. A period without a successful deployment has no “Change failure rate”.

The values are written at the moment of the event. Deployments and incidents that happened before the update that brought the report get their values once an administrator loads the history, as described in Loading history; the same applies to the incidents created before the project had a production environment, and to the days counted before the branch list of Branches counted in lead time was changed.

Metric cards

The row above the charts holds a card per metric with its name, its subtitle and its value over the whole period:

  • “Deployment frequency” — deployments per day;
  • “Lead time for changes” and “Time to restore service” — days;
  • “Change failure rate” — a percentage.

A metric without a value in the period shows a dash. A value above zero and below 0.01 reads as < 0.01 in the unit of the card. When the values cannot be loaded, the card shows “Failed to load DORA metrics.”

Charts

Under the cards, a chart per metric carries the name and the subtitle of its card: a line with one point per day of the period, the vertical axis in the unit of the card, with numbers in the format of the interface language, and the horizontal axis “Date”. A dashed line across the chart carries the value of the card over the whole period; it is named “Median” on “Lead time for changes” and “Time to restore service” and “Average” on “Deployment frequency” and “Change failure rate”. Pointing at a point shows the date and the value. A day on which the metric has no value carries no point.

A chart with no value on any day of the period shows “No data available” and “Create production deployments and incidents to populate this chart.” When the values by day cannot be loaded, each chart shows “Failed to load DORA metrics.” When the values over the period cannot be loaded, the cards show “Failed to load DORA metrics.”, the charts are drawn without the dashed line, and a chart with values reads “Failed to load the average for this period.” or “Failed to load the median for this period.” under it.

Period

The list in the top right corner of the page sets the period: “Last 7 days”, “Last 30 days”, “Last 90 days”, “Last 180 days” or “Custom range”, which opens the “From” and “To” date pickers. The report opens on “Last 180 days”. The dates of the period are calendar days in UTC, and a preset period ends with the current day in UTC and starts the given number of days earlier: “Last 7 days” covers 8 days, and its deployment frequency divides by 8.

A custom period is applied once both dates are picked; it ends with the current day or earlier and spans up to 181 days counting both the first and the last, as “Last 180 days” does. A custom period of one day can be any day, the current one included. When a new “From” date is not earlier than the “To” date already picked or makes the period longer than 181 days, the “To” date is cleared and its calendar opens; the period is applied once an end date is picked. The icon next to the pickers reads “Dates and times are displayed in the UTC timezone. Date range is limited to 181 days.”

When no metric has a value on any day of the period, the page shows “No DORA metrics available” and “Create production deployments and incidents to populate this dashboard.” in place of the cards and the charts.

Branches counted in lead time

By default, the lead time of a deployment counts every merge request linked to it. In a project that promotes changes through several branches — a merge request into staging, then a merge request from staging into main, and a deployment of main — both merge requests are linked to the deployment, and the same change is counted twice. The DORA configuration of the project names the target branches whose merge requests are counted: with main alone, the merges into staging stay out of the lead time.

The list applies to production environments; an environment of another tier keeps every linked merge request. The branch or the tag the deployment was made from is not compared with the list, so a project that deploys tags keeps its lead time. The list cannot be empty and cannot contain empty or repeated names; a project holds one configuration.

The lead time is measured from the merge into a listed branch: with main alone, from the merge into main to the deployment, and the time the change spent in staging is not counted. A list of every branch of the flow, such as development, staging and main, brings the intermediate merges back into the lead time.

The configuration is set from the Rails console. Open the console for the installation type:

  • Linux package
  • Omnibus Docker
  • Helm Chart
  • Deckhouse Platform module
sudo gitlab-rails console
docker exec -it code gitlab-rails console
d8 k -n code exec -it deploy/code-toolbox -- gitlab-rails console -e production
d8 k -n d8-code exec -it -c toolbox deploy/toolbox -- gitlab-rails console -e production

Then create the configuration, naming the project by its full path and the branches by name:

project = Project.find_by_full_path('<GROUP>/<PROJECT>')
Dora::Configuration.create!(project: project, branches_for_lead_time_for_changes: %w[main])

To change the list of an existing configuration:

Dora::Configuration.find_by!(project: project).update!(branches_for_lead_time_for_changes: %w[main release])

To return to counting every linked merge request, delete the configuration with Dora::Configuration.find_by!(project: project).destroy!.

The days counted before the configuration was created or changed keep their lead time. To recount them, load the history of the affected period as described in Loading history.

REST API

The values of the report are available through the REST API, one metric per request:

GET /api/v4/projects/:id/dora/metrics
GET /api/v4/groups/:id/dora/metrics

:id is the ID or the URL-encoded full path of the project or the group. The request is authenticated with an access token with the api or read_api scope, or with a fine-grained personal access token with the read_dora_metric permission; the user of the token needs the same access as for the page.

Parameters:

ParameterDescription
metricRequired. The metric: deployment_frequency, lead_time_for_changes, time_to_restore_service or change_failure_rate
start_dateFirst day of the period, in the YYYY-MM-DD form. Three months before the current day by default. With an end_date earlier than that and no start_date, the request answers 400, so pass both
end_dateLast day of the period, in the YYYY-MM-DD form. The current day by default. It may be equal to start_date, then the period is one day
intervalBucket of the values: daily (default), monthly or all
environment_tiersDeployment tiers of the environments to read, as an array: production, staging, testing, development, other. production by default. time_to_restore_service and change_failure_rate are counted on production only: without production in the list they are null, and other tiers do not change the deployments the rate divides by

The response is an array of objects with date and value. With daily and monthly, the array holds an object per day or per month of the period, date being the day or the first day of the month and value being null for a day or a month without recorded data; a recorded day without deployments, for example a day with incidents only, gives 0 for the deployment frequency; with all, one object with date set to null. Deployment frequency is given in deployments per day, lead time and time to restore in seconds, change failure rate as the number of incidents per production deployment, which can exceed 1.

For a month cut by the period, the deployment frequency divides by the days of the month inside the period. An end_date later than the current day is accepted as is, and the future days of the period count in the divisor: with interval=monthly, for a request made on the first day of a month with end_date on the 10th of that month, one deployment on that first day gives 0.1 for the month.

Response codes:

  • 200 — the values;
  • 400 — start_date later than end_date, end_date more than 180 days after start_date, an empty environment_tiers, a missing metric, a start_date or end_date that is not a date, or a value outside the lists above;
  • 401 — no token, a public project or group included;
  • 403 — the user of the token has no access to the report: a member with the “Guest” role, a user who is not a member of a public or an internal project or group, or a project with the “Analytics” feature off;
  • 404 — the project or the group is not found or is private and the user of the token is not its member, or the report is unavailable in the edition of the instance, as in Standard Edition.

Example:

curl --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<GROUP>%2F<PROJECT>/dora/metrics?metric=deployment_frequency&start_date=2026-03-09&end_date=2026-03-11"

Response for a project with 2 successful deployments to a production environment on 2026-03-10:

[
  { "date": "2026-03-09", "value": null },
  { "date": "2026-03-10", "value": 2.0 },
  { "date": "2026-03-11", "value": null }
]

Loading history

The values are written at the moment of a deployment or an incident. To count the deployments and incidents that happened before the update that brought the report, or the incidents created before the project had a production environment, or to recount the days after a change of the branch list, an administrator runs the gitlab:dora:backfill task with the full path of the project and the first and the last day of the period in the YYYY-MM-DD form:

  • Linux package
  • Omnibus Docker
  • Helm Chart
  • Deckhouse Platform module
sudo gitlab-rake 'gitlab:dora:backfill[<GROUP>/<PROJECT>,<START_DATE>,<END_DATE>]'
docker exec code gitlab-rake 'gitlab:dora:backfill[<GROUP>/<PROJECT>,<START_DATE>,<END_DATE>]'
d8 k -n code exec deploy/code-toolbox -- gitlab-rake 'gitlab:dora:backfill[<GROUP>/<PROJECT>,<START_DATE>,<END_DATE>]'
d8 k -n d8-code exec -it -c toolbox deploy/toolbox -- gitlab-rake 'gitlab:dora:backfill[<GROUP>/<PROJECT>,<START_DATE>,<END_DATE>]'

The task takes one project; for the report of a group, run it for each project of the group. It queues a recount of every day of the period on which a successful deployment finished, in the environment of that deployment, of every day on which an incident was created or closed, and of every day already recorded in the period, so that a day whose events are gone is recounted to zero. In a project without a production environment, the incident days are not queued. The task prints Enqueued N DORA day recounts., or Enqueued 1 DORA day recount. for one day, and returns; the recounts run in the background through Sidekiq, and the report fills in as they complete. A day is recounted from scratch, so a repeated run over the same period gives the same values.

The task stops with an error when an argument is missing (project, start_date and end_date are required), when the project is not found (Project not found: <PATH>), when a date is not a valid ISO 8601 date (start_date must be a date in the YYYY-MM-DD format: <VALUE>, with end_date for the last day) or when the first day is later than the last (start_date must not be after end_date).