{"id":"IL-0318","org":"Clerk","date":"2026-03-10","docs":[],"title":{"en":"Clerk's APIs went down with lock contention and 429s while a Google Cloud SQL live migration slowed its database disk","ko":"Google Cloud SQL 데이터베이스의 디스크 지연이 치솟아 Clerk API 가 429 를 내며 전체 장애가 났다"},"domain":["database","gcp"],"impact":{"scope":"Clerk's APIs: increased latency, 5xx errors and then 429 responses, and a complete service outage; session management kept working from 16:10 UTC through Origin Outage Mode","users":"Clerk customers and the users of their applications","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"Clerk concludes that Cloud SQL live migrations are still unsafe after months of joint work with Google, and that they are opaque, leaving Clerk to trust Google's word. Clerk prefers traditional replica promotion for all Postgres maintenance, an automated process it had already used without incident for a Postgres major version upgrade on January 17, 2026.","ko":"2025년 9월 장애에서 Clerk 는 라이브 마이그레이션이 실패하면 작업이 끝날 때까지 서비스가 멈추고, 마이그레이션 도중 replica 장애 조치를 하는 것도 안전하지 않다는 것을 배웠다. 몇 달에 걸친 Google 과의 작업 뒤에도 이번 장애로 라이브 마이그레이션이 여전히 안전하지 않다는 것이 드러났다. 라이브 마이그레이션은 잘 되면 무중단이지만 안을 들여다볼 수 없어 Google 의 말을 믿는 수밖에 없다. 그래서 Clerk 는 준비가 더 들더라도 기존 방식의 replica 승격에 기대는 편이 더 안전하다고 보았다."},"related":[],"sources":[{"url":"https://clerk.com/blog/2026-03-10-service-outage-postmortem","kind":"blog","archived":"https://web.archive.org/web/20261010193212/https://clerk.com/blog/2026-03-10-service-outage-postmortem"}],"summary":{"en":"Clerk runs Postgres on Google Cloud SQL Enterprise Plus with high availability. Cloud SQL performs live migrations of its virtual machines on a routine basis, without telling Clerk in advance, and when they work they do not affect availability. On 10 March 2026 a live migration did not work as expected: disk latency on Clerk's database rose sharply, lock contention followed, and the service went down completely. Clerk enabled Origin Outage Mode at 16:10 UTC to keep session management working. At 16:23 the problem ended on its own when the migration completed, Clerk turned Origin Outage Mode off shortly after, and GCP later told Clerk the cause.\n\nThis was not the first such failure. In September 2025 a different live migration had caused a major Clerk incident, from which Clerk learned that a failed live migration causes downtime until it completes and that a replica failover during one is unsafe. Google escalated that ticket to P0 and pinned the database to its datacenter so no further live migrations would run. Over the following months, with weekly calls and over 80 Google staff involved, Clerk worked, at Google's guidance, on reducing its average queries per request, introducing Google's managed connection pooler and increasing the Postgres version, while Google looked for the issue in its live migration process. The database was unpinned in January, and the first live migration after that succeeded with both teams on a call.","ko":"Clerk 는 2021년부터 고가용성 구성의 Google Cloud SQL Enterprise Plus 를 데이터베이스로 쓴다. Google Cloud SQL 은 데이터베이스 가상 머신을 일상적으로 라이브 마이그레이션한다. 이 작업은 Cloud SQL 문서에는 없지만 Google Compute Engine 의 라이브 마이그레이션과 비슷하다. 정상으로 끝나면 가용성이나 부하에 영향이 없다. Clerk 는 라이브 마이그레이션이 언제 일어나는지 미리 통보받지 않는다. 2025년 9월에는 다른 라이브 마이그레이션이 큰 장애를 일으켰다. 그때 Google 은 티켓을 P0 로 올리고 데이터베이스를 데이터센터에 고정해 추가 라이브 마이그레이션을 막았다. 두 회사는 몇 달 동안 함께 일한 끝에 1월에 고정을 풀었다. 고정을 푼 뒤 첫 라이브 마이그레이션은 문제없이 끝났다.\n\n2026-03-10 에 라이브 마이그레이션이 다시 실패했다. 데이터베이스의 디스크 지연이 크게 늘었고, 이것이 락 경합을 키워 결국 전체 서비스 장애로 이어졌다. 15:57 UTC 에 알림이 API 의 지연과 5xx 증가를 알렸고 내부에서 사고를 선언했다. 쿼리와 트랜잭션이 오래 걸려 컴퓨트가 포화되자 요청이 429 를 받았고, 자동으로 작동한 세션 장애 대비 기능도 대부분 429 를 냈다. 모든 읽기를 replica 로 돌려 봤지만 소용없었다. 16:10 UTC 에 Origin Outage Mode 를 켜자 세션 관리가 다시 돌아갔다. 팀은 읽기의 IO wait 만 오르는 것을 보고 인프라 문제를 의심해 GCP 에 티켓을 열었다. 16:23 UTC 에 마이그레이션이 끝나며 문제가 스스로 풀렸고, 시스템이 안정된 것을 확인한 뒤 Origin Outage Mode 를 껐다. GCP 가 나중에 근본 원인을 알려 주었다."},"trigger":{"en":"A routine live migration of the Google Cloud SQL virtual machine that hosts Clerk's Postgres database, done without advance notice to Clerk, did not work as intended.","ko":"Google Cloud SQL 이 Clerk 데이터베이스를 호스팅하는 가상 머신을 일상적으로 라이브 마이그레이션하다 실패했다. Clerk 는 라이브 마이그레이션 시점을 미리 통보받지 않는다."},"severity":"unknown","symptoms":["high-latency","high-error-rate","lock-contention","service-unavailable"],"timeline":{"detected_after":"1m","resolved_after":"27m"},"date_kind":"incident","detection":{"en":"Alerting reported increased latency and elevated 5xx errors across the APIs at 15:57 UTC, and monitoring showed lock contention in the database that had begun about a minute earlier.","ko":"15:57 UTC 에 알림 시스템이 API 전반의 지연 증가와 5xx 오류 증가를 알렸고, 이때 내부에서 사고를 선언했다."},"components":["database"],"root_cause":"cloud-provider","remediation":[{"text":{"en":"Enabled Origin Outage Mode to keep session management working","ko":"16:10 UTC 에 Origin Outage Mode 를 켜 세션 관리가 계속 돌아가게 했다."}},{"text":{"en":"Opened a ticket with GCP after seeing elevated IO wait on reads","ko":"읽기의 IO wait 만 오르는 것을 보고 인프라 문제를 의심해 GCP 에 티켓을 열었다."}},{"text":{"en":"Disabled Origin Outage Mode after the live migration completed and the system stabilised","ko":"16:23 UTC 에 문제가 스스로 풀리고 시스템이 안정된 것을 확인한 뒤 곧 Origin Outage Mode 를 껐다."}}],"action_items":[{"text":{"en":"Ask Google to pin the database again to stop further live migrations","ko":"추가 라이브 마이그레이션을 막도록 Google 에 데이터베이스를 다시 고정해 달라고 요청했다. 글을 쓸 때까지 요청은 받아들여지지 않았다."}},{"text":{"en":"Use replica promotion instead of live migrations for all Postgres database maintenance","ko":"앞으로 모든 Postgres 데이터베이스 유지 보수는 기존 방식의 replica 승격으로 한다. Clerk 는 이미 안전하고 빠른 replica 승격 자동화를 갖고 있고, 2026-01-17 Postgres 메이저 버전 업그레이드에 문제없이 썼다."}},{"text":{"en":"Move to another database provider or run Postgres in-house unless Google offers a way to disable live migrations permanently","ko":"Google 이 라이브 마이그레이션을 영구히 끌 방법을 주지 않으면 다른 데이터베이스 제공업체로 옮기거나 Postgres 를 직접 운영한다. 지금 선택지를 조사하고 있다."}},{"text":{"en":"Return 500 instead of the internal service's 429 so applications can tell the state of Clerk's systems from the error code","ko":"내부 서비스의 429 가 그대로 전달되지 않고 500 으로 바뀌게 고쳐, 애플리케이션이 오류 코드로 Clerk 시스템의 상태를 정확히 판단하게 한다."}},{"text":{"en":"Shift most of the engineering team to reliability-focused projects","ko":"엔지니어링 팀 대부분을 안정성 중심 프로젝트로 옮겼고, 당분간 시스템 안정성 회복을 가장 앞에 둔다."}}],"contributing":["limited-debug-access"],"recurrence_of":null,"symptoms_text":{"en":"At 15:57 UTC on 10 March 2026, Clerk's alerting reported increased latency and elevated 5xx errors across its APIs, and the incident was declared. Monitoring showed increased lock contention in the database, which had started about a minute earlier.\n\nThe database stayed up with CPU usage within normal limits, but queries and transactions took far longer to complete, which saturated Clerk's compute resources, and incoming requests began returning 429. Session outage resiliency triggered automatically at origin to keep serving session token requests, but because compute was already saturated most of those requests got 429 as well. The 429 came straight from an internal service instead of being turned into a 500.\n\nThere was no clear cause at first. Moving all reads to the replicas to relieve the primary did not help. During the investigation the team saw elevated IO wait on reads without a matching increase in writes, suspected an infrastructure problem and opened a ticket with GCP.","ko":"2026-03-10 15:57 UTC 에 알림 시스템이 Clerk API 전반의 지연 증가와 5xx 오류 증가를 알렸다. 모니터링에는 그보다 1분쯤 앞서 시작된 데이터베이스 락 경합 증가가 보였다.\n\n데이터베이스 CPU 사용률은 정상 범위였고 데이터베이스 자체도 돌아가고 있었다. 그러나 쿼리와 트랜잭션이 훨씬 오래 걸려 컴퓨트 자원이 포화됐고, 컴퓨트가 바닥나자 들어오는 요청이 429 를 받았다.\n\n세션 장애 대비 기능이 origin 에서 자동으로 작동해 세션 토큰 요청을 계속 받았다. 그러나 컴퓨트가 이미 포화돼 처리가 너무 오래 걸렸고, 세션 토큰 요청도 대부분 429 를 받았다. 이 429 는 내부 서비스가 낸 응답이 500 으로 바뀌지 않고 그대로 전달된 것이었다.\n\n조사 중 읽기의 IO wait 가 올랐는데 쓰기는 그만큼 늘지 않은 특이한 모습이 보였다. 팀은 이때 인프라 문제를 의심해 GCP 에 티켓을 열었다.\n\n팀은 원인을 찾아 나섰지만 뚜렷한 단서가 없었다. 완화책으로 모든 읽기를 replica 로 돌려 primary 데이터베이스의 부담을 덜려 했지만 소용없었다."},"updated_at":"2026-11-14T12:33:57.185572Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0318","org_slug":"clerk"}