{"id":"IL-0290","org":"GitLab","date":"2026-05-12","docs":["https://gitlab.com/gitlab-com/gl-infra/production/-/work_items/22103","https://gitlab.com/gitlab-com/gl-infra/production/-/issues/19532","https://gitlab.com/gitlab-com/gl-infra/production/-/issues/19543","https://gitlab.com/gitlab-com/gl-infra/production/-/issues/19690"],"title":{"en":"GitLab.com's Redis Sidekiq cluster ran out of memory and lost quorum, causing 500 errors and a 12 million job backlog","ko":"GitLab.com 의 Redis Sidekiq 클러스터에서 노드 여러 대가 메모리를 다 써 멈추고 쿼럼을 잃어, 웹과 Git 과 CI 전반에서 500 오류가 늘었다"},"domain":["database","gcp"],"impact":{"scope":"All major GitLab.com services, including web, Git, API, CI runners and Sidekiq: more than 1 million requests affected, a Sidekiq backlog of over 12 million jobs and an estimated more than 10,000 pipelines affected","users":"All GitLab.com customers active during the impact period","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"Broad degradation across web, Git, authentication, CI runners, Sidekiq and the internal API made it hard to settle on one cause and explain it clearly. The customer symptom of pipelines stuck in created was hard to measure in real time, and the dashboards that would have answered it were not obvious to on-call responders. Some alerts did not reach the right on-call people, and hosts that hung on login slowed diagnosis and made changes riskier. Redis-sidekiq under memory saturation forces choices between availability and data loss that are hard to make during an incident and call for guardrails and design changes.","ko":"web, Git, 인증, CI 러너, Sidekiq, 내부 API 가 한꺼번에 나빠져 원인 하나로 좁히고 그것을 짧게 전하기가 어려웠다. created 상태에 멈춘 파이프라인처럼 고객이 겪는 증상을 실시간으로 세고 확인할 방법이 부족했고, 관련 대시보드와 SLI 를 온콜이 찾기 어려웠다. 호스트가 응답하지 않아 SSH 로그인이 멈추면서 진단이 늦어지고 변경할 때의 위험도 커졌다. 신호가 있어도 라벨과 라우팅의 틈 때문에 맞는 온콜에게 닿지 않았다. redis-sidekiq 의 메모리가 포화되자 엔지니어는 장애 한가운데서 가용성과 데이터 손실 사이의 어려운 선택을 해야 했다. 이 부분에는 안전장치와 설계 개선이 필요했다. 대시보드와 로그로 트래픽 급증을 먼저 배제한 덕분에 공용 의존성과 인프라 쪽 원인에 집중할 수 있었다. 대기열 비우기처럼 되돌릴 수 없는 선택을 미루고 안전한 완화부터 한 것도 도움이 됐다."},"related":[],"sources":[{"url":"https://gitlab.com/gitlab-com/gl-infra/production/-/issues/22108","kind":"github","archived":null}],"summary":{"en":"GitLab.com runs its Sidekiq background jobs on Redis Sidekiq clusters; the catchall-b shard ran on three VMs, redis-sidekiq-catchall-b-01-db-gprd, -02 and -03. Earlier on 12 May, responders to INC-10084, a Sidekiq queueing apdex SLO violation on shard catchall-b, deferred the jobs of AuditEvents::AuditEventStreamingWorker. The deferred audit event jobs accumulated in Redis until they had taken all available memory on the cluster. The memory exhaustion led to kernel errors and made several Redis nodes fail, leaving one healthy node that could not keep cluster quorum. From 17:12 UTC every major GitLab.com service had raised error rates, authentication failures and delayed jobs, and the incident was raised to Severity 1 at 17:32.\n\nSymptoms across many services and hosts that hung on SSH login slowed the diagnosis. Once the catchall-b nodes were confirmed unhealthy, engineers restarted and force-reset the two unresponsive nodes; all three were up by 18:00, but errors came back. Engineers then stopped each Redis VM in turn and resized it to the c2-standard-16 machine type, doubling its memory and CPU, starting with catchall-b-01 at about 18:10 and stopping catchall-b-03 at 18:25. By 18:40 all three nodes were upgraded and error rates fell, and impact ended at 18:43:44 UTC, 1 hour 31 minutes after it began. AuditEventStreamingWorker was re-enabled instead of being deferred, the backlog dropped from its peak of 12.2 million jobs to under 7 million by 19:10, and the incident was resolved at 21:30. Responders held back from irreversible options such as flushing queues, and the review notes that Redis-sidekiq under memory saturation forced hard choices between availability and data loss.\n\nThe review names AuditEvents::AuditEventStreamingWorker as a recurring contributing factor, counting at least 4 prior incidents since March 2025 that grew in severity each time. It lists INC-310 (S2, 24 March 2025, PGBouncer saturation), INC-311 (S2, a repeat the next day), INC-489 (S2, 15 April 2025, a bad streaming destination) and then this S1 incident. During the incident a responder also noted that this was the second S2 involving the worker that month, after INC-8169, and that there had been an S3 in December.","ko":"2026-05-12 GitLab.com 에서 같은 날 앞선 장애 inc-10084 를 완화하면서 감사 이벤트 작업을 지연 처리로 돌렸다. 지연된 작업이 쌓여 Redis Sidekiq catchall-b 클러스터의 메모리를 모두 차지했고, 메모리가 바닥나자 Redis 호스트에서 커널 오류가 나며 노드 여러 대가 멈췄다. 정상 노드가 하나만 남아 클러스터는 쿼럼을 유지하지 못했다. 17:12 UTC 부터 web, CI 러너, Git, API, Sidekiq 을 포함한 GitLab.com 의 주요 서비스 전반에서 오류율이 올랐고, 100만 건이 넘는 요청이 영향을 받았다. Sidekiq 대기열이 1,200만 개를 넘으며 파이프라인 생성과 작업 처리가 멈췄고, 영향받은 파이프라인은 1만 개가 넘는 것으로 추정됐다. 장애는 Severity 1 로 올라갔다.\n\n대응한 엔지니어들은 트래픽 급증을 원인에서 빼고 catchall-b 노드들이 응답하지 않는다는 것을 확인한 뒤, 응답 없는 노드 두 대를 재시작하고 강제로 리셋했다. 18:00 UTC 에 세 노드가 모두 올라오고 O2 가 primary 가 됐지만 노드들은 곧 다시 오류를 냈다. 엔지니어는 VM 을 한 대씩 멈추고 메모리와 CPU 를 두 배로 늘린 머신 타입으로 바꿨고, 18:40 UTC 에 세 노드의 교체가 끝나며 오류율이 떨어졌다. 영향은 18:43:44 UTC 에 끝나 1시간 31분 이어졌다. 대기열 비우기처럼 되돌릴 수 없는 선택은 미루고 안전한 완화부터 했다. Sidekiq 대기열은 최대 1,220만 개에서 19:10 UTC 에 700만 개 아래로 줄었고, 장애는 21:30:57 UTC 에 사후 처리 단계로 넘어갔다.\n\n문제의 워커인 AuditEvents::AuditEventStreamingWorker 는 2025년 3월부터 장애를 거듭 일으켰고 그때마다 심각도가 올랐다. 2025-03-24 의 INC-310 은 PGBouncer 포화였고, 다음 날 INC-311 은 같은 일이 되풀이된 것이었다. 2025-04-15 의 INC-489 는 잘못된 스트리밍 대상 때문이었다. 셋 다 S2 였다. 이번 INC-10096 은 S1 이었다. 장애 중에 한 엔지니어는 이 워커가 얽힌 S2 장애가 이번 달에만 두 번째라고 짚었다. 앞선 것은 INC-8169 였고, 12월에는 S3 장애도 있었다."},"trigger":{"en":"Earlier on 12 May, as a mitigation for a previous incident, INC-10084, a Sidekiq queueing apdex SLO violation on shard catchall-b, jobs of AuditEvents::AuditEventStreamingWorker were deferred. The deferred audit event jobs then piled up in the Redis Sidekiq cluster.","ko":"같은 날 앞선 장애 inc-10084 를 완화하려고 감사 이벤트 작업을 지연 처리로 돌려 두었고, 지연된 작업이 Redis Sidekiq 클러스터에 쌓였다."},"severity":"sev1","symptoms":["high-error-rate","memory-pressure","throughput-degraded"],"timeline":{"detected_after":"3m","resolved_after":"1h 31m"},"date_kind":"incident","detection":{"en":"A Prometheus Alertmanager alert reported the incident at 17:15:10 UTC, three minutes after impact began. A follow-up asks why the redis-sidekiq memory alert did not page, and the review says some signals did not reach the right on-call people.","ko":"17:12 UTC 에 영향이 시작됐고 17:15:10 UTC 에 Prometheus Alertmanager 알림이 incident.io 에 장애를 트리아지 상태로 올렸다. 온콜이 17:16:59 UTC 에 Severity 2 로 받아들였고 17:32:49 UTC 에 Severity 1 로 올렸다. redis-sidekiq 메모리 알림은 온콜을 호출하지 않았고, 다른 신호들도 라벨과 라우팅의 틈 때문에 맞는 온콜에게 제대로 닿지 않았다."},"components":["cache"],"root_cause":"capacity","remediation":[{"text":{"en":"Restarted and force-reset the two unresponsive Redis Sidekiq nodes","ko":"응답하지 않는 Redis 노드 두 대를 골라 재시작하고 강제로 리셋했다. 18:00 UTC 에 세 노드가 모두 올라왔고 O2 가 primary 가 됐다."}},{"text":{"en":"Stopped each Redis Sidekiq VM in turn and resized it to c2-standard-16, doubling memory and CPU","ko":"Redis VM 을 한 대씩 멈추고 메모리와 CPU 를 두 배로 늘린 c2-standard-16 머신 타입으로 바꿨다. 18:40 UTC 에 세 노드의 교체가 끝났다."}},{"text":{"en":"Re-enabled AuditEventStreamingWorker instead of deferring it","ko":"AuditEventStreamingWorker 를 다시 켜고 더는 지연 처리로 돌리지 않았다. 앞서 지연시킨 탓인지 이 워커의 대기열이 계속 늘어 지켜봤다."}}],"action_items":[{"text":{"en":"Investigate why the redis-sidekiq memory alert did not page","ko":"redis-sidekiq 메모리 알림이 왜 온콜을 호출하지 않았는지 조사한다."}},{"text":{"en":"Establish the root cause, failure mode and remediation status of the WebHookWorker poison pill","ko":"WebHookWorker poison pill 문제의 근본 원인과 실패 양상, 해결 진행 상황을 정리한다."}},{"text":{"en":"Give mitigations that disable safety limits an explicit owner and a deadline for re-evaluating them","ko":"안전 한도를 끄는 완화 조치에는 담당자와 재검토 기한을 분명히 정하도록 절차를 고친다."}},{"text":{"en":"Stop AuditEvents::AuditEventStreamingWorker from causing recurring incidents","ko":"AuditEvents::AuditEventStreamingWorker 가 장애를 되풀이해 일으키지 않도록 고친다."}},{"text":{"en":"Create a runbook for AuditEventStreamingWorker","ko":"AuditEventStreamingWorker 의 런북을 만든다."}},{"text":{"en":"Address PG connection pool saturation","ko":"PG 연결 풀 포화 문제를 후속 작업으로 다룬다."}}],"contributing":["delayed-effect-change","paging-failed","limited-debug-access"],"recurrence_of":null,"symptoms_text":{"en":"From 17:12 UTC on 12 May 2026, error rates rose at the same time across GitLab.com's web, Git, API and CI runner services. Users got frequent 500 errors, failed or stuck CI pipelines, authentication failures and unreliable Git access, and a Prometheus Alertmanager alert opened the incident at 17:15.\n\nThe platform triage dashboard showed many services erroring at once, with CI runners at up to 5% errors and the git workhorse API and the web service also affected. On the Redis Sidekiq hosts of the catchall-b shard, the kernel logged \"INFO: task kcompactd0:67 blocked for more than 120 seconds.\" and the redis-rdb-backup.service unit failed on redis-sidekiq-catchall-b-01-db-gprd. On redis-sidekiq-catchall-b-02-db-gprd, systemd reported \"Found left-over process 2516163 (redis-server) in control group while starting unit\", redis_exporter logged \"Couldn't connect to redis instance (redis://localhost:6379)\", and Teleport logged \"SLOW TRANSACTION\" warnings and name lookups ending in \"i/o timeout\". SSH logins to the hosts hung.\n\nResponders first looked at Redis connectivity, then at evidence that seemed to point to DNS service discovery or a wider disruption in the US East region, and asked for outside DNS expertise. No rollout was running in production; the only recent change was a registry rollout in staging. Request rates on the dashboards were flat or falling, which ruled out a traffic surge.\n\nBy 18:00 the two unresponsive Redis nodes had been restarted and reset, and all three nodes, O1, O2 and O3, were up with O2 as primary, but the nodes started throwing errors again right away. The Sidekiq queue backlog peaked at 12.2 million jobs, pipeline creation stayed near zero for long stretches and pipelines sat stuck in created, with more than 10,000 pipelines estimated to be affected. Responders found the \"Pipelines stuck in created\" symptom hard to measure and confirm while it was happening.","ko":"2026-05-12 17:15 UTC 에 Prometheus Alertmanager 알림으로 장애가 접수됐다. 플랫폼 대시보드에서 web, Git, API, CI 러너, Sidekiq 의 오류율이 한꺼번에 올랐고, 사용자는 잦은 500 오류와 인증 실패, CI 파이프라인 실패를 겪었다.\n\nCI 러너의 오류율은 최대 5% 까지 올랐고 git workhorse API 와 web 서비스도 영향을 받았다. 파이프라인이 created 상태에 멈춰 있었고 파이프라인 생성이 오랫동안 0 에 가깝게 떨어졌다. 엔지니어는 이 증상을 실시간으로 세고 확인하기 어려웠고, 맞는 대시보드와 SLI 를 온콜이 바로 찾지 못했다.\n\nRedis 호스트 redis-sidekiq-catchall-b-01-db-gprd 의 커널 로그에는 \"INFO: task kcompactd0:67 blocked for more than 120 seconds.\" 가 찍혔다. redis-sidekiq-catchall-b-02-db-gprd 에서는 systemd 가 \"redis-server.service: Found left-over process 2516163 (redis-server) in control group while starting unit. Ignoring.\" 을 남겼고, redis_exporter 는 \"Couldn't connect to redis instance (redis://localhost:6379)\" 를 거듭 기록했다. 호스트 자체가 응답하지 않아 SSH 로그인이 멈췄다.\n\n엔지니어는 처음에 Redis 연결 문제를 의심했고, 이어서 DNS 서비스 디스커버리 문제나 US East 리전 전체의 장애일 가능성도 살폈다. 운영 환경에서 진행 중인 롤아웃은 없었고 최근 변경은 스테이징의 레지스트리 관련 롤아웃뿐이었다. 외부 DNS 전문가의 도움도 구했다. 대시보드와 로그에서 초당 요청 수가 평탄하거나 줄고 있음을 보고 트래픽 급증은 원인에서 뺐다.\n\n18:00 UTC 에 Redis 노드 세 대가 모두 다시 올라왔지만 노드들은 곧바로 다시 오류를 냈다. Sidekiq 대기열은 최대 1,220만 개까지 쌓였다."},"updated_at":"2026-11-14T12:33:54.480020Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0290","org_slug":"gitlab"}