100만 사용자가 정말 동시에 접속할까?
회원 100만 명과 동시 접속자 100만 명은 완전히 다르다. MAU, DAU, CCU, RPS를 학교 축제 매점 이야기와 간단한 계산으로 이해한다.
대용량 트래픽 시리즈 1/7
서비스는 어떻게 100만 사용자를 버틸까? — 대용량 트래픽과 데이터베이스를 공부하며 이해한 것들
학교 축제에 학생 1,000명이 왔다고 생각해 보겠습니다. 그렇다고 학생 1,000명이 동시에 매점 계산대 앞에 서지는 않습니다.
어떤 학생은 운동장에서 공연을 봅니다. 어떤 학생은 교실에서 체험 활동을 하고, 일부만 매점에 옵니다. 매점에 온 학생도 모두 같은 순간에 주문하지는 않습니다.
인터넷 서비스도 비슷합니다. 회원이 100만 명이라는 말만으로는 서버가 얼마나 바쁜지 알 수 없습니다.
회원 수와 같은 순간에 들어오는 요청 수는 서로 다른 숫자입니다.
이 글은 2026년 1월 대용량 트래픽과 데이터베이스를 공부하며 이해한 내용을 제 언어로 다시 정리한 기록입니다. 강의와 기술 자료를 통해 원리를 학습한 것이며, 제가 실제로 100만 사용자 서비스를 운영했다는 뜻은 아닙니다.
‘100만 사용자’에는 여러 의미가 있다
“사용자가 100만 명이다”라는 문장에는 중요한 시간이 빠져 있습니다. 가입한 사람을 모두 센 것인지, 이번 달에 방문한 사람을 센 것인지에 따라 서버가 받는 부담은 완전히 달라집니다.
먼저 전체 회원 수는 지금까지 가입한 계정의 수입니다. 이미 서비스를 떠난 사람과 이번 달에는 방문하지 않은 사람도 포함될 수 있습니다. 데이터베이스에 저장할 회원 정보의 규모를 짐작하는 데는 도움이 되지만, 오늘 서버가 얼마나 바쁜지는 알려주지 않습니다.
MAU(Monthly Active Users, 월간 활성 사용자)는 한 달 동안 서비스를 실제로 이용한 사용자의 수입니다. 여기서 “이용했다”의 기준은 로그인, 글 읽기, 구매처럼 서비스가 정한 행동에 따라 달라집니다. MAU는 서비스의 월간 규모를 보여주지만 특정 하루의 혼잡함은 숨길 수 있습니다.
DAU(Daily Active Users, 일간 활성 사용자)는 하루 동안 서비스를 이용한 사용자의 수입니다. MAU가 같아도 매일 고르게 방문하는 서비스와 주말에만 몰리는 서비스의 DAU는 다를 수 있습니다.
CCU(Concurrent Users, 동시 접속 사용자)는 특정 순간에 함께 접속해 있는 사용자의 수입니다. 다만 접속의 기준을 단순 로그인 상태로 볼지, 최근 몇 분 안에 행동한 사람으로 볼지는 서비스가 분명하게 정해야 합니다. 접속 중인 사용자가 아무 행동도 하지 않는다면 서버에 새 요청을 보내지 않을 수도 있습니다.
마지막으로 RPS(Requests Per Second, 초당 요청 수)는 1초 동안 서버로 들어온 요청의 수입니다. 서버 용량을 생각할 때는 전체 회원 수보다 이 숫자가 실제 작업량에 더 가깝습니다.
모든 숫자는 원리를 이해하기 위한 가정입니다. 마지막 단계는 사용자 수가 아니라 10분 동안 발생한 요청을 초당 평균으로 바꾼 값입니다.
숫자는 보통 전체 회원에서 월간 사용자, 일간 사용자, 동시 사용자로 갈수록 작아집니다. 그러나 마지막의 RPS는 사람 수가 아니라 요청 수이므로 단순히 같은 단위의 숫자를 줄여 쓴 것이 아닙니다.
서버가 실제로 받는 것은 사람이 아니라 요청이다
학교 매점의 계산대는 학생의 이름을 처리하지 않습니다. 주문 한 건마다 상품을 확인하고 금액을 계산하며 결제를 처리합니다. 서버도 접속한 사람 그 자체가 아니라 그 사람이 보낸 요청을 처리합니다.
사용자 한 명이 게시글 화면 하나를 열었다고 해보겠습니다. 로그인 상태를 확인하고, 게시글 내용을 가져오고, 댓글과 작성자 정보를 불러오는 요청이 따로 생길 수 있습니다. 이미지와 글꼴도 내려받아야 하지만, 구성에 따라 이런 파일은 애플리케이션 서버가 아니라 별도의 저장소나 전송망이 처리하기도 합니다.
반대로 사용자가 화면을 읽는 동안에는 접속 상태여도 새 요청을 거의 보내지 않을 수 있습니다. 그래서 CCU만 알아서는 서버가 해야 할 일을 정확히 계산할 수 없습니다.
한 사람이 일정 시간에 몇 번의 요청을 보내는지까지 알아야 RPS를 구할 수 있습니다. 같은 CCU라도 실시간 게임, 동영상 댓글, 한 번 열고 오래 읽는 글 서비스의 RPS는 크게 다릅니다.
이해를 위한 간단한 계산
이제 실제 서비스 측정값이 아닌 이해를 위한 가정으로 계산해 보겠습니다.
- 전체 회원은 1,000,000명입니다.
- 하루 동안 방문하는 사람은 100,000명입니다.
- 가장 붐비는 10분 동안 10,000명이 방문합니다.
- 한 사람이 그 10분 동안 평균 6개의 요청을 만듭니다.
먼저 10분 동안 발생한 전체 요청을 구합니다.
10,000명 × 6개 요청 = 60,000개 요청
10분은 600초이므로 이를 다시 초로 나눕니다.
60,000개 요청 ÷ 600초 = 평균 100 RPS
산술상 10,000에 6을 곱하면 60,000이고, 이를 600으로 나누면 100입니다. 이 가정에서 회원 100만 명인 서비스가 매초 100만 요청을 받는 것은 아닙니다.
하지만 평균 100 RPS가 매초 정확히 100개씩 들어온다는 뜻도 아닙니다. 어느 1초에는 40개가 들어오고, 다음 1초에는 300개가 몰릴 수 있습니다. 이렇게 짧은 시간에 요청이 몰리는 현상을 버스트(Burst)라고 부릅니다.
평균만 보면 위험한 이유
축제 매점은 하루 평균 손님 수가 많지 않아도 쉬는 시간이 되면 갑자기 줄이 길어집니다. 서비스도 출근 시간, 티켓 판매 시작, 알림 발송 직후처럼 특정 순간에 요청이 집중됩니다.
그래서 평균 RPS 하나만 보고 서버 크기를 정하면 가장 바쁜 순간에 느려질 수 있습니다. 최소한 다음 조건을 함께 확인해야 합니다.
- 최대 RPS는 가장 붐비는 짧은 구간에 실제로 몇 개의 요청이 들어오는지 보여줍니다. 평균이 같아도 최대값이 높으면 순간적인 대기열이 길어질 수 있습니다.
- 읽기와 쓰기의 비율은 데이터를 보기만 하는 요청과 새로 저장하거나 바꾸는 요청의 비율입니다. 쓰기는 충돌을 막고 저장 결과를 확인해야 하므로 읽기와 부담이 다를 수 있습니다.
- 요청 하나의 처리 시간이 길면 같은 수의 요청도 서버 자리를 더 오래 차지합니다. 계산이 복잡하거나 기다림이 길수록 다음 요청이 줄을 서게 됩니다.
- 데이터 크기가 크면 네트워크로 옮기고 메모리에 담는 비용이 늘어납니다. 요청 수가 같아도 작은 글 목록과 큰 동영상 파일의 부담은 같지 않습니다.
- 데이터베이스 쿼리 수가 많으면 화면 한 번을 열 때 데이터베이스가 여러 차례 일해야 합니다. 불필요한 조회가 반복되면 애플리케이션 서버보다 데이터베이스가 먼저 느려질 수 있습니다.
- 외부 시스템 호출 여부는 결제나 문자 발송처럼 다른 서비스의 응답을 기다리는지를 뜻합니다. 외부 시스템이 느리거나 실패하면 내 서버의 요청도 함께 오래 머물 수 있습니다.
- 오류율은 전체 요청 중 실패한 비율입니다. 응답이 빨라도 많은 요청을 버리고 있다면 트래픽을 제대로 처리했다고 말할 수 없습니다.
이 조건들은 “서버가 몇 대 필요한가?”보다 먼저 물어야 할 질문입니다. 같은 100 RPS라도 단순 조회 100건과 결제·재고 변경 100건은 필요한 자원이 다릅니다.
‘100만 사용자를 견딘다’고 말하려면 무엇이 필요할까?
“이 서버는 100만 사용자를 처리할 수 있습니다”라는 문장은 그럴듯하지만 확인할 방법이 없습니다. 100만 명이 가입했다는 뜻인지, 동시에 접속했다는 뜻인지, 1초 동안 요청을 보냈다는 뜻인지 알 수 없기 때문입니다.
검증 가능한 설명으로 바꾸려면 적어도 다음 조건이 필요합니다.
- 전체 회원, DAU, CCU 중 어떤 사용자 수를 말하는지 밝혀야 합니다.
- 시험 중 평균과 최대 RPS가 얼마였는지 알려야 합니다.
- 로그인, 글 조회, 주문처럼 어떤 기능을 시험했는지 설명해야 합니다.
- 사용자가 기다려도 된다고 정한 응답시간을 공개해야 합니다.
- 성공한 요청뿐 아니라 오류가 얼마나 발생했는지도 보여줘야 합니다.
- 서버 수와 사양, 데이터베이스 종류와 크기 같은 시험 환경을 기록해야 합니다.
이런 조건을 고정한 뒤 부하 테스트를 해야 서로 다른 설계를 비교할 수 있습니다. 큰 회원 수를 적는 것만으로는 데이터베이스가 버텼는지, 응답이 제시간에 왔는지, 요청이 중간에 사라지지 않았는지 증명할 수 없습니다.
저 역시 이 글에서 100만 사용자 운영 능력을 증명하려는 것이 아닙니다. 공부한 원리를 바탕으로 어떤 숫자를 구분하고 무엇을 측정해야 하는지 정리한 것입니다.
숫자보다 측정 조건을 먼저 보자
핵심은 세 줄로 정리할 수 있습니다.
- 전체 회원 수와 동시 접속자 수는 다릅니다.
- 서버는 사용자가 아니라 사용자가 발생시키는 요청을 처리합니다.
- 대용량을 증명하려면 RPS, 응답시간, 오류율과 테스트 환경을 함께 공개해야 합니다.
회원 수 100만 명과 동시 접속자 100만 명은 완전히 다른 말입니다. 서버 용량은 전체 회원 수가 아니라 특정 시간에 들어오는 요청의 양과 요청 하나를 처리하는 비용을 기준으로 설계해야 합니다.
그렇다면 요청이 실제로 몰리기 시작할 때 서버에서는 어디가 가장 먼저 느려질까요?
이 시리즈의 다음 글
사용자 요청이 서버와 데이터베이스를 통과하는 길을 따라가며 병목이 생기는 지점을 살펴봅니다.