[SE100 #070] DORA 지표 — 소프트웨어 전달 성과 측정
소프트웨어 공학 100 주제 시리즈의 70번째 글이다. (카테고리: 프로세스와 방법론)
한 줄 요약
DORA 지표는 “얼마나 빨리” 와 “얼마나 덜 깨지게” 를 한 쌍으로 재는 다섯 개의 숫자다. 지표 이름보다 중요한 것은 정의를 팀이 합의하는 일(무엇이 배포이고, 무엇이 실패인가)과, 그 숫자를 목표가 아니라 개선할 곳을 찾는 질문으로 쓰는 일이다.
왜 필요한가
다섯 지표의 이름과 뜻은 CI/CD 글에서 정리했다. 이 글은 그 다음 문제를 다룬다. 실제로 재려고 하면 바로 질문이 쏟아진다.
- 스테이징 배포도 배포인가? 피처 플래그를 켜는 것은?
- 리드 타임은 첫 커밋부터인가, PR 머지부터인가?
- 배포 후 사흘 뒤 발견된 버그는 “변경 실패” 인가?
- 열 개 팀의 숫자를 한 대시보드에 놓고 순위를 매겨도 되는가?
이 질문에 답하지 않고 대시보드부터 만들면, 숫자는 매주 나오지만 아무도 믿지 않거나, 더 나쁘게는 모두가 숫자를 맞추려고 행동을 바꾼다.
핵심 개념
지표는 진화해 왔다
DORA 의 Nathen Harvey 가 쓴 A history of DORA’s software delivery metrics(2026)가 변천을 정리한다.
| 시기 | 변화 |
|---|---|
| 2014 | 첫 연구가 “IT 성과” 를 정의하려고 배포 빈도, 변경 리드 타임, 평균 복구 시간(MTTR), 변경 실패율 네 변수로 출발. 그해 통계 분석에서는 변경 실패율이 다른 변수와 하나의 잠재 구성 개념으로 묶이지 않아, 2014년 정의는 나머지 세 지표에 의존 |
| 2015 | 처리량(배포 빈도, 리드 타임)과 안정성(MTTR, 변경 실패율)의 이원 구조로 정착. 고성과 팀이 둘 다 잘한다는 결과로 “속도는 안정성을 희생한다” 는 통념을 반박 |
| 2018 | 운영 건강도로 “가용성” 추가, 용어를 “소프트웨어 전달 및 운영(SDO) 성과” 로 변경 |
| 2021 | “가용성” 을 지연·성능·확장성까지 포괄하는 “신뢰성” 으로 확장 |
| 2023 | MTTR 을 실패한 배포 복구 시간으로 재정의. 소프트웨어 변경이 일으킨 장애와 외부 요인(데이터센터 장애 등)을 구분하기 위해 |
| 2024 | 다섯 번째 지표 배포 재작업률 도입. 처리량과 불안정성 두 묶음으로 재편 |
같은 글은 2021년 보고서가 신뢰성을 “다섯 번째 지표” 라고 부른 것이 부정확했다고 바로잡는다. 신뢰성은 전달 성과보다 운영 성과의 척도라는 것이다. 오래된 자료에서 “다섯 번째 지표 = 신뢰성” 을 보면 이 맥락을 기억해야 한다.
현재의 다섯 지표
DORA 지표 가이드의 정의다.
| 묶음 | 지표 | 정의 |
|---|---|---|
| 처리량 | 변경 리드 타임 | 변경이 버전 관리에 커밋된 때부터 운영에 배포될 때까지 걸리는 시간 |
| 처리량 | 배포 빈도 | 일정 기간의 배포 횟수, 또는 배포 사이의 시간 |
| 처리량 | 실패한 배포 복구 시간 | 즉각 조치가 필요한 실패 배포에서 복구하는 데 걸리는 시간 |
| 불안정성 | 변경 실패율 | 배포 직후 즉각 조치가 필요했던 배포의 비율 |
| 불안정성 | 배포 재작업률 | 운영 사고의 결과로 생긴, 계획에 없던 배포의 비율 |
복구 시간이 “안정성” 이 아니라 “처리량” 쪽에 있다는 점에 주목한다. 고치는 변경을 얼마나 빨리 내보낼 수 있는가도 흐름의 능력이기 때문이다.
왜 쌍으로 재는가
가이드는 DORA 연구가 “속도와 안정성이 트레이드오프가 아님” 을 거듭 보여 줬고, 대부분의 팀에서 지표들이 상관관계를 보이며, 상위 성과 팀은 다섯 지표 모두에서 잘하고 하위 팀은 모두에서 못한다고 쓴다. 한쪽만 재면 이런 일이 생긴다.
배포 빈도만 목표 ─▶ 쪼개기·빈 배포로 숫자 상승, 실패율도 상승 (보이지 않음)
실패율만 목표 ─▶ 배포를 미루고 묶음 ─▶ 큰 배치 ─▶ 실패 시 피해·복구 시간 증가
쌍으로 측정 ─▶ 한쪽을 희생한 개선이 바로 드러남
측정 정의를 먼저 합의한다
DORA 정의는 개념 수준이다. 팀이 운영적 정의를 정해야 한다.
| 질문 | 권장 기준 | 이유 |
|---|---|---|
| 무엇이 “배포” 인가 | 사용자 트래픽을 받는 운영 환경에 새 버전이 반영된 것 | 스테이징 포함 시 빈도가 부풀려짐 |
| 리드 타임 시작점 | 해당 배포에 포함된 커밋의 시각 (가이드 정의) | PR 머지 기준은 리뷰 대기를 숨김 |
| 리드 타임 대표값 | 중앙값과 상위 백분위 | 평균은 오래 묵은 커밋 하나에 휘둘림 |
| 무엇이 “실패” 인가 | 배포 직후 롤백·핫픽스·패치 등 즉각 조치가 필요했던 것 | 며칠 뒤 발견된 결함까지 넣으면 다른 지표가 됨 |
| 복구 완료 시점 | 서비스가 정상으로 돌아온 때(롤백 완료 포함) | 근본 수정 배포까지 기다리면 의미가 바뀜 |
| 재작업 배포 판별 | 사고 티켓에 연결된 계획 외 배포 | 수동 라벨보다 연결 규칙이 일관적 |
| 측정 단위 | 애플리케이션·서비스 단위 | 가이드도 애플리케이션 수준 적용을 권함 |
예제
배포 기록에서 다섯 지표를 계산한다. 데이터는 예시다.
from datetime import datetime as dt
from statistics import median
# commit: 배포에 포함된 가장 오래된 커밋 시각
# failed: 배포 직후 즉각 조치가 필요했나 / unplanned: 사고 대응용 계획 외 배포인가
deploys = [
dict(at="2026-09-01 10:00", commit="2026-08-29 15:00", failed=False, unplanned=False),
dict(at="2026-09-02 16:00", commit="2026-09-01 11:00", failed=True,
recovered="2026-09-02 17:10", unplanned=False),
dict(at="2026-09-02 17:05", commit="2026-09-02 16:40", failed=False, unplanned=True),
dict(at="2026-09-04 11:00", commit="2026-09-02 18:00", failed=False, unplanned=False),
dict(at="2026-09-08 14:00", commit="2026-09-04 09:00", failed=False, unplanned=False),
dict(at="2026-09-09 10:30", commit="2026-09-08 17:00", failed=True,
recovered="2026-09-09 13:30", unplanned=False),
dict(at="2026-09-09 13:20", commit="2026-09-09 12:50", failed=False, unplanned=True),
dict(at="2026-09-11 15:00", commit="2026-09-10 10:00", failed=False, unplanned=False),
]
p = lambda s: dt.strptime(s, "%Y-%m-%d %H:%M")
hours = lambda a, b: (p(b) - p(a)).total_seconds() / 3600
days = (p(deploys[-1]["at"]) - p(deploys[0]["at"])).days + 1
lead = [hours(d["commit"], d["at"]) for d in deploys]
fails = [d for d in deploys if d["failed"]]
recov = [hours(d["at"], d["recovered"]) for d in fails]
print(f"배포 빈도 : {len(deploys)}회 / {days}일")
print(f"변경 리드 타임 중앙값 : {median(lead):.1f}시간")
print(f"실패 배포 복구 시간 중앙값: {median(recov):.1f}시간")
print(f"변경 실패율 : {len(fails)}/{len(deploys)} = {len(fails)/len(deploys):.0%}")
rw = sum(d["unplanned"] for d in deploys)
print(f"배포 재작업률 : {rw}/{len(deploys)} = {rw/len(deploys):.0%}")
실행 결과:
배포 빈도 : 8회 / 11일
변경 리드 타임 중앙값 : 29.0시간
실패 배포 복구 시간 중앙값: 2.1시간
변경 실패율 : 2/8 = 25%
배포 재작업률 : 2/8 = 25%
읽는 법:
- 실패 두 건이 각각 재작업 배포(핫픽스)를 낳았다. 변경 실패율과 재작업률이 같은 것은 우연이 아니다. DORA 가 재작업률을 도입한 이유가, 변경 실패율이 팀이 해야 하는 재작업 양의 대리 지표로 작동한다는 관찰이었다.
- 리드 타임 중앙값 29시간 중 대부분은 커밋 뒤 배포를 기다린 시간일 가능성이 크다. 다음 질문은 “어디서 기다렸나” 다. 가치 흐름 지도(SE100 #065)로 넘어간다.
- 표본 8건은 너무 작다. 한 달 이상 모아 추세를 본다.
수집 파이프라인
# 이벤트 소스와 지표의 연결 (개념)
sources:
vcs: [commit_sha, committed_at]
cd: [deploy_id, service, env, deployed_at, commit_shas]
incident: [incident_id, caused_by_deploy_id, resolved_at]
derive:
change_lead_time: deployed_at - min(committed_at of commit_shas)
deployment_frequency: count(deploy where env == prod) per week
change_fail_rate: deploys with linked incident / prod deploys
failed_deploy_recovery: incident.resolved_at - deploy.deployed_at
deployment_rework_rate: prod deploys created to resolve an incident / prod deploys
Google 이 공개했던 참조 구현 Four Keys는 현재 보관(archived) 상태다. 구조는 참고하되 그대로 운영할 도구로 보지 않는 편이 좋다. 데이터가 없다면 DORA 의 Quick Check 설문으로 대략의 위치부터 볼 수 있다.
흔한 오해와 함정
DORA 지표 가이드가 직접 꼽는 함정이 대부분을 덮는다.
- 지표를 목표로 삼는다. 가이드는 지표를 목표로 설정하면 팀이 지표를 조작할 가능성이 커진다고 경고한다(굿하트의 법칙).
- 팀끼리 비교한다. 애플리케이션마다 맥락이 다르므로 팀·조직을 섞어 비교하는 것은 문제가 된다. 목표는 다른 팀과의 경쟁이 아니라 자기 팀의 시간에 따른 개선이다.
- 소유가 갈라진다. 개발은 처리량, 운영은 안정성만 책임지면 쌍으로 재는 의미가 사라진다. 가이드는 지표를 전달에 관여하는 모든 팀이 공유하라고 한다.
- 측정에 매달려 개선을 못 한다. 여러 시스템을 완벽하게 통합하는 데 몇 달을 쓰기보다, 거친 측정으로 시작해 개선에 집중하라고 권한다.
- DORA = 개발자 생산성. 다섯 지표는 소프트웨어 전달 성과다. 개인 생산성이나 개발 경험은 재지 않는다. 더 넓은 측정 틀은 SE100 #095(SPACE)에서, 사용자 관점의 신뢰성 목표는 SE100 #084(SLO)에서 다룬다.
- AI 도입 효과를 지표 하나로 판단한다. DORA 의 2025 보고서(State of AI-assisted Software Development)는 AI 의 주된 역할을 “조직의 기존 강점과 약점을 확대하는 증폭기” 로 본다. 처리량만 오르고 불안정성이 같이 오르면 증폭된 것은 약점이다.
확인 문제
- 2023년에 MTTR 이 “실패한 배포 복구 시간” 으로 바뀐 이유는?
- 현재 다섯 지표의 두 묶음과 각 묶음의 지표를 쓰라.
- 리드 타임 시작점을 “PR 머지 시각” 으로 잡으면 무엇이 가려지는가?
- 배포 빈도만 목표로 삼았을 때 생길 수 있는 왜곡 두 가지를 쓰라.
- 2021년 보고서가 신뢰성을 “다섯 번째 지표” 라고 부른 것이 부정확했다고 DORA 가 정정한 이유는?
풀이
- 이전 정의는 소프트웨어 변경이 일으킨 장애와 데이터센터 장애 같은 외부 요인을 구분하지 않았다. 변경으로 인한 손상에서의 복구에 초점을 맞춰 다른 전달 지표와 일관되게 했다.
- 처리량: 변경 리드 타임, 배포 빈도, 실패한 배포 복구 시간. 불안정성: 변경 실패율, 배포 재작업률.
- 커밋 뒤 리뷰를 기다리고 수정하는 시간. 흔히 리드 타임의 큰 부분인 리뷰 대기가 지표에서 사라진다.
- 의미 없는 작은 배포·빈 배포로 숫자를 부풀리는 것, 그리고 검증을 줄여 빈도를 올리면서 실패율·재작업률이 함께 나빠지는 것.
- 신뢰성은 소프트웨어 전달 성과라기보다 운영 성과의 척도이기 때문이다.
더 읽을거리 (References)
- DORA, DORA’s software delivery performance metrics
- Nathen Harvey, A history of DORA’s software delivery metrics, DORA, 2026
- DORA, State of AI-assisted Software Development 2025, Accelerate State of DevOps Report 2024
- DORA, Quick Check
- dora-team, Four Keys (archived)
- Nicole Forsgren, Jez Humble, Gene Kim, Accelerate: The Science of Lean Software and DevOps, IT Revolution, 2018 (서지 정보)
- CS300: CI/CD