| name | DORA Metrics and DevOps Performance |
| description | The agent implements DORA metrics tracking for measuring and improving software delivery performance. Use when establishing engineering metrics, benchmarking teams, or driving DevOps transformation. |
| category | devops |
DORA Metrics and DevOps Performance
Purpose
DORA (DevOps Research and Assessment) metrics are the industry standard for measuring software delivery performance. Google's research across thousands of organizations identified four key metrics that predict:
- Organizational performance (profitability, market share)
- Non-commercial performance (quality, customer satisfaction)
- Team well-being and reduced burnout
Elite performers who meet reliability targets are 2.3x more likely to use trunk-based development and continuous delivery practices.
Features
| Metric | What It Measures | Elite Benchmark |
|---|
| Deployment Frequency | How often code reaches production | Multiple times per day |
| Lead Time for Changes | Time from commit to production | Less than 1 hour |
| Change Failure Rate | Percentage of deployments causing failures | 0-15% |
| Time to Restore Service | Recovery time from incidents | Less than 1 hour |
The Four Key Metrics
1. Deployment Frequency
Definition: How often your organization deploys code to production.
interface DeploymentData {
timestamp: Date;
environment: string;
service: string;
success: boolean;
}
function calculateDeploymentFrequency(
deployments: DeploymentData[],
periodDays: number = 30
): { frequency: string; deploymentsPerDay: number } {
const productionDeployments = deployments.filter(
d => d.environment === 'production' && d.success
);
const deploymentsPerDay = productionDeployments.length / periodDays;
let frequency: string;
if (deploymentsPerDay >= 1) {
frequency = 'elite';
} else if (deploymentsPerDay >= 1/7) {
frequency = 'high';
} else if (deploymentsPerDay >= 1/30) {
frequency = 'medium';
} {
frequency = ;
}
{ frequency, deploymentsPerDay };
}
2. Lead Time for Changes
Definition: Time from code commit to code running in production.
interface ChangeData {
commitTimestamp: Date;
deployTimestamp: Date;
commitSha: string;
prNumber?: number;
}
function calculateLeadTime(changes: ChangeData[]): {
medianHours: number;
p90Hours: number;
performance: string;
} {
const leadTimes = changes.map(c =>
(c.deployTimestamp.getTime() - c.commitTimestamp.getTime()) / (1000 * 60 * 60)
);
leadTimes.sort((a, b) => a - b);
const median = leadTimes[Math.floor(leadTimes.length / 2)];
const p90 = leadTimes[Math.floor(leadTimes.length * 0.9)];
let performance: string;
if (median < 1) {
performance = 'elite';
} (median < ) {
performance = ;
} (median < ) {
performance = ;
} {
performance = ;
}
{ : median, : p90, performance };
}
3. Change Failure Rate
Definition: Percentage of deployments that result in degraded service requiring remediation.
interface DeploymentOutcome {
deploymentId: string;
timestamp: Date;
success: boolean;
causedIncident: boolean;
requiredRollback: boolean;
requiredHotfix: boolean;
}
function calculateChangeFailureRate(deployments: DeploymentOutcome[]): {
rate: number;
performance: string;
} {
const total = deployments.length;
const failures = deployments.filter(d =>
d.causedIncident || d.requiredRollback || d.requiredHotfix
).length;
const rate = (failures / total) * 100;
let performance: string;
if (rate <= 15) {
performance = 'elite';
} else if (rate <= 30) {
performance = 'high';
} else if (rate <= 45) {
performance = ;
} {
performance = ;
}
{ rate, performance };
}
4. Time to Restore Service (MTTR)
Definition: How long it takes to restore service when an incident occurs.
interface Incident {
id: string;
startTime: Date;
resolvedTime: Date;
severity: 'critical' | 'major' | 'minor';
service: string;
}
function calculateMTTR(incidents: Incident[]): {
medianHours: number;
performance: string;
byService: Record<string, number>;
} {
const restorationTimes = incidents.map(i =>
(i.resolvedTime.getTime() - i.startTime.getTime()) / (1000 * 60 * 60)
);
restorationTimes.sort((a, b) => a - b);
const median = restorationTimes[Math.floor(restorationTimes.length / 2)];
let performance: string;
if (median < 1) {
performance = 'elite';
} (median < ) {
performance = ;
} (median < ) {
performance = ;
} {
performance = ;
}
: <, []> = {};
( incident incidents) {
(!byService[incident.]) byService[incident.] = [];
hours = (incident..() - incident..()) / ( * * );
byService[incident.].(hours);
}
: <, > = {};
( [service, times] .(byService)) {
times.( a - b);
serviceMedians[service] = times[.(times. / )];
}
{ : median, performance, : serviceMedians };
}
Performance Levels (2024 Benchmarks)
| Level | Deploy Freq | Lead Time | Change Failure | MTTR |
|---|
| Elite | Multiple/day | < 1 hour | 0-15% | < 1 hour |
| High | Daily-Weekly | 1 day - 1 week | 16-30% | < 1 day |
| Medium | Weekly-Monthly | 1 week - 1 month | 16-30% | < 1 day |
| Low | Monthly+ | 1-6 months | 16-30% | < 1 week |
Key Insight (2024 DORA Report): Elite performers are 2.3x more likely to meet reliability targets when using trunk-based development.
Measurement Implementation
GitHub Actions DORA Workflow
name: DORA Metrics Collection
on:
schedule:
- cron: '0 0 * * 0'
workflow_dispatch:
jobs:
collect-metrics:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Collect Deployment Data
id: deployments
uses: actions/github-script@v7
with:
script: |
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
// Get workflow runs (deployments)
const { data: runs } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'deploy.yml',
created: `>=${thirtyDaysAgo.toISOString()}`,
{
,
,
}
{ }
{
}
{
,
}
[ ]
[ ]
Custom Metrics Collection Script
import { Octokit } from '@octokit/rest';
interface DORAMetrics {
period: { start: Date; end: Date };
deploymentFrequency: {
count: number;
perDay: number;
performance: 'elite' | 'high' | 'medium' | 'low';
};
leadTime: {
medianHours: number;
p90Hours: number;
performance: 'elite' | 'high' | 'medium' | 'low';
};
changeFailureRate: {
total: number;
failures: number;
rate: number;
performance: 'elite' | 'high' | 'medium' | 'low';
};
mttr: {
medianHours: number;
incidentCount: number;
performance: 'elite' | 'high' | 'medium' | 'low';
};
: | | | ;
}
{
: ;
: ;
: ;
() {
. = ({ : token });
. = owner;
. = repo;
}
(: = ): <> {
end = ();
start = ();
start.(start.() - periodDays);
[deployments, prs, incidents] = .([
.(start, end),
.(start, end),
.(start, end)
]);
deploymentFrequency = .(deployments, periodDays);
leadTime = .(prs);
changeFailureRate = .(deployments, incidents);
mttr = .(incidents);
performances = [
deploymentFrequency.,
leadTime.,
changeFailureRate.,
mttr.
];
overallPerformance = .(performances);
{
: { start, end },
deploymentFrequency,
leadTime,
changeFailureRate,
mttr,
overallPerformance
};
}
() {
{ data } = ...({
: .,
: .,
: ,
:
});
data.;
}
() {
{ data } = ...({
: .,
: .,
: ,
: ,
:
});
data.(
pr. &&
(pr.) >= start &&
(pr.) <= end
);
}
() {
{ data } = ...({
: .,
: .,
: ,
: ,
: start.()
});
data;
}
() {
successful = deployments.( d. === );
perDay = successful. / periodDays;
{
: successful.,
perDay,
: .(perDay)
};
}
() {
times = prs.( {
created = (pr.);
merged = (pr.);
(merged.() - created.()) / ( * * );
});
times.( a - b);
median = times[.(times. / )] || ;
p90 = times[.(times. * )] || ;
{
: median,
: p90,
: .(median)
};
}
() {
total = deployments.( d. === ).;
failures = incidents.;
rate = total > ? (failures / total) * : ;
{
total,
failures,
rate,
: .(rate)
};
}
() {
times = incidents
.( i.)
.( {
opened = (i.);
closed = (i.);
(closed.() - opened.()) / ( * * );
});
times.( a - b);
median = times[.(times. / )] || ;
{
: median,
: incidents.,
: .(median)
};
}
(: ): | | | {
(perDay >= ) ;
(perDay >= /) ;
(perDay >= /) ;
;
}
(: ): | | | {
(hours < ) ;
(hours < ) ;
(hours < ) ;
;
}
(: ): | | | {
(rate <= ) ;
(rate <= ) ;
(rate <= ) ;
;
}
(: ): | | | {
(hours < ) ;
(hours < ) ;
(hours < ) ;
;
}
(: []): | | | {
scores = { : , : , : , : };
avg = performances.( sum + scores[p keyof scores], ) / performances.;
(avg >= ) ;
(avg >= ) ;
(avg >= ) ;
;
}
}
collector = (
process..!,
,
);
metrics = collector.();
.(.(metrics, , ));
Grafana Dashboard Configuration
{
"dashboard": {
"title": "DORA Metrics Dashboard",
"panels": [
{
"title": "Deployment Frequency",
"type": "stat",
"targets": [
{
"expr": "sum(increase(deployments_total{environment=\"production\"}[30d])) / 30",
"legendFormat": "Deploys/day"
}
],
"fieldConfig": {
"defaults": {
"thresholds": {
"steps": [
{ "value": 0, "color": "red" }
Tools and Platforms
| Tool | Type | Features |
|---|
| Four Keys (Google) | Open Source | GitHub/GitLab integration, BigQuery |
| LinearB | Commercial | Git analytics, workflow metrics |
| Sleuth | Commercial | Deploy tracking, change intelligence |
| Faros AI | Commercial | Multi-source aggregation |
| Propelo | Commercial | SDLC insights |
| Jellyfish | Commercial | Engineering management |
Four Keys Setup (Google)
git clone https://github.com/dora-team/fourkeys.git
cd fourkeys
export PROJECT_ID="my-project"
export REGION="us-central1"
./setup/setup.sh
Improvement Strategies
Improving Deployment Frequency
| Current | Target | Strategy |
|---|
| Monthly | Weekly | Automate deployments, reduce batch size |
| Weekly | Daily | Feature flags, trunk-based development |
| Daily | Multiple/day | Continuous deployment, small PRs |
Improving Lead Time
| Bottleneck | Solution |
|---|
| Long code reviews | Smaller PRs, async reviews, automation |
| Manual testing | Automated tests, shift-left |
| Manual deployments | CI/CD automation |
| Environment issues | Infrastructure as code |
Reducing Change Failure Rate
| Problem | Solution |
|---|
| Insufficient testing | Increase coverage, add integration tests |
| Big bang releases | Feature flags, canary releases |
| Lack of review | Automated checks, required reviews |
| Poor monitoring | Better observability, alerting |
Reducing MTTR
| Improvement | Impact |
|---|
| Runbooks | Faster diagnosis |
| Feature flags | Instant rollback |
| Observability | Faster root cause |
| Chaos engineering | Proactive resilience |
Best Practices
1. Measure Consistently
const METRIC_DEFINITIONS = {
deploymentFrequency: {
source: 'GitHub Actions',
filter: 'workflow=deploy.yml, conclusion=success',
aggregation: 'count per day'
},
leadTime: {
source: 'GitHub PRs',
measurement: 'created_at to merged_at',
aggregation: 'median'
},
changeFailureRate: {
source: 'GitHub Issues + Deployments',
filter: 'label=incident, within 24h of deployment',
aggregation: 'incidents / deployments * 100'
},
mttr: {
source: 'PagerDuty',
measurement: 'triggered_at to resolved_at',
aggregation: 'median'
}
};
2. Set Realistic Goals
q1_2024:
deployment_frequency:
current: 0.5/day
target: 1.0/day
improvement: 100%
lead_time:
current: 48h
target: 24h
improvement: 50%
change_failure_rate:
current: 25%
target: 20%
improvement: 20%
mttr:
current: 4h
target: 2h
improvement: 50%
3. Avoid Gaming Metrics
| Gaming Behavior | Why It's Bad | Better Approach |
|---|
| Deploying empty commits | Fake frequency | Track meaningful changes |
| Not labeling incidents | Hide failures | Blameless culture |
| Splitting PRs artificially | Fake lead time | Focus on value |
| Rushing fixes | Lower quality | Fix root cause |
Use Cases
1. Team Performance Review
async function quarterlyReview(team: string) {
const metrics = await collectMetrics({ team, period: '90d' });
return {
summary: {
overallPerformance: metrics.overallPerformance,
strongestMetric: findStrongest(metrics),
improvementArea: findWeakest(metrics)
},
comparison: {
vsLastQuarter: await compareToLastQuarter(team, metrics),
vsIndustry: compareToIndustryBenchmarks(metrics)
},
recommendations: generateRecommendations(metrics)
};
}
2. DevOps Transformation Tracking
const transformationGoals = {
phase1: {
deploymentFrequency: 'weekly',
leadTime: '< 1 week'
},
phase2: {
deploymentFrequency: 'daily',
leadTime: '< 1 day',
changeFailureRate: '< 30%'
},
phase3: {
deploymentFrequency: 'multiple/day',
leadTime: '< 1 hour',
changeFailureRate: '< 15%',
mttr: '< 1 hour'
}
};
Related Skills
devops/github-actions - CI/CD automation
devops/observability - Monitoring and metrics
testing/comprehensive-testing - Quality gates
devops/feature-flags - Progressive delivery
Think Omega. Build Omega. Be Omega.