개발자들은 갓 출시한 앱이 수천 명의 사용자가 접속하는 순간 멈춰버리는 것을 지켜보게 됩니다. 이러한 속도 저하는 코드의 버그 때문인 경우가 드뭅니다. 서버의 CPU와 RAM이 자원을 차지하기 위해 싸우고 있기 때문입니다. 병목 현상은 페이지 로딩 지연, 타임아웃 또는 아예 앱이 다운되는 현상으로 나타나며, 이는 사용자 경험, 매출, 그리고 브랜드 신뢰도를 해칩니다.

실험실에서는 잘 돌아가던 서버가 운영 환경에서 멈춰버리는 이유

개발 단계에서는 개발자 한 명이 소수의 요청만 보내기 때문에 서버 자원은 대부분 유휴 상태로 유지됩니다. 하지만 앱이 라이브로 전환되면, 모든 방문자가 두 가지 핵심 요소가 필요한 요청을 생성합니다.

  • CPU (중앙 처리 장치) – 모든 루프, 함수, 계산을 실행하는 프로세서입니다. 한 번에 요리할 수 있는 양이 정해져 있는 요리사라고 생각하면 쉽습니다. 주문 하나는 즉시 처리되지만, 주문이 백 개가 되면 요리사의 작업 속도는 그대로일지라도 손님들은 더 오래 기다려야 합니다.
  • RAM (랜덤 액세스 메모리) – 요청을 처리하는 동안 CPU가 필요로 하는 데이터를 담아두는 임시 저장 공간입니다. 요리사가 각 요리에 필요한 재료를 올려두는 조리대와 같습니다. 조리대가 가득 차면, 공간이 확보될 때까지 요리사는 새로운 주문을 받을 수 없습니다.

수천 명의 사용자가 동시에 로그인하면, 각 요청은 자신만의 CPU 시간과 RAM 공간을 점유합니다. 서버의 한정된 자원 풀이 요청들 사이에서 나누어지면서 대기열이 길어집니다. 서버 자체가 느려진 것이 아니라, 각 요청에 대한 대기 시간이 늘어난 것입니다.

“그냥 더 큰 서버를 사면 되지”라는 유혹

가장 흔한 첫 번째 반응은 기계를 업그레이드하는 것입니다. 이를 **수직적 확장(vertical scaling)**이라고 합니다. CPU 코어를 늘리거나 RAM을 추가하면 용량을 개선할 수 있습니다. 예를 들어 4코어에서 16코어로, 또는 8GB에서 64GB로 업그레이드하면 코드 수정 없이도 더 큰 트래픽 급증을 수용할 수 있습니다.

하지만 수직적 확장은 명확한 한계에 부딪힙니다.

  • 물리적 한계 – 모든 메인보드는 수용할 수 있는 코어의 수와 메모리 양이 정해져 있습니다.
  • 수익 체감 – 코어나 기가바이트를 추가할수록 이전보다 더 많은 비용이 들지만, 성능 향상 폭은 점점 줄어듭니다.
  • 단일 장애점(Single point of failure) – 만약 거대한 서버 하나가 다운되면, 전체 서비스가 중단됩니다.

이러한 제약 때문에 스트리밍 플랫폼, 검색 엔진, 이커머스 사이트와 같은 업계의 거물들은 단일 대형 서버 방식에서 벗어났습니다.

대안: 여러 대의 작은 서버로 부하 분산하기

더 높은 탑을 쌓는 대신, 운영자는 적당한 크기의 서버를 여러 대 추가하여 트래픽을 나누어 처리하게 합니다. 이러한 수평적 확장(horizontal scaling) 방식은 각 서버를 안정적인 성능 범위 내에서 유지하며, 수직적 업그레이드 시 발생하는 기하급수적인 비용 곡선을 피할 수 있게 해줍니다.

여러 대의 머신을 조정하려면 **로드 밸런서(load balancer)**가 필요합니다. 로드 밸런서는 모든 들어오는 요청을 받아 가용 용량이 가장 많은 서버로 전달하는 소프트웨어 또는 하드웨어입니다. 로드 밸런서는 클라이언트로부터 복잡성을 숨겨줍니다. 사용자 입장에서는 사이트가 여전히 하나의 엔드포인트처럼 보입니다.

수평적 확장은 회복 탄력성(resilience)도 제공합니다. 하나의 노드가 다운되더라도 로드 밸런서는 단순히 트래픽을 나머지 정상적인 노드로 라우팅하여 서비스를 계속 유지합니다.

서버를 추가하기 시작할 때 주의할 점

  • 무상태 설계(Stateless design) – 요청이 특정 서버의 메모리에만 저장된 데이터에 의존해서는 안 됩니다. 그렇지 않으면 사용자가 필요한 컨텍스트가 없는 노드로 연결될 수 있습니다. 공유 캐시나 데이터베이스를 사용하면 이 문제를 해결할 수 있습니다.
  • 상태 확인(Health checks) – 로드 밸런서는 장애가 발생한 서버를 빠르게 감지하고 해당 서버로 트래픽을 보내는 것을 중단할 수 있어야 합니다.
  • 오토스케일링 정책(Auto-scaling policies) – 많은 클라우드 플랫폼에서는 임계값(CPU 사용률, 요청 지연 시간 등)을 정의하여 인스턴스를 자동으로 생성하거나 종료할 수 있게 해주며, 이를 통해 비용을 수요에 맞게 조절할 수 있습니다.

반론: 수직적 확장이 완전히 사라진 것은 아니다

소규모 팀이나 트래픽이 적은 앱의 경우, 성능을 강화한 단일 서버가 가장 간단하고 저렴한 해결책이 될 수 있습니다. 트래픽 급증이 예측 가능하다면(예: 예정된 제품 출시), 새로운 인스턴스 군단을 구축하는 것보다 일시적인 수직적 업그레이드가 더 실용적일 수 있습니다.

핵심은 “더 큰 서버” 방식이 더 이상 비례하는 가치를 제공하지 못하는 시점을 파악하고, 분산 처리를 위한 계획을 세우기 시작하는 것입니다.

요약

출시 후 서버 속도가 느려지는 현상은 대개 코드 결함이 아니라 리소스 경합(resource-contention) 문제입니다. CPU 사이클과 RAM 슬롯은 한정되어 있으며, 많은 요청이 동시에 들어오면 대기열이 형성되어 응답 시간이 길어집니다. 수직적 확장(Vertical scaling)은 어느 정도 여유 공간을 확보해 주지만, 곧 물리적 및 경제적 한계에 부딪히게 됩니다. 로드 밸런서 뒤에 더 적절한 규모의 서버를 추가하는 수평적 확장(Horizontal scaling)은 트래픽이 증가함에 따라 더 저렴하고 탄력적인 경로를 제공합니다. 대기열이 길어지는 것을 감지하는 순간, 코어를 몇 개 더 추가하는 것으로 충분할지, 아니면 여러 대의 머신으로 부하를 분산하기 시작해야 할지 평가해야 할 시점입니다.

출처: dev.to 기사 “Why Servers Slow Down – CPU, RAM and the hidden cost of every request.”