“앱이 자꾸 느려져요.” 사용자가 이렇게 느끼는 순간이면 이미 늦은 경우가 많습니다. 매일 5만 명이 쓰는 앱을 몇 년째 굴리면서 배운 건 하나입니다. 안정성은 사고가 났을 때 잘 대응하는 게 아니라, 사고가 나기 전에 준비를 끝내두는 일이라는 것.
트래픽은 평평하게 오지 않습니다
사용자는 하루 종일 고르게 들어오지 않습니다. 출근길, 점심시간, 퇴근 후. 이 세 구간에 확 몰립니다. 리워드 앱은 특히 심합니다. 미션이 새로 열리는 시각에 사람이 한꺼번에 들어옵니다.
평균 접속자 수를 기준으로 서버를 준비하면 반드시 터집니다. 기준은 “가장 붐빌 때”여야 합니다. 저희는 평소의 열 배가 순간적으로 들어와도 버티는 걸 목표로 잡습니다.
서버는 평균이 아니라 피크를 기준으로 준비해야 합니다.
준비 1. 자동으로 늘어나게
사용자가 늘면 서버도 늘어나야 합니다. 사람이 지켜보다가 손으로 켜는 방식으로는 새벽에 몰리는 트래픽을 못 막습니다.
저희는 AWS 위에서 서버를 자동으로 늘리고 줄입니다. 접속이 늘면 자동으로 서버가 붙고, 한산해지면 다시 줄어듭니다. 늘 크게 잡아두면 비용이 아깝고, 작게 잡아두면 터집니다. 자동으로 움직이게 만드는 게 결국 가장 쌉니다.
준비 2. 같은 걸 두 번 계산하지 않기
앱을 열면 대부분의 사용자가 같은 화면을 봅니다. 홈 화면의 미션 목록, 배너, 공지 같은 것들입니다. 이걸 매번 데이터베이스에서 새로 꺼내면 사람이 몰릴수록 데이터베이스가 먼저 주저앉습니다.
그래서 자주 쓰는 데이터는 미리 만들어 캐시에 넣어둡니다. ElastiCache를 쓰고 있습니다. 이 하나만 제대로 걸어도 데이터베이스 부하가 눈에 띄게 떨어집니다.
포인트는 “무엇을 캐시할지”보다 “언제 지울지”입니다. 미션이 마감됐는데 캐시에는 아직 열려 있으면, 사용자는 없는 미션을 누르게 됩니다. 데이터가 바뀌는 순간 캐시도 같이 정리되도록 짜야 합니다.

준비 3. 지켜보고 있기
응답 속도, 오류 수, 데이터베이스 연결 수를 계속 봅니다. 중요한 건 숫자를 모으는 게 아니라 이상할 때 알림이 오게 하는 것입니다.
- 응답 속도가 평소보다 느려지면 알림
- 오류 비율이 올라가면 알림
- 데이터베이스 연결이 한계에 가까워지면 알림
사용자가 “느려요”라고 말하기 전에 저희가 먼저 아는 상태. 이게 목표입니다.

그래도 터질 때가 있습니다
준비를 아무리 해도 예상 못 한 일은 생깁니다. 외부 서비스가 멈추거나, 특정 이벤트에 사람이 예상의 몇 배로 몰리거나.
그때 중요한 건 두 가지입니다. 첫째, 전체가 아니라 문제가 난 기능만 잠시 끌 수 있어야 합니다. 둘째, 원인을 빨리 찾을 수 있게 로그가 남아 있어야 합니다.
기능을 서버에서 켜고 끌 수 있게 만들어 두면, 앱을 새로 올리지 않고도 불을 끌 수 있습니다. 이 스위치 하나가 새벽에 잠을 지켜줍니다.
정리
- 피크를 기준으로 준비합니다.
- 서버는 자동으로 늘고 줄게 만듭니다.
- 자주 쓰는 데이터는 캐시로 막고, 지우는 시점을 정확히 잡습니다.
- 숫자를 모으는 데서 그치지 말고 알림까지 연결합니다.
- 문제가 난 기능만 따로 끌 수 있게 해둡니다.
버프는 앱을 만들고 끝내지 않습니다. 매일 5만 명이 쓰는 서비스를 직접 운영하면서 배운 것들이라, 남의 이야기가 아닙니다.
