{"id":49521,"date":"2025-05-28T02:36:32","date_gmt":"2025-05-28T02:36:32","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=49521"},"modified":"2025-05-28T02:38:17","modified_gmt":"2025-05-28T02:38:17","slug":"gitlab-guide-to-generating-dora-metrics-in-gitlab","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/gitlab-guide-to-generating-dora-metrics-in-gitlab\/","title":{"rendered":"Gitlab &#8211; Guide to Generating DORA Metrics in GitLab"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\"><\/h1>\n\n\n\n<p>GitLab 18.x Ultimate provides <strong>native support for all four DORA metrics<\/strong> via its <strong>REST API<\/strong>, giving engineering teams deep insights into the performance and reliability of their software delivery processes.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u2705 Prerequisites<\/h2>\n\n\n\n<p>Before you begin, ensure:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Requirement<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td>GitLab Tier<\/td><td>GitLab Ultimate (SaaS or Self-Managed)<\/td><\/tr><tr><td>User Role<\/td><td>At least Reporter on the target project\/group<\/td><\/tr><tr><td>API Access<\/td><td>A personal access token with <code>read_api<\/code> scope<\/td><\/tr><tr><td>Environments<\/td><td>Deployments to <code>production<\/code> tier are configured<\/td><\/tr><tr><td>Incidents (for MTTR\/CFR)<\/td><td>Use GitLab\u2019s built-in incident management<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83e\udded Overview of Supported DORA Metrics<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Metric<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td>Deployment Frequency<\/td><td>How often code is deployed to production<\/td><\/tr><tr><td>Lead Time for Changes<\/td><td>Time between MR merge and deployment<\/td><\/tr><tr><td>Change Failure Rate<\/td><td>Ratio of failed deployments (with incidents) to total deployments<\/td><\/tr><tr><td>Time to Restore Service<\/td><td>Time from incident creation to resolution<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd27 Step 1: Setup Deployments and Environments<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Define production environments in your CI\/CD pipeline:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">deploy_prod:\n  stage: deploy\n  script:\n    - .\/deploy.sh\n  environment:\n    name: production\n    tier: production\n<\/code><\/span><\/pre>\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>Ensure your production deployments are successfully tracked under:<br><strong>Project \u2192 Operations \u2192 Environments<\/strong><\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udee0 Step 2: Use GitLab\u2019s Incidents (For CFR + MTTR)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Go to: <strong>Project \u2192 Monitor \u2192 Incidents<\/strong><\/li>\n\n\n\n<li>Create incidents manually or via <code>\/incident<\/code> in issues<\/li>\n\n\n\n<li>Ensure incidents are associated with the correct environment (<code>production<\/code>)<\/li>\n\n\n\n<li>Close incidents when resolved<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83e\uddea Step 3: Generate DORA Metrics Using REST API<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd38 Project-Level DORA Metrics<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">GET \/projects\/:id\/dora\/metrics\n<\/code><\/span><\/pre>\n\n\n<p><strong>Example Request:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl --header <span class=\"hljs-string\">\"PRIVATE-TOKEN: &lt;your_access_token&gt;\"<\/span> \\\n  <span class=\"hljs-string\">\"https:\/\/gitlab.com\/api\/v4\/projects\/123456\/dora\/metrics?metric=deployment_frequency&amp;start_date=2024-01-01&amp;end_date=2024-04-01\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd38 Group-Level DORA Metrics<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">GET \/groups\/:id\/dora\/metrics\n<\/code><\/span><\/pre>\n\n\n<p><strong>Example Request:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl --header <span class=\"hljs-string\">\"PRIVATE-TOKEN: &lt;your_access_token&gt;\"<\/span> \\\n  <span class=\"hljs-string\">\"https:\/\/gitlab.com\/api\/v4\/groups\/5678\/dora\/metrics?metric=lead_time_for_changes&amp;interval=daily\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udccc Supported API Parameters<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Parameter<\/th><th>Description<\/th><th>Default<\/th><\/tr><\/thead><tbody><tr><td><code>metric<\/code><\/td><td>Required. One of: <code>deployment_frequency<\/code>, <code>lead_time_for_changes<\/code>, <code>change_failure_rate<\/code>, <code>time_to_restore_service<\/code><\/td><td>\u2014<\/td><\/tr><tr><td><code>start_date<\/code><\/td><td>ISO 8601 start date<\/td><td>3 months ago<\/td><\/tr><tr><td><code>end_date<\/code><\/td><td>ISO 8601 end date<\/td><td>Today<\/td><\/tr><tr><td><code>interval<\/code><\/td><td><code>daily<\/code>, <code>monthly<\/code>, <code>all<\/code><\/td><td><code>daily<\/code><\/td><\/tr><tr><td><code>environment_tiers<\/code><\/td><td><code>production<\/code>, <code>staging<\/code>, etc.<\/td><td><code>production<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udce5 Example Responses<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json\">&#91;\n  { <span class=\"hljs-attr\">\"date\"<\/span>: <span class=\"hljs-string\">\"2024-04-01\"<\/span>, <span class=\"hljs-attr\">\"value\"<\/span>: <span class=\"hljs-number\">4<\/span> },\n  { <span class=\"hljs-attr\">\"date\"<\/span>: <span class=\"hljs-string\">\"2024-04-02\"<\/span>, <span class=\"hljs-attr\">\"value\"<\/span>: <span class=\"hljs-number\">2<\/span> }\n]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li><code>value<\/code> meaning depends on the metric:\n<ul class=\"wp-block-list\">\n<li><strong>Deployment Frequency<\/strong>: # of successful deployments<\/li>\n\n\n\n<li><strong>Lead Time<\/strong>: Seconds between merge and deploy<\/li>\n\n\n\n<li><strong>Change Failure Rate<\/strong>: Ratio (e.g. 0.25 = 25%)<\/li>\n\n\n\n<li><strong>MTTR<\/strong>: Seconds taken to resolve incidents<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udcc8 Step 4: Visualize &amp; Analyze Metrics<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Metrics appear in <strong>Project \u2192 Analytics \u2192 CI\/CD \u2192 DORA Metrics<\/strong> (UI available if licensed)<\/li>\n\n\n\n<li>You can export metrics to:\n<ul class=\"wp-block-list\">\n<li><strong>Grafana \/ PowerBI \/ Google Sheets<\/strong><\/li>\n\n\n\n<li><strong>GitLab CI pipeline reports or Slack alerts<\/strong><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u2699\ufe0f Step 5: Automate DORA API Pulls Using GitLab CI Job<\/h2>\n\n\n\n<p>Add the following job to your <code>.gitlab-ci.yml<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">dora_metrics:\n  stage: report\n  script:\n    - mkdir -p dora\n    - |\n      <span class=\"hljs-keyword\">for<\/span> metric in deployment_frequency lead_time_for_changes change_failure_rate time_to_restore_service; <span class=\"hljs-keyword\">do<\/span>\n        curl --silent --header <span class=\"hljs-string\">\"PRIVATE-TOKEN: $GITLAB_TOKEN\"<\/span> \\\n          <span class=\"hljs-string\">\"https:\/\/gitlab.com\/api\/v4\/projects\/$CI_PROJECT_ID\/dora\/metrics?metric=$metric&amp;start_date=$(date -I -d '30 days ago')&amp;end_date=$(date -I)&amp;interval=daily\"<\/span> \\\n          &gt; <span class=\"hljs-string\">\"dora\/${metric}.json\"<\/span>\n      done\n    - <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"\u2705 DORA metrics saved in the 'dora' directory\"<\/span>\n  artifacts:\n    paths:\n      - dora\/\n    expire_in: <span class=\"hljs-number\">7<\/span> days\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd10 CI\/CD Variable Required<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Key<\/th><th>Value<\/th><\/tr><\/thead><tbody><tr><td><code>GITLAB_TOKEN<\/code><\/td><td>Your personal access token with <code>read_api<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>This will generate JSON files in <code>dora\/<\/code> which can be uploaded to dashboards or emailed\/reported as needed.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83e\udde0 Best Practices<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Keep <code>production<\/code> tier tagging consistent for environments<\/li>\n\n\n\n<li>Use structured commit messages to link MRs to features<\/li>\n\n\n\n<li>Automate incident creation when pipeline fails in production<\/li>\n\n\n\n<li>Pull metrics into dashboards to observe trends<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u2705 Summary<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>DORA Metric<\/th><th>Setup Required<\/th><th>How to Fetch<\/th><\/tr><\/thead><tbody><tr><td>Deployment Frequency<\/td><td>Deployments with <code>production<\/code> tier<\/td><td><code>\/dora\/metrics?metric=deployment_frequency<\/code><\/td><\/tr><tr><td>Lead Time for Changes<\/td><td>MRs + Production Deployments<\/td><td><code>\/dora\/metrics?metric=lead_time_for_changes<\/code><\/td><\/tr><tr><td>Change Failure Rate<\/td><td>Incidents + Deployments<\/td><td><code>\/dora\/metrics?metric=change_failure_rate<\/code><\/td><\/tr><tr><td>MTTR<\/td><td>Incident open \u2192 close duration<\/td><td><code>\/dora\/metrics?metric=time_to_restore_service<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>GitLab 18.x Ultimate provides native support for all four DORA metrics via its REST API, giving engineering teams deep insights into the performance and reliability of their software delivery processes&#8230;. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[2],"tags":[],"class_list":["post-49521","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=49521"}],"version-history":[{"count":2,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49521\/revisions"}],"predecessor-version":[{"id":49523,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49521\/revisions\/49523"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=49521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=49521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=49521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}