한 개발자가 클라이언트 측 폴링(polling) 간격을 30초에서 15분으로 늘려 Neon의 서버리스 데이터베이스 컴퓨팅 비용을 절감했습니다. 폴링 간격을 늘리면 데이터베이스가 충분히 유휴 상태(idle)를 유지하여 스케일 투 제로(scale to zero)가 가능해지며, 30초마다 지속적으로 폴링할 때 소모되었던 컴퓨팅 크레딧을 없앨 수 있습니다.
Neon은 컴퓨팅 엔진이 작동하는 매 초마다 비용을 청구합니다. 일반적인 서버리스 설정에서는 아무리 작은 요청이라도 엔진을 깨어 있는 상태로 유지합니다. 저자의 TV 대시보드는 사용자가 수동으로 동기화하거나 새로운 방송이 시작될 때만 데이터가 변경됨에도 불구하고, 30초마다 데이터베이스에 쿼리를 보냈습니다. 이러한 패턴 때문에 Neon의 컴퓨팅 풀이 과금을 중단하는 제로 상태(zero-state)에 도달하지 못했고, 이로 인해 Vercel 비용 대시보드에는 정기적인 비용 급증이 나타났습니다.
기존 폴링 방식이 문제가 되었던 이유
- 대시보드는 순수 클라이언트 측 React 컴포넌트였으므로, 각 브라우저 인스턴스가 Neon에 직접 요청을 보냈습니다.
- Neon의 요금 체계는 요청 횟수가 아닌 활성 컴퓨팅 시간에 따라 비용이 결정되므로, 30초마다 한 번씩 발생하는 요청이 기본 요금을 계속 발생시켰습니다.
- 저자의 Vercel 모니터링 결과, 트래픽과 Neon 컴퓨팅 사용량 사이에 상관관계가 있음이 확인되었으며, 이는 폴링이 데이터베이스를 계속 깨어 있게 만들었음을 증명했습니다.
실패한 해결책들
마지막 사용자 상호작용 이후 요청을 지연시키는 간단한 디바운스(debounce)를 적용해 보았지만, 타이머가 여전히 30초마다 작동했기 때문에 도움이 되지 않았습니다. Vercel Edge Functions를 사용하는 방법도 시도해 보았으나, 구조가 너무 복잡해졌습니다.
간단한 해결 방법
필요한 코드 변경 사항은 새로고침 간격을 정의하는 상수 하나를 바꾸는 것뿐이었습니다.
- 30초 → 5분
- 그 다음 5분 → 15분
15분 간격으로 설정하면 Neon이 유휴 상태를 인식하고 컴퓨팅 리소스를 스핀 다운(spin down)하기에 충분한 시간이 확보됩니다. 대시보드는 여전히 정상적으로 작동합니다. 사용자가 수동으로 새로고침하면 최신 데이터를 볼 수 있고, 가끔 발생하는 자동 폴링을 통해 불필요한 통신 없이도 새로운 방송 내용을 확인할 수 있습니다.
왜 클라이언트 측 폴링을 유지하는가?
- 단순함 – 추가적인 서버리스 함수나 빌드 단계가 필요 없습니다.
- 사용자 기대치 – 대시보드는 이미 클라이언트 앱처럼 동작하며, 수동 클릭 시 즉각적인 업데이트가 가능합니다.
- 비용 모델과의 일치 – Neon은 요청당이 아닌 컴퓨팅 초당 비용을 청구하므로, 빈도를 줄이는 것이 직접적으로 비용 절감으로 이어집니다.
서버리스 개발자를 위한 교훈
- 폴링 빈도를 데이터의 실제 업데이트 주기와 맞추십시오. 데이터셋이 한 시간에 몇 번만 변경된다면 15분 간격으로도 충분한 경우가 많습니다.
- 서버리스 환경에서 빈번한 폴링은 숨겨진 비용 유발 요인입니다. 분당 단 한 번의 추가 요청만으로도 데이터베이스가 스케일 다운(scale down)되는 것을 막을 수 있습니다.
- 아키텍처를 완전히 개편하지 않고도 작은 설정 변경만으로 상당한 비용 절감 효과를 거둘 수 있습니다.
결론적으로, 상수 하나를 바꾼 것만으로 항상 깨어 있던 데이터베이스를 진정한 서버리스 컴포넌트로 탈바꿈시켰으며, 대시보드의 유용성을 유지하면서도 컴퓨팅 비용을 줄일 수 있었습니다. Neon이나 이와 유사한 초 단위 컴퓨팅 서비스를 사용하는 팀이라면, 폴링 간격을 재검토하는 것만으로도 즉각적인 효과를 볼 수 있을 것입니다.
