데이터와 리포트 설계 시리즈 5/8
비동기 리포트 생성에서는 사용자가 작업 상태를 알아야 한다.
가장 단순한 방법은 polling이다.
프론트엔드가 일정 간격으로 상태 API를 호출한다.
GET /api/jobs/{jobId}
완료되면 다운로드 URL을 보여준다.
Polling은 오래된 방식처럼 보일 수 있다. WebSocket이나 Server-Sent Events가 더 세련되어 보일 수도 있다.
하지만 내부 운영 도구에서는 polling이 충분히 좋은 선택일 때가 많다.
polling이란 무엇인가
Polling은 클라이언트가 주기적으로 서버에 상태를 묻는 방식이다.
예를 들어 2초마다 job 상태를 확인한다.
0초: IN_PROGRESS
2초: IN_PROGRESS
4초: IN_PROGRESS
6초: COMPLETE
구현은 단순하다.
프론트엔드는 timer를 두고 상태 API를 호출한다.
서버는 job table에서 상태를 읽어 응답한다.
polling의 장점
Polling의 가장 큰 장점은 단순함이다.
- HTTP API만 있으면 된다.
- 방화벽이나 proxy 환경에서 잘 동작한다.
- 서버가 connection을 유지하지 않아도 된다.
- 장애가 나도 다음 요청에서 회복할 수 있다.
- 내부 운영 도구의 낮은 트래픽에 적합하다.
리포트 생성 작업이 많지 않고, 사용자가 수십 명 수준이라면 polling 부하는 크지 않다.
polling의 단점
물론 단점도 있다.
- 완료되지 않았는데 계속 요청한다.
- 상태 반영이 polling 간격만큼 늦다.
- 작업 수가 많으면 요청이 늘어난다.
- 탭을 닫거나 네트워크가 끊기면 상태 확인이 중단된다.
하지만 이 단점들이 항상 치명적인 것은 아니다.
내부 리포트 다운로드처럼 실시간성이 낮은 작업에서는 2~5초 지연이 문제가 되지 않을 수 있다.
WebSocket이 더 좋은 경우
WebSocket은 서버가 클라이언트에 즉시 상태를 push할 수 있다.
다음 조건에서는 WebSocket이나 SSE를 검토할 수 있다.
- 실시간 진행률이 중요하다.
- 작업 수가 많다.
- 사용자가 긴 시간 대기한다.
- 여러 이벤트를 지속적으로 받아야 한다.
- 이미 실시간 인프라가 있다.
하지만 WebSocket은 운영 복잡도도 있다.
- connection 관리
- 인증 처리
- 재연결 처리
- scale-out 시 connection 분산
- 서버 리소스 관리
단순한 리포트 완료 알림만을 위해 도입하기에는 과할 수 있다.
내부 운영 도구에서 polling이 충분한 이유
내부 운영 도구는 일반 사용자 서비스와 다르다.
- 사용자 수가 제한적이다.
- 작업 빈도가 높지 않다.
- 실시간성이 낮다.
- 구현과 운영 단순성이 중요하다.
- 브라우저 탭에서 잠시 기다리는 UX를 받아들일 수 있다.
이 조건에서는 polling이 현실적이다.
복잡한 push 구조를 만들기보다, 안정적인 상태 API와 명확한 UX를 제공하는 편이 더 낫다.
polling 간격 정하기
간격은 너무 짧지도 길지도 않아야 한다.
예를 들어 1초 간격은 빠르지만 요청이 많아질 수 있다.
10초 간격은 부하는 낮지만 사용자가 답답할 수 있다.
내부 리포트라면 2~5초 정도가 현실적인 시작점이다.
작업이 오래 걸릴수록 점진적으로 간격을 늘릴 수도 있다.
예:
처음 30초: 2초 간격
이후 2분: 5초 간격
그 이후: 10초 간격
처음에는 단순 고정 간격으로 시작해도 된다.
timeout UX
Polling에는 종료 조건이 필요하다.
완료 또는 실패가 오면 중단한다.
하지만 너무 오래 IN_PROGRESS 상태라면 사용자에게 안내해야 한다.
예를 들어:
- "처리 시간이 길어지고 있습니다."
- "잠시 후 다운로드 내역에서 다시 확인할 수 있습니다."
- "문제가 계속되면 운영자에게 문의하세요."
중요한 것은 polling을 무한히 돌리지 않는 것이다.
프론트엔드 timeout과 서버 job timeout을 함께 설계해야 한다.
사용자가 화면을 떠난 경우
사용자가 브라우저를 닫아도 worker는 계속 작업할 수 있다.
그래서 완료된 파일은 다운로드 이력에서 다시 볼 수 있어야 한다.
Polling UI만 있으면 사용자가 화면을 떠났을 때 결과를 잃어버린 것처럼 보일 수 있다.
job table과 다운로드 이력 화면이 있으면 이 문제가 줄어든다.
리포트 요청
-> job 생성
-> 사용자가 화면을 떠남
-> worker 완료
-> 다운로드 이력에서 파일 확인
이것이 비동기 리포트 UX에서 중요하다.
상태 메시지 설계
Polling UX에서는 상태 메시지가 중요하다.
단순 spinner만 보여주면 사용자는 멈춘 것인지 처리 중인지 모른다.
상태를 명확히 보여준다.
- 요청 접수됨
- 파일 생성 중
- 완료됨
- 실패함
- 다운로드 가능
정확한 진행률을 모르면 percentage를 억지로 만들 필요는 없다.
상태만 명확해도 충분하다.
정리
Polling은 나쁜 UX가 아니다.
상황에 맞으면 가장 단순하고 안정적인 선택이다.
특히 내부 운영 도구의 비동기 리포트 생성에서는 polling이 충분히 실용적이다.
좋은 polling UX에는 다음이 필요하다.
- 적절한 polling 간격
- 명확한 상태 메시지
- 실패와 timeout 처리
- 사용자가 화면을 떠나도 확인 가능한 다운로드 이력
- 서버의 job 상태 관리
실시간 기술을 쓰는 것보다 중요한 것은 사용자가 작업 상태를 신뢰할 수 있게 만드는 것이다.
함께 볼 GitHub 저장소
'성장과 기술 > 시스템 설계' 카테고리의 다른 글
| Worker가 결과 파일을 만들고 Object Storage에 올리는 흐름 (0) | 2026.06.03 |
|---|---|
| Job table로 리포트 작업 상태 관리하기 (0) | 2026.06.02 |
| 오래 걸리는 엑셀 생성을 동기 API로 처리하면 생기는 문제 (0) | 2026.06.01 |
| 운영 콘솔의 리포트 기능은 왜 생각보다 어려운가 (0) | 2026.05.31 |
| 문서가 개인 브랜딩이 되는 순간 (0) | 2026.05.30 |
글에서 정리한 생각은 GitHub의 코드와 포트폴리오로 이어지고, 일부는 FamBlend 같은 제품 실험으로 확장됩니다.