{"id":"IL-0322","org":"GitLab","date":"2026-06-11","docs":["https://gitlab.com/gitlab-com/gl-infra/production/-/issues/18269","https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/work_items/29220","https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/work_items/29221","https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/work_items/29222","https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/work_items/29192"],"title":{"en":"A GCP storage incident degraded the disk under GitLab.com's primary PostgreSQL and caused two bursts of site-wide 503s","ko":"GitLab.com 의 모든 주요 서비스에서 HTTP 503 오류가 두 차례 쏟아졌다가 저절로 멎었다"},"domain":["database","gcp"],"impact":{"scope":"Web, frontend, API, git, websockets, web-pages and CI runners on https://gitlab.com returned HTTP 503 errors during 06:16-06:22 and 07:03-07:12 UTC","users":"All external customers and users of https://gitlab.com","region":"GCP us-east1-b (zone of the degraded disk)"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"A single degraded disk was enough to take down GitLab.com because all primary database traffic goes through one node and requests waited for the Rack timeout instead of failing fast. The leading indicators, disk IO queue depth, pgBouncer pool saturation and LWLock contention, rose before full impact but had no alerts. Without decision criteria for a switchover, responders spent much of an intermittent incident waiting, and it was hard to decide when to move the incident to Fixing or Monitoring.","ko":"디스크 하나가 나빠진 것만으로 GitLab.com 전체가 멈췄다. 데이터베이스 부하 분산이 빨리 실패하지 않아 요청이 60초 Rack 타임아웃까지 쌓였다. 빨리 실패하지 않는 문제는 이전 장애 #18269 에서 얻은 교훈과 겹쳤다. 장애 조치 기준이 미리 정해져 있지 않아 문제가 다시 날지 몰라 지켜보고 기다리는 데 많은 시간을 썼다. 클라우드 제공자 장애가 넓게 퍼진 상황이라 어느 존이 정상인지 미리 확인할 수도 없었다. 끊겼다 저절로 회복하는 장애에서는 장애 상태를 언제 Fixing 이나 Monitoring 으로 옮길지 정하기 어려웠다."},"related":[],"sources":[{"url":"https://gitlab.com/gitlab-com/gl-infra/production/-/issues/22330","kind":"github","archived":null}],"summary":{"en":"All primary database traffic for GitLab.com goes through a single primary node, patroni-main-v17-01-db-gprd in project gitlab-production. A confirmed GCP storage incident affected a disk backing that node in `us-east1-b`, and the node suffered severe IO contention, seen as disk IO queue depth spikes, LWLock contention, replication lag and pgBouncer connection pool saturation. Calls to the primary were blocked, and because the application's database load balancing did not shed or reroute requests when the primary stopped responding, requests piled up until the 60-second Rack timeout instead of failing fast. That turned one degraded disk into two short site-wide outages; both ended without manual remediation.\n\nThe incident was raised to Severity 1 at 06:17:42. Responders paused deployments, engaged the GCP TAM and opened a support case, and GCP confirmed the storage incident; the root cause was confirmed at 12:15:57. Failover depended on a human decision with no agreed threshold, so the team prepared a Patroni switchover to another zone as a contingency, weighing its effect on write throughput, and paused the incident for a 3-hour review at 15:19:42; no recurrence was seen and the platform has been fully operational since 07:25 UTC. There was no direct alerting on disk IO saturation, pgBouncer pool saturation or LWLock contention, which were the leading indicators. The review ties the missing fail-fast behaviour to learnings from the earlier incident #18269.","ko":"2026-06-11 https://gitlab.com 의 모든 주요 서비스가 06:16~06:22 UTC 와 07:03~07:12 UTC 두 차례 HTTP 503 오류를 냈다. 오류는 넓은 범위에서 끊겼다 이어지기를 반복했다. 영향은 06:12 에 시작됐다. 06:16 에 Pingdom 알림이 이를 잡았고 06:17 에 Severity 1 로 올라갔다. 두 번 모두 5~10분 안에 저절로 회복했다.\n\n원인은 us-east1-b 존의 GCP 스토리지 장애였고, 이 장애가 주 데이터베이스 노드가 쓰는 디스크에 영향을 줬다. 디스크 IO 가 떨어지자 주 노드에서 IO 큐 깊이가 치솟고 LWLock 경합, 복제 지연, pgBouncer 연결 풀 포화가 뒤따랐다. Postgres 와 Redis 로 가는 호출이 막혀 요청이 60초 Rack 제한에 걸려 타임아웃됐다. 주 데이터베이스로 가는 트래픽은 모두 주 노드 하나를 거쳤다. 애플리케이션의 데이터베이스 부하 분산은 주 노드가 응답하지 않을 때 요청을 덜어 내거나 다른 곳으로 보내지 못했다. 그래서 요청이 빨리 실패하지 않고 Rack 타임아웃까지 쌓였다. 장애 조치는 사람이 판단해야 했고 미리 정한 기준이 없었다.\n\n팀은 데이터베이스 운영 전문가에게 장애를 에스컬레이션하고 배포를 멈췄다. 08:13 에 주 노드의 디스크 IO 큐 깊이 급증 두 번을 찾아 GCP TAM 에 연락했고, 08:56 에 GCP 지원 케이스를 열었다. 12:15 에 클라우드 제공자 장애가 원인으로 확인됐다. 12:29 에 us-east1-d 의 04 노드로 Patroni 주 노드 전환을 준비했지만 실행하지는 않았다. 서비스는 07:25 부터 안정적이었고, 15:19 에 장애를 멈춰 두고 3시간 동안 검토해 재발이 없음을 확인한 뒤 해결로 처리했다."},"trigger":{"en":"A GCP storage incident degraded the IO of a disk in the `us-east1-b` zone that backed GitLab.com's primary PostgreSQL node.","ko":"us-east1-b 존의 GCP 스토리지 장애로 주 데이터베이스 노드가 쓰는 디스크의 스토리지 IO 성능이 떨어졌다."},"severity":"sev1","symptoms":["service-unavailable","intermittent-timeouts","connection-pool-exhausted","lock-contention","replication-lag"],"timeline":{"detected_after":"4m","resolved_after":"1h"},"date_kind":"incident","detection":{"en":"A Pingdom alert on the user-facing 503 errors was reported in triage at 06:16:12 UTC. No alert existed for disk IO saturation, pgBouncer pool saturation or LWLock contention.","ko":"06:16:12 UTC 에 Pingdom 알림이 장애를 알렸다. 영향은 06:12 에 시작됐으므로 감지까지 약 4분이 걸렸다. 사용자에게 보이는 503 은 알림이 잡았지만, 먼저 나타난 신호인 디스크 IO 포화, pgBouncer 풀 포화, LWLock 경합에는 알림이 없었다."},"components":["database","block-storage"],"root_cause":"cloud-provider","remediation":[{"text":{"en":"Escalated to Database Operations experts","ko":"두 번째 구간이 데이터베이스와 연결 계층을 가리키자 07:11 UTC 에 데이터베이스 운영 tier2 로 장애를 에스컬레이션했다. 데이터베이스 전문가가 LWLock 경합, pg_wait_sampling_buffer_mapping 급증, 복제 지연을 깊이 진단했다."}},{"text":{"en":"Paused deployments","ko":"배포를 멈췄다."}},{"text":{"en":"Opened a GCP support case and engaged the GCP TAM, and GCP confirmed the storage incident","ko":"08:13 UTC 에 GCP TAM 에 연락하고 08:56 에 GCP 지원 케이스를 열었다. 클라우드 제공자가 스토리지 장애를 확인해 줬다."}},{"text":{"en":"Prepared a Patroni primary switchover to node 04 in us-east1-d as a contingency, without executing it","ko":"다시 나빠지면 바로 실행할 수 있게 us-east1-d 의 04 노드로 Patroni 주 노드 전환을 준비했다. 쓰기 처리량에 줄 영향도 따져 두었지만 실행하지는 않았다."}},{"text":{"en":"Held a 3-hour pause-and-review window and resolved the incident after no recurrence","ko":"GCP 쪽 문제가 가라앉은 것으로 보이자 15:19 UTC 에 장애를 멈춰 두고 3시간 동안 지켜봤고, 재발이 없음을 확인한 뒤 해결로 처리했다."}}],"action_items":[{"text":{"en":"Add disk IO saturation and queue-depth alerting for primary Patroni database nodes","ko":"Patroni 주 데이터베이스 노드에 디스크 IO 포화와 큐 깊이 알림을 넣는다."}},{"text":{"en":"Write a Patroni primary switchover runbook with explicit trigger thresholds","ko":"명시적인 실행 기준을 담은 Patroni 주 노드 전환 런북을 쓴다."}},{"text":{"en":"Clarify incident state-transition guidance for intermittent, self-resolving issues","ko":"끊겼다 저절로 회복하는 장애에서 장애 상태를 언제 바꿀지 지침을 분명히 한다."}},{"text":{"en":"Decide whether the primary should fail over automatically during disk IO degradation","ko":"디스크 IO 가 떨어지는 동안 자동으로 장애 조치했어야 했는지 검토한다."}},{"text":{"en":"Find a short-term mitigation that limits the blast radius of a single degraded disk until Cells do so","ko":"Cells 는 장기적으로 영향 범위를 줄이도록 설계됐다. 그와 별도로 디스크 하나가 GitLab.com 전체를 멈추지 않도록 단기 완화책을 마련한다."}},{"text":{"en":"Make application database load balancing fail fast or reroute when the primary stops responding","ko":"주 노드가 응답하지 않을 때 애플리케이션의 데이터베이스 부하 분산이 요청을 덜어 내거나 다른 곳으로 보내, 요청이 60초 Rack 타임아웃까지 쌓이지 않고 빨리 실패하게 한다."}},{"text":{"en":"Consider alerting on pgBouncer pool saturation and LWLock contention as leading indicators","ko":"pgBouncer 풀 포화와 LWLock 경합이 전면 장애보다 먼저 튀었으므로, 이 둘을 먼저 나타나는 신호로 보고 알림을 걸지 검토한다."}}],"contributing":["single-point-of-failure","no-alert-on-limit","no-runbook"],"recurrence_of":null,"symptoms_text":{"en":"On 2026-06-11 https://gitlab.com returned widespread, intermittent HTTP 503 errors across all major services in two bursts of about 5 to 10 minutes, 06:16 to 06:22 UTC and 07:03 to 07:12 UTC. A Pingdom alert reported the first burst in triage at 06:16:12, about four minutes after impact began at 06:12, and each burst ended on its own.\n\nWeb, frontend, API, git, websockets, web-pages and CI runners were all affected. Requests timed out at the 60-second Rack limit because network calls to Postgres and Redis were blocked. HAProxy 5xx errors spiked in both windows, peaking at 06:18 to 06:20 and 07:06 to 07:08. On the primary database instance patroni-main-v17-01-db-gprd, disk IO queue depth jumped to about 219 at 06:16 and to about 353 to 405 at 07:00 to 07:02, and LWLock contention, `pg_wait_sampling_buffer_mapping`, replication lag and pgBouncer pool saturation in both the sync and async pools spiked during the windows.\n\nAfter the first burst the initial assessment pointed to a temporary external networking issue, and the incident went to Monitoring at 06:30:06. Cloudflare data showed no DDoS activity and no unusual request volume, and slow queries were ruled out early. When the second burst began at 07:03, pgBouncer pool saturation across the sync and async pools pointed to the database layer, and the incident was escalated to Database Operations at 07:11:35. Responders found the `pg_wait_sampling_buffer_mapping` spikes at 07:36:45, the LWLock contention at 08:00:22 and the two disk IO queue depth spikes on the primary at 08:13:27, then contacted the GCP TAM and opened a GCP support case at 08:56:29.\n\nBecause the errors came and went, much of the response was spent watching and waiting to see whether they would return. There was no agreed threshold for when to fail over, and with a widespread cloud provider problem the team could not confirm in advance which zone was healthy enough to switch to. A Patroni primary switchover to node `04` in `us-east1-d` was prepared at 12:29:08 but not executed.","ko":"2026-06-11 06:16 UTC 에 Pingdom 알림이 https://gitlab.com 의 HTTP 503 오류를 알렸다. 웹, 프런트엔드, API, git, 웹소켓, web-pages, CI 러너가 06:16~06:22 UTC 와 07:03~07:12 UTC 두 차례 503 을 냈다. 오류는 여러 서비스에 걸쳐 끊겼다 이어지기를 반복했고, 매번 5~10분 안에 저절로 회복했다.\n\n요청은 60초 Rack 제한에 걸려 타임아웃됐다. Redis 와 Postgres 로 가는 네트워크 호출이 막혀 있었다. HAProxy 5xx 오류는 06:18~06:20 과 07:06~07:08 에 가장 많았다.\n\n주 데이터베이스 인스턴스 patroni-main-v17-01-db-gprd 의 디스크 IO 큐 깊이가 06:16 에 약 219, 07:00~07:02 에 약 353 에서 405 로 치솟아 오류 구간과 겹쳤다. 같은 구간에 LWLock 경합, pg_wait_sampling_buffer_mapping, 복제 지연, sync 와 async pgBouncer 풀 포화가 함께 튀었다.\n\n첫 번째 구간이 지난 뒤 팀은 일시적인 외부 네트워크 문제로 판단하고 06:30 에 상태를 Monitoring 으로 바꿨다. 07:03 에 두 번째 구간이 시작되고 07:10 에 sync 와 async 풀 모두에서 pgBouncer 풀 포화가 보이자 상태를 Investigating 으로 되돌리고 데이터베이스 운영 tier2 로 에스컬레이션했다. Cloudflare 데이터로 DDoS 와 느린 쿼리는 일찍 배제했고, 장애 전에 이상한 요청량도 없었다."},"updated_at":"2026-11-14T12:33:57.520357Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0322","org_slug":"gitlab"}