![[실전 커뮤니티 06] 무엇을 언제 알릴까](https://img.thenullpage.com/posts/5727/5727_1_5d7634.webp)
지난 편에서 목록을 신선하고 공정하게 정렬하는 이야기를 했다. 이제 떠난 사람을 다시 불러들일 차례다. 내 글에 댓글이 달렸다고, 내 댓글에 답이 왔다고 알려주는 알림이 그 열쇠다. 이번 편은 알림 시스템, 그중에서도 무엇을 언제 알릴 것인가라는 가장 중요한 질문에 대한 내 설계 기록이다.
1. 알림은 재방문의 엔진이다
커뮤니티가 성장하려면 사람들이 반복해서 돌아와야 한다. 그런데 사람들은 바쁘고, 우리 커뮤니티는 그들의 하루에서 아주 작은 조각이다. 가만히 두면 잊힌다. 알림은 그렇게 잊혀가는 사람의 소매를 살짝 잡아당기는 장치다. 당신이 남긴 흔적에 반응이 왔다고 알려주는 순간, 사람은 무슨 일인지 궁금해서 다시 들어온다. 알림은 재방문을 만드는 가장 강력한 엔진이었다.
첫 편에서 말한 무응답의 공포를 기억할 것이다. 알림은 그 공포의 반대편에 있는 희망이다. 내 글에 누가 답했다는 알림 하나가, 이 공간이 나를 기억하고 있다는 증거가 된다. 특히 초기 커뮤니티에서는 이 신호가 결정적이었다. 어렵게 첫 글을 쓴 사람에게 반응 알림이 도착하면, 그 사람은 커뮤니티에 정서적으로 묶인다. 알림은 관계를 만드는 끈이었다.
그래서 나는 알림을 부수 기능이 아니라 핵심 기능으로 대했다. 하지만 동시에 알림은 가장 위험한 기능이기도 했다. 잘 쓰면 사람을 부르지만, 잘못 쓰면 사람을 내쫓는다. 쓸데없는 알림이 쏟아지면 사람들은 알림을 꺼버리고, 한번 꺼진 알림은 다시 켜지지 않는다. 알림은 신뢰를 담보로 한 외줄 타기였다.
이 양면성 때문에 알림 설계의 본질은 기술이 아니라 절제였다. 무엇을 보낼 수 있느냐가 아니라 무엇을 보내지 않을 것이냐가 더 중요한 질문이었다. 나는 알림 하나를 추가할 때마다 이걸 정말 보내야 하는가를 스스로에게 물었다. 보낼 수 있는 모든 것을 보내는 순간, 알림은 소음이 되고 소음은 이탈을 부른다.
2. 무엇을 알릴 것인가
알림의 종류를 정리하며 나는 크게 세 갈래로 나눴다. 첫째는 나와 직접 관련된 반응이다. 내 글에 달린 댓글, 내 댓글에 달린 답글, 내 글이 받은 추천 같은 것들이다. 이건 사용자가 가장 궁금해하고 가장 반가워하는 알림이다. 둘째는 관계 기반 알림이다. 내가 팔로우한 사람의 새 글이나, 내가 참여한 대화의 새 소식 같은 것이다. 셋째는 운영 알림, 즉 공지나 제재 안내다.
이 중 우선순위가 가장 높은 것은 단연 첫째였다. 나와 직접 관련된 반응은 거의 항상 반가운 소식이라, 보내도 사용자가 싫어하지 않는다. 그래서 나는 여기에 집중했다. 개념적으로는 어떤 행동이 특정 사용자를 대상으로 삼을 때, 그 대상에게 알림 한 건을 생성하는 구조였다. 남이 내 것을 건드렸을 때만 알린다는 단순한 원칙이 대부분의 경우를 깔끔하게 커버했다.
반대로 나는 보내지 않기로 한 것도 많았다. 내가 쓴 글에 대한 조회 수가 올랐다는 알림, 커뮤니티 어딘가에 새 글이 올라왔다는 알림, 오랜만에 들어오라는 재촉성 알림 같은 것들이다. 이런 것들은 사용자에게 별 가치가 없으면서 알림 개수만 부풀린다. 알림 목록에 쓸모없는 것이 하나 섞이면, 진짜 중요한 알림의 신뢰도까지 떨어진다.
가장 조심한 것은 내가 한 행동에 대한 알림이었다. 사람들은 자기가 방금 한 일을 알림으로 다시 받는 걸 싫어한다. 그래서 나는 알림을 만들 때 행동의 주체와 알림의 대상이 같으면 알림을 만들지 않도록 했다. 내가 내 글에 댓글을 달았다고 나에게 알림이 가면 그건 소음일 뿐이다. 이 작은 예외 처리 하나가 알림의 품질을 크게 높였다.
3. 언제 알릴 것인가
무엇을 알릴지 못지않게 언제 알릴지가 중요했다. 반응이 생기는 즉시 알리는 실시간 방식은 반가움이 크지만, 알림이 자주 쏟아지면 피로해진다. 인기 글을 쓴 사람은 추천이 하나 붙을 때마다 알림을 받다가는 폭탄을 맞는다. 그래서 나는 알림의 성격에 따라 시점을 달리했다. 답글처럼 즉각성이 중요한 것은 바로 알리고, 추천처럼 누적되는 것은 묶어서 알렸다.
묶어서 알리는 방식은 알림 피로를 줄이는 핵심 기법이었다. 누군가 내 글에 추천을 열 번 눌렀다면, 알림 열 개가 아니라 여러 명이 당신의 글을 추천했다는 알림 하나로 합쳤다. 이렇게 묶으니 알림 개수가 확 줄면서도 정보는 그대로 전달됐다. 개념적으로는 같은 대상에 대한 유사한 알림을 일정 시간 창 안에서 하나로 병합하는 방식이었다.
시간대도 고려 대상이었다. 새벽 세 시에 도착한 알림은 반가움보다 짜증이다. 물론 내 커뮤니티는 별도 앱이 없어 한밤중 진동으로 사람을 깨우는 일은 없었지만, 그래도 알림이 언제 쌓이고 언제 보이는지는 신경 썼다. 사람이 활동하는 시간에 자연스럽게 확인하도록, 알림은 조용히 쌓였다가 사용자가 들어왔을 때 반겨주는 방식이 좋았다.
즉시성과 절제 사이의 균형은 결국 사용자에게 선택권을 주는 것으로 마무리됐다. 어떤 알림을 받을지 사용자가 끄고 켤 수 있게 열어둔 것이다. 다만 기본값은 신중하게 설정했다. 대부분의 사용자는 기본값을 바꾸지 않기에, 기본 상태가 곧 대다수의 경험이었다. 나는 기본을 요란하지 않되 중요한 것은 놓치지 않는 선에 맞췄다.
4. 알림을 세는 배지의 함정
알림 시스템에는 눈에 잘 안 띄는 기술적 함정이 있었다. 바로 안 읽은 알림 개수를 세는 빨간 배지다. 이 숫자는 사용자가 어느 페이지에 있든 화면 구석에 항상 떠 있어야 한다. 즉 모든 페이지를 열 때마다 이 사람의 안 읽은 알림이 몇 개인지를 계산해야 한다. 별것 아닌 듯 보이지만, 방문자가 많아지면 이 계산이 서버를 짓누른다.
나는 이걸 실제로 겪었다. 안 읽은 알림 개수를 세느라 매 페이지 요청마다 데이터베이스가 알림 기록 전체를 훑었다. 방문이 늘자 이 조회가 전체 부하의 상당 부분을 차지했다. 개념적으로는 안 읽음 상태만 걸러 세는 조회가 인덱스를 못 타고 전체를 스캔하는 문제였다. 알림을 보여주기도 전에 알림 개수 세기가 먼저 서비스를 느리게 만든 것이다.
해결책은 안 읽은 것만 빠르게 찾도록 특화된 색인을 만드는 것이었다. 전체 알림이 아니라 안 읽은 알림만 따로 모아 빠르게 셀 수 있게 하니, 부하가 극적으로 줄었다. 조건에 맞는 일부만 담는 부분 색인을 쓴 것이다. 이 최적화로 매 페이지마다 벌어지던 무거운 조회가 거의 사라졌다. 알림 하나 세는 데도 이런 궁리가 필요했다.
이 경험은 앞선 정렬 편의 교훈과 정확히 맞닿아 있었다. 사용자에게 보이는 작은 숫자 하나가, 뒤에서는 성능을 좌우하는 무거운 연산일 수 있다는 것. 알림 설계는 무엇을 언제 알릴지의 판단과, 그걸 어떻게 싸게 계산할지의 기술이 함께 가야 완성됐다. 어느 한쪽만으로는 실제 서비스에서 버티지 못했다.
5. 클릭 이후가 진짜다
알림의 마지막 관문은 사용자가 알림을 눌렀을 때였다. 애써 사람을 다시 불러들였는데, 알림을 눌렀더니 엉뚱한 페이지로 가거나, 정작 그 반응이 어디 있는지 못 찾으면 모든 노력이 헛수고다. 그래서 나는 알림을 누르면 정확히 그 반응이 있는 지점으로 곧장 데려가도록 했다. 내 댓글에 답이 왔다는 알림을 누르면 바로 그 답글 위치로 이동하는 식이었다.
이 정확한 도착지 연결은 생각보다 손이 많이 갔다. 알림에는 어떤 글의 어떤 위치인지를 다시 찾아갈 수 있는 정보가 담겨 있어야 했고, 그 정보로 곧장 해당 지점을 열어줘야 했다. 중간에 한 번 더 클릭하게 하거나 목록에서 다시 찾게 하면, 어렵게 부른 사람이 그새 흥미를 잃는다. 알림의 가치는 클릭 이후의 매끄러움에서 완성됐다.
읽음 처리도 세심하게 다뤘다. 확인한 알림은 조용히 읽음으로 바뀌어 배지 숫자에서 빠져야 하고, 아직 안 본 알림은 남아 있어야 한다. 이 상태 관리가 어긋나면 사용자는 이미 본 알림을 계속 보거나, 못 본 알림을 놓친다. 알림은 생성부터 도착, 확인, 소멸까지 전 생애를 정교하게 관리해야 하는 작은 생명체 같았다.
이번 편에서 무엇을 언제 알릴지를 다뤘다면, 다음 편에서는 알림이 너무 많아질 때의 문제, 즉 알림 피로를 본격적으로 파고든다. 알림을 어떻게 묶고, 다이제스트로 요약하고, 사용자가 통제권을 갖게 할 것인가. 사람을 부르는 알림이 사람을 쫓는 알림으로 변하지 않게 하는 방법을 이어서 이야기하겠다.