무료 플랜 4개를 조합했더니 어느 날 데이터 312건이 사라졌다
3월 11일 오전 11시 22분, 슬랙 알림 하나가 왔다. "최근 7일 신규 등록 0건." 버그인 줄 알았는데 버그가 아니었다. 데이터베이스 테이블이 통째로 비어 있었다.
그 전까지는 꽤 잘 굴러가고 있었다
편의점 1+1 행사 앱, 이제 20편째다. 19편까지 이어온 흐름 중에서 제일 창피한 이야기를 오늘 꺼낸다.
앱을 처음 올릴 때 목표가 하나였다. “유료 플랜은 손익분기점 이후에.” 그래서 무료 tier를 퍼즐처럼 끼워 맞췄다.
- DB 호스팅: A 서비스 무료 플랜 (행 500개 제한)
- 백엔드 함수: B 서비스 무료 플랜 (월 10만 호출)
- 스케줄러: C 서비스 무료 플랜 (일 100건 작업)
- 이미지 스토리지: D 서비스 무료 플랜 (월 5GB)
네 개를 붙여놓으니 그럴듯하게 돌아갔다. 2개월 동안 서버비 $0. 자랑스러웠다.
무료 플랜 네 개를 이어 붙인 건 스택이 아니라 시한폭탄이었다.
사고가 터진 날의 타임라인
A 서비스 무료 플랜에는 “행 500개 초과 시 오래된 데이터 자동 삭제” 정책이 있었다. 저는 그걸 읽었는데 안 읽은 척한 거나 다름없었어요. ‘어차피 금방 유료로 올리겠지’ 하면서.
3월 10일 자정, 누적 행이 501번째를 넘었다. A 서비스 내부 정리 작업이 돌았고, 오래된 행부터 312건을 지웠다. 알림? 없었다. 메일? 없었다. 대시보드에 조그만 배너가 하나 떴다는데 저는 그날 대시보드를 열지 않았다.
발견까지 11시간 22분 걸렸다. 슬랙 알림이 없었으면 더 걸렸을 거다.
복구 시도: 7번 중 2번만 성공
A 서비스 무료 플랜에는 백업이 없다. 유료 플랜($25/월)부터 일별 스냅샷이 생긴다.
그래서 다른 곳을 뒤졌다.
- B 서비스 함수 로그 → 호출 기록은 있는데 페이로드가 잘려 있었다. 무료 플랜은 로그 보존이 3일.
- C 서비스 스케줄러 실행 이력 → 작업 성공/실패 여부만, 데이터 내용 없음.
- 제 로컬 노트앱에 복붙해둔 초기 테스트 데이터 → 38건 복구 성공.
- 구글 스프레드시트에 수동으로 옮겨둔 1월분 스냅샷 → 51건 복구 성공.
- 나머지 223건 → 영구 소실.
7번의 복구 시도 중 실제로 데이터를 살린 건 2번. 복구율 28%.
백업 없는 무료 플랜에서 "나중에 옮기지 뭐"는 데이터 소실 동의서와 같다.
사라진 건 데이터만이 아니었다
312건 중에는 사용자 직접 입력 데이터가 섞여 있었다. 앱 특성상 개인정보는 없었지만, 사용자가 직접 등록한 ‘즐겨찾기 매장’ 목록이었다. 그걸 그냥 날렸다.
공지를 올렸다. “시스템 오류로 일부 데이터가 초기화됐습니다.” 그날 탈퇴가 평소의 4배였다.
MAU 기준으로 약 12%가 그 주에 이탈했다. 수치로 보니까 더 아팠다.
결국 쓴 돈
사고 당일 오후에 카드를 꺼냈다.
- A 서비스 유료 전환: $25/월 (일별 백업 포함)
- B 서비스 로그 플랜 업그레이드: $0 → $9/월 (30일 보존)
- C 서비스는 같은 기능 오픈소스로 셀프호스팅 전환: 서버비 포함 월 $6 추가
한 달 추가 비용 $40. 2개월 동안 아낀 돈이 $0이었으니, 결국 이 사고 하나로 그 ‘절약’이 전부 날아갔고 MAU까지 깎였다.
무료 플랜을 쓰는 비용은 돈이 아니라 리스크로 청구된다. 그리고 청구서는 예고 없이 온다.
지금은 어떻게 바꿨냐면
지금 스택은 단순하게 바꿨다. 유료 하나, 셀프호스팅 하나, 무료는 사라져도 괜찮은 것만.
기준이 생겼어요. 무료 플랜을 써도 되는 경우는 딱 하나예요. “이게 사라져도 앱이 그냥 돌아갈 수 있을 때.” 사용자 데이터가 거기 있으면 안 된다는 걸, 312건 잃고 나서야 몸에 새겼다.
무료 플랜 조합은 비용을 0으로 만드는 게 아니라, 비용 청구 시점을 데이터 소실로 미루는 것이다.