모바일 배터리 수명을 위한 API 설계: 통신 빈도 줄이기
모바일 배터리 수명 관점의 API 설계: 배칭, 캐싱 헤더, 페이로드 축소로 라디오 깨어남을 줄이고 화면 로딩 속도와 배터리 소모를 개선하는 방법을 설명합니다.

왜 잦은 API 통신이 모바일 배터리를 소모하는가
“채티(chatty)”한 API는 하나의 화면을 구성하기 위해 많은 작은 요청을 앱이 연속으로 보내게 만듭니다. 각 요청은 표면상으로는 가벼워 보이지만, 휴대폰에서는 빠르게 누적됩니다.
가장 큰 배터리 비용은 종종 네트워크 라디오에서 나옵니다. 셀룰러와 Wi‑Fi 칩은 데이터를 보내고 받을 때 고전력 상태로 전환합니다. 앱이 여러 요청을 연달아 보낼 때 라디오는 계속 깨어있거나 자주 깨어나게 됩니다. 응답이 작더라도 반복적인 깨어남은 실제 에너지를 소비합니다.
CPU 작업도 있습니다. 각 요청은 헤더 구성, TLS 처리, JSON 파싱, 캐시 업데이트, 결과 병합을 위한 앱 코드 실행을 의미합니다. 연결이 끊기면 이 설정 작업이 반복됩니다.
또한 채티한 API는 UI를 느리게 느껴지게 합니다. 예측 가능한 한 번의 로드 대신 여러 호출 체인을 기다리게 되어 스피너가 길어지고 부분 렌더가 깜빡이며, 네트워크가 약하면 타임아웃이 늘어납니다. 백그라운드 새로고침도 마찬가지로 악화되어 재시도와 깨어남이 늘고 배터리를 더 소모합니다.
모바일 배터리 수명을 위한 API 설계를 실용적으로 생각하는 방법은 단순합니다: 같은 UI를 더 적은 왕복, 더 적은 바이트, 더 적은 백그라운드 작업으로 보여주자.
다음과 같은 구체적 변화를 추적하면 성공을 알 수 있습니다:
- 화면 로드당 API 호출 수 감소
- 화면당 다운로드 바이트 감소
- 셀룰러 환경에서의 중앙값 및 최악 사례의 상호작용 가능 시간 개선
- 동일 결과를 위한 백그라운드 페치와 재시도 감소
이 수치들이 좋아지면 반응성과 배터리 수명도 함께 개선되는 경우가 많습니다.
바꾸기 전에 무엇을 측정할 것인가
요청을 배치하거나 캐싱을 조정하기 전에 앱이 현재 무엇을 하는지 명확히 파악하세요. 빠른 성과는 보통 반복적으로 문제를 일으키는 소수의 부분을 고치면서 나오는데, 실제 화면과 흐름(행복 경로 테스트 하나만이 아님)을 측정해야 찾을 수 있습니다.
트래픽이 많은 몇몇 화면에 대해 기본 항목을 로깅하세요: 로드당 요청 수, 호출되는 엔드포인트, 전송 및 수신 바이트(헤더와 바디 포함), 재시도 및 타임아웃 비율, 그리고 UI가 사용 가능해질 때까지 걸리는 시간. 가능하다면 네트워크 타입(와이파이 vs 셀룰러)별로 오류 비율을 나누세요. 안정된 연결에서는 보이지 않는 문제들이 셀룰러에서 드러나곤 합니다.
전경 트래픽과 백그라운드 트래픽을 분리하세요. 화면은 조용해 보여도 기기는 백그라운드 새로고침, 푸시로 유발된 동기화, 분석 업로드, 혹은 ‘혹시 몰라’ 하는 프리페치로 바쁠 수 있습니다. 이들을 따로 추적해 잘못된 것을 최적화하지 않도록 하세요.
핫스팟은 보통 앱 시작, 홈/피드 화면, 여러 호출로 확장되는 상세 화면, 풀투리프레시 같은 순간에 집중됩니다. 이 중 하나를 골라 종단간으로 측정하세요.
팀이 ‘좋음’의 기준에 합의할 수 있도록 기준 예산을 정하세요. 예: “주문 추적 화면의 콜드 로드는 상태를 보여주기 전에 최대 6개의 요청을 하고 250KB를 초과하지 않아야 한다.”
간단한 KPI 쌍을 사용하고 싶다면 (1) 화면 로드당 요청 수와 (2) 재시도율을 사용하세요. 재시도 감소는 예상보다 더 많은 배터리를 절약하는 경우가 많습니다. 반복 재시도는 라디오를 더 오래 활성화하기 때문입니다.
단계별: 배치로 요청 수 줄이기
채티한 API는 실수로 쉽게 생깁니다. 각 위젯이 ‘자신의’ 데이터를 로드하고 한 화면이 열 개가 넘는 작은 호출을 트리거합니다. 해결책은 보통 간단합니다: 항상 함께 로드되는 것을 식별하고 더 적은 호출로 반환하세요.
먼저 트래픽이 많은 한 화면(홈, 인박스, 주문 목록)을 매핑하세요. 접히지 않는(above the fold) 부분에 무엇이 보이는지 적고, 각 UI 요소가 어떤 요청에서 오는지 추적합니다. 같은 사용자 프로필을 두 번 가져오는 중복이나 항상 함께 가는 호출들(프로필 + 권한 + 읽지 않은 수 등)을 자주 발견할 것입니다.
다음으로 신뢰할 수 있게 함께 발생하는 호출을 그룹으로 묶으세요. 일반적으로 두 가지 선택지가 있습니다:
- 그 화면을 위해 목적별 엔드포인트를 만들기(보통 더 안정적)
- 소형 예측 가능한 리소스 목록을 받는 배치 엔드포인트 추가하기
배치는 화면 기반이고 범위가 제한되게 유지해 캐시, 모니터링, 디버그를 쉽게 만드세요.
배칭이 엉망이 되지 않도록 몇 가지 규칙을 지키세요. 화면이 지금 실제로 필요로 하는 것만 반환하고 ‘혹시 몰라’ 전체 객체를 주지 마세요. 일부 조각이 선택적이면 명확히 표시해 UI가 중요한 부분을 빠르게 렌더하도록 하세요. 또한 부분 실패가 전체 재시도를 강요하지 않도록 응답을 설계하세요. 실패한 것만 재시도하는 것이 전체 배치를 다시 보내는 것보다 훨씬 비용이 적습니다.
배터리를 절약하는 캐싱 헤더(단순한 대역폭 절감이 아님)
캐싱은 배터리 기능입니다. 모든 요청은 라디오를 깨우고 CPU를 바쁘게 하며 파싱과 앱 로직을 촉발합니다. 좋은 캐싱 헤더는 많은 새로고침을 가벼운 검사로 바꿉니다.
가장 큰 이득은 조건부 요청입니다. 동일한 데이터를 다시 다운로드하는 대신 앱이 “변경되었나?”를 묻습니다. 변경되지 않았다면 서버는 작은 304 Not Modified로 응답합니다.
리소스의 버전을 나타내는 응답에 ETag를 사용하고, 클라이언트가 다음 가져오기에서 If-None-Match를 보내게 하세요. ETag 생성이 어렵다면 Last-Modified와 If-Modified-Since도 간단한 “업데이트됨” 리소스에 잘 동작합니다.
변경이 드문 데이터는 캐시 정책을 명확히 하세요. Cache-Control은 실제 변화 빈도와 맞아야 합니다. 사용자 프로필에는 짧은 max-age가 적당할 수 있지만 앱 설정, 참조 목록, 기능 플래그는 더 길게 둘 수 있습니다.
앱 쪽에서 304를 빠른 경로로 취급하세요. JSON을 파싱하지 말고(없습니다), 모델을 재구성하지 말고, UI를 깜박이지 마세요. 화면에 이미 있는 것을 유지하고 표시기만 업데이트하세요.
예: 주문 추적 화면이 매 15초마다 주문 상태를 폴링한다고 합시다. 응답에 ETag가 포함되어 있으면 대부분의 검사에서 304를 받을 수 있습니다. 앱은 마지막 상태를 유지하고 상태가 바뀔 때만 실제 작업을 합니다(예: “포장됨”에서 “배송됨”으로 변경될 때).
민감한 데이터에 대해서는 의도적으로 처리하세요. 캐싱이 자동으로 위험한 것은 아니지만 명확한 규칙이 필요합니다. 개인 정보나 토큰이 포함된 응답은 제품 요구사항이 허용하지 않으면 캐시하지 마세요. 사용자별 데이터에는 짧은 수명을 사용하고, 공유 캐시가 개인 응답을 저장하지 못하도록 (Cache-Control: private) 하세요.
더 똑똑한 페이로드: 덜 보내고 덜 파싱하기
추가 바이트는 모바일에서 단순한 대역폭을 넘는 비용을 유발합니다. 라디오를 더 오래 깨우고 앱이 JSON 디코딩과 모델 업데이트에 더 많은 CPU를 사용하게 합니다. API 통신을 줄이려면 페이로드 트리밍이 가장 빠른 성과를 주는 경우가 많습니다.
화면별로 페이로드를 감사하세요. 하나의 화면(예: 홈 피드)을 골라 응답 크기를 기록하고 필드별로 검토하세요: 클라이언트가 이것을 렌더하는가, 아니면 표시 결정을 위해서만 사용하는가? 아니라면 해당 엔드포인트에서 제거하세요.
목록에는 보통 작은 ‘요약’ 형태면 충분합니다. 목록 행에는 보통 id, 제목, 상태, 타임스탬프 정도면 충분합니다. 사용자가 항목을 열 때만 상세를 가져오세요.
빠르게 페이로드를 줄이는 몇 가지 방법:
- 반복되는 긴 문자열 대신 id나 짧은 enum 코드 사용
- 클라이언트가 안전하게 가정할 수 있는 명백한 기본값은 재전송하지 않기
- 동일한 중첩 객체를 각 목록 항목마다 반복하지 않기
- 필드 이름과 타입을 안정적으로 유지해 클라이언트가 분기 처리하거나 재파싱하지 않도록 하기
압축은 특히 느린 네트워크에서 도움이 되지만 실제 기기에서 CPU 트레이드오프를 테스트하세요. Gzip이나 Brotli는 전송 크기를 크게 줄이지만 오래된 폰에서는 매우 큰 응답을 압축 해제하는 데 눈에 띄는 시간이 걸릴 수 있습니다. 여전히 가장 큰 이득은 처음부터 전송하는 데이터를 줄이는 것입니다.
응답 형태를 계약(contract)처럼 다루세요. 필드 이름과 타입이 일관되면 앱은 더 적은 폴백과 방어적인 코드를 필요로 하고, 이는 UI를 부드럽게 유지하고 배터리 사용을 낮추는 데 도움이 됩니다.
열악한 네트워크와 재시도 횟수를 줄이도록 설계하기
모바일 앱은 요청을 보낼 때뿐 아니라 실패해서 재시도하고 라디오를 다시 깨우고 작업을 반복할 때도 배터리를 소모합니다. API가 완벽한 와이파이를 가정하면 불안정한 4G를 쓰는 실제 사용자는 그 비용을 지불합니다.
더 적은 데이터를 요청하기 쉽게 만드세요. 서버 측 필터와 페이지네이션을 클라이언트 필터링보다 우선시키세요. 화면이 특정 사용자에 대해 최근 20개의 이벤트만 필요하면, 앱이 수백 행을 받아 대부분을 버리지 않도록 그 정확한 쿼리를 지원하세요.
델타 동기(delta sync)를 지원하세요. 앱이 “내가 마지막으로 확인한 이후 무엇이 바뀌었나?”를 물을 수 있게 하면 클라이언트는 그 시점 이후의 업데이트와 삭제만 요청하면 됩니다. 이는 타임스탬프나 증가하는 버전 번호를 반환하는 단순한 방식으로 구현할 수 있습니다.
재시도는 불가피하므로 업데이트를 멱등하게 만드세요. 재시도가 중복 청구나 중복 제출을 일으키면 안 됩니다. 생성 작업에 대한 idempotency 키와 상태를 설정하는 업데이트 방식은 큰 도움이 됩니다.
재시도가 발생할 때는 재시도 폭풍(retry storms)을 피하세요. 지수 백오프와 지터를 사용해 수천 대의 기기가 동시에 서버를 때리지 않게 하고, 기기가 초마다 깨어나지 않도록 하세요.
명확한 오류 코드를 반환해 클라이언트가 동작을 결정하게 하세요. 401은 재인증을 트리거하고, 404는 보통 재시도를 멈추게 하며, 409는 상태 새로고침이 필요할 수 있고, 429나 503은 백오프를 유도합니다.
클라이언트 동작이 API 비용을 배로 만드는 경우
잘 설계된 API가 있어도 클라이언트가 네트워크 작업을 조용히 배로 만들 수 있습니다. 모바일에서는 그런 추가 깨어남과 라디오 시간들이 바이트 자체보다 배터리에 더 큰 비용을 낼 때가 많습니다.
변경이 거의 없는 데이터를 캐시하세요. 프로필 사진, 기능 플래그, 참조 데이터(국가, 상태, 카테고리)는 매번 화면 방문 시 가져오지 않아야 합니다. 합리적인 수명을 부여하고 디스크에 저장하며 필요할 때만 새로 고치세요. API가 유효성 검사를 지원하면(ETag나 Last-Modified) 빠른 재검사가 전체 다운로드보다 훨씬 저렴합니다.
또 다른 흔한 문제는 진행 중인 중복 요청입니다. 앱의 두 부분이 동시에 같은 리소스를 요청하면(예: 헤더와 설정 화면이 모두 프로필을 요청) 요청을 합치지 않으면 두 번 전송하고 두 번 파싱하고 상태를 두 번 갱신합니다. 한 네트워크 호출을 단일 진실 소스로 취급하고 여러 소비자가 그 결과를 기다리게 하세요.
백그라운드 새로고침은 의도적으로 수행되어야 합니다. 유저가 곧 보게 될 내용을 바꾸지 않거나 알림을 유발하지 않는다면 보통 기다려도 됩니다. 모든 앱 재개(resume) 시 새로고침 로직을 실행하지 마세요. 짧은 쿨다운을 추가하고 마지막 업데이트 시각을 확인하세요.
AppMaster로 백엔드를 만들면 화면 중심 엔드포인트를 쉽게 설계하고 응답 스키마를 일관되게 유지하며 캐싱 헤더를 제어된 방식으로 추가해 클라이언트가 대부분의 시간은 조용할 수 있게 도울 수 있습니다.
배칭, 캐싱, 페이로드에서 흔히 하는 실수
목표는 라디오 깨우기 감소, CPU 작업 감소, 재시도 감소입니다. 몇 가지 패턴은 절약을 상쇄하거나 오히려 화면을 더 느리게 만들 수 있습니다.
배칭이 상황을 악화시키는 경우
배칭은 도움이 되다가 배치가 ‘모두 달라줘’ 호출로 변할 때 문제가 됩니다. 서버가 많은 테이블을 조인하고 무거운 권한 검사를 하며 거대한 응답을 만들어야 한다면, 그 단일 요청이 여러 작은 요청보다 더 오래 걸릴 수 있습니다. 모바일에서는 한 번의 느린 요청이 앱을 기다리게 하고 네트워크를 활성 상태로 유지하며 타임아웃 위험을 높입니다.
건강한 배치는 화면 모양으로 제한되어야 합니다: 하나의 뷰에 필요한 것만, 명확한 한계를 두고. 응답을 한 문장으로 설명할 수 없다면 그 엔드포인트는 아마도 범위가 너무 넓습니다.
오래된 데이터를 만드는 캐싱
명확한 무효화 계획 없이 캐싱하면 사용자가 오래된 데이터를 보고 풀투리프레시를 하며 앱이 불필요한 전체 재로드를 하게 됩니다. 캐싱 헤더를 사용할 때는 데이터가 무엇에 의해 업데이트되는지(생성/업데이트 액션, 서버 이벤트, 짧은 신선도 창)를 미리 계획해 클라이언트가 캐시된 응답을 신뢰할 수 있게 하세요.
폴링도 배터리 함정입니다. 5초 간격의 타이트한 타이머는 아무 변화가 없어도 기기를 바쁘게 합니다. 가능하면 서버 주도 업데이트를 사용하거나 강하게 백오프하세요(빈 폴링 후 간격 늘리기, 백그라운드에서는 일시중지).
과대화된 페이로드는 은밀한 비용입니다. 거대한 중첩 객체를 ‘편의상’ 반환하면 더 많은 바이트, 더 많은 JSON 파싱, 더 많은 메모리 churn이 발생합니다. 화면이 필요로 하는 것만 보내고 상세는 필요 시 가져가세요.
마지막으로 배치에서 부분 실패를 무시하지 마세요. 하나의 하위 결과가 실패해 전체를 재시도하면 트래픽이 중복됩니다. 클라이언트가 실패한 부분만 다시 시도할 수 있게 설계하세요.
짧은 체크리스트: 배치는 범위를 제한하라, 캐시 신선도를 미리 정하라, 타이트한 폴링을 피하라, 페이로드를 다듬어라, 부분 성공을 지원하라.
출시 전 빠른 체크리스트
릴리스 전에 네트워크 동작에만 집중한 한 번의 점검을 하세요. 대부분의 배터리 이득은 놀라운 상황을 제거하는 데서 옵니다: 더 적은 깨어남, 적은 파싱, 백그라운드에서의 재시도 감소.
상위 세 개 화면에서 다음을 점검하세요:
- 콜드 로드가 작은 예측 가능한 수의 요청으로 끝나는가(항목별 조회 같은 숨은 추가 호출을 경계)
- 응답에 명확한 캐싱 규칙이 포함되어 있는가(
ETag또는Last-Modified가 적합한 곳에 있으며, 변경이 없을 때304 Not Modified를 반환하는가) - 목록 엔드포인트가 한계가 정해져 있는가: 안정적 정렬, 페이지네이션, 기본적으로 사용되지 않는 필드 없음
- 재시도 로직이 지터가 있는 백오프를 사용하고 자체적으로 멈출 수 있는 오류에서 멈추며 전체 재시도 시간이 제한되는가
- 백그라운드 업데이트가 정당화되는가; 화면에 변화를 주지 않는 지속적 폴링은 피하라
간단한 현실 점검: 화면을 한 번 로드한 뒤 비행기 모드를 켜고 다시 열어보세요. 캐시된 내용, 마지막 상태, 친절한 플레이스홀더 등 유용한 것을 여전히 보여주면 불필요한 호출을 줄여 체감 속도도 개선했을 가능성이 큽니다.
예시: 주문 추적 화면을 더 저렴하게 로드하기
고객이 모바일 데이터로 주문 추적 앱을 열고 배터리가 20% 남아 있다고 합시다. 그들이 원하는 것은 하나입니다: “내 소포가 지금 어디 있지?” 화면은 단순해 보여도 그 뒤의 API 트래픽은 생각보다 비쌀 수 있습니다.
이전에는 앱이 화면을 로드할 때 요청이 폭주했습니다. UI는 라디오가 계속 깨어나는 동안 기다리고 약한 연결에서는 몇몇 호출이 타임아웃이 났습니다.
전형적인 ‘이전’ 패턴은 다음과 같습니다:
GET /orders/{id}주문 요약GET /orders/{id}/items라인 아이템GET /orders/{id}/history상태 이벤트GET /me사용자 프로필 및 설정GET /settings표시 규칙(통화, 날짜 형식)
이제 UI를 바꾸지 않고 세 가지 변경을 적용하세요.
첫째, 화면이 필요로 하는 것만 한 번에 반환하는 단일 화면 엔드포인트를 추가합니다: 주문 요약, 최신 상태, 최근 기록, 항목 제목 등. 둘째, 프로필을 캐시하세요: GET /me가 ETag와 Cache-Control: private, max-age=86400를 반환하면 대부분의 열람은 빠른 304 응답(또는 캐시가 아직 신선하면 아예 요청 없음)이 됩니다. 셋째, 페이로드를 슬림하게 만드세요: 항목 목록은 전체 제품 설명이나 사용되지 않는 메타데이터 대신 id, name, qty, thumbnail_url만 보냅니다.
결과는 적은 왕복, 적은 바이트, 네트워크가 불안정할 때 재시도 감소입니다. 기기의 라디오는 더 자주 잠들고, 그게 배터리 절감의 핵심입니다.
사용자에게는 새로운 것이 보이지 않습니다. 화면은 동일하지만 더 빨리 로드되고 반응성이 좋아지며 연결이 불안정해도 더 잘 작동합니다.
다음 단계: 실용적인 단계별 롤아웃 계획(그리고 AppMaster가 도울 수 있는 부분)
빠른 성과를 원한다면 작게 시작해 영향을 증명하세요. 배터리 절감은 보통 소수의 라디오 깨우기와 파싱 작업을 줄이는 것에서 나오지, 대규모 재작성에서 나오지 않습니다.
안전하고 측정 가능하며 되돌리기 쉬운 세 가지 변경:
- 한 화면을 종단간으로 측정(요청 수, 총 바이트, 상호작용 가능 시간, 오류 및 재시도율)
- 그 화면의 요청을 하나 또는 두 개의 호출로 배치(호환성을 위해 기존 엔드포인트는 유지)
- 최고 트래픽 GET 엔드포인트에
ETag지원 추가해 클라이언트가If-None-Match로304 Not Modified를 받게 함
사용량이 안정적인 기능(예: 주문 목록 또는 메시지 인박스)을 선택하세요. 가능하면 서버 사이드 플래그로 배포한 뒤 며칠간 오래된 경로와 새 경로의 KPI를 비교하세요. 세션당 요청 수 감소, 재시도 감소, 활성 사용자당 다운로드 바이트 감소를 찾으세요.
API와 앱 릴리스를 조율해 이전 클라이언트가 깨지지 않게 하세요. 실용적 규칙: 먼저 새 동작을 추가하고, 클라이언트를 이주시키고, 마지막에 이전 동작을 제거하세요. 캐싱 동작을 바꿀 때는 개인화된 데이터에 주의하고 공유 캐시가 사용자 간 데이터를 섞지 않도록 하세요.
백엔드 변경을 빠르게 프로토타이핑하고 배포하고 싶다면 AppMaster (appmaster.io)를 사용해보세요. 시각적으로 데이터를 모델링하고 드래그 앤 드롭 에디터로 비즈니스 로직을 만들며 요구사항이 바뀔 때 프로덕션용 소스코드를 재생성할 수 있습니다.
우선 하나의 배치된 엔드포인트와 그 엔드포인트의 주요 GET들에 ETag를 추가해보세요. 수치가 개선되면 어디에 더 공을 들여야 할지 정확히 알 수 있습니다.
자주 묻는 질문
좋은 출발점은 화면별 예산을 정하고 실제 세션을 측정하는 것입니다. 많은 팀이 처음에는 셀룰러 환경에서 차가운(처음) 화면 로드당 4–8개의 요청을 목표로 삼고, 가장 큰 문제들을 수정한 뒤에 그 범위를 더 좁힙니다. 정답은 네트워크 재시도나 장시간 라디오 활성화를 유발하지 않으면서 일관되게 목표하는 시간대비 상호작용 가능 시간(time-to-interactive)을 만족시키는 수치입니다.
여러 호출이 항상 함께 발생할 때는 일반적으로 배칭이 도움이 됩니다. 하지만 배치가 너무 느리거나 거대해져서 많은 불필요한 데이터를 반환하면 오히려 해로울 수 있습니다. 배치 응답은 ‘화면 모양(screen-shaped)’으로 제한하고 범위를 명확히 하세요. 배치 엔드포인트가 정기적으로 타임아웃되거나 많은 사용되지 않는 데이터를 반환한다면, 소수의 집중된 호출로 다시 나누는 것이 낫습니다.
우선 ETag와 조건부 요청(If-None-Match)으로 시작하세요. 이것은 많은 새로고침을 작은 304 Not Modified 응답으로 바꿀 수 있기 때문에 배터리 절감 효과가 큽니다. 또한 데이터 변경 빈도에 맞춘 Cache-Control을 추가해 클라이언트가 불필요한 네트워크 작업을 피하도록 하세요. ETag 구현이 어렵다면 Last-Modified + If-Modified-Since가 ‘업데이트된 시각’ 스타일 리소스에 실용적인 대안입니다.
컨텐츠 변경이 타임스탬프와 잘 매핑되지 않거나 정확한 버전 체크가 필요하면 ETag를 사용하세요. 서버에 명확한 갱신 시간이 있고 타임스탬프 단위의 그레인(granularity)이 괜찮다면 Last-Modified를 사용해도 됩니다. 하나만 구현할 수 있다면 불필요한 다운로드를 막는 데에는 ETag가 더 정확한 선택인 경우가 많습니다.
API 변경 전에 화면과 세션 단위로 계측하세요. 엔드포인트만 보지 말고 실제 화면이 어떻게 동작하는지 측정해야 합니다. 요청 수, 바이트(헤더 + 바디), 재시도 및 타임아웃 비율, 상호작용 가능 시간, 그리고 전경(포어그라운드) 트래픽과 백그라운드 트래픽을 구분해 기록하세요. 보통 반복적인 라디오 깨우기를 유발하는 문제는 몇몇 화면이나 흐름에서 집중적으로 발생합니다.
배치 응답을 각 하위 결과가 독립적으로 성공하거나 실패할 수 있도록 설계하고, 실패한 항목만 재시도할 수 있도록 충분한 오류 상세를 포함하세요. 하나의 하위 결과 실패 때문에 전체 배치를 다시 요청하게 만들지 마세요. 이렇게 하면 중복 트래픽을 줄이고 불안정한 연결에서 라디오 깨우기를 줄일 수 있습니다.
화면이 지금 렌더하는 데이터만 남기고 응답을 정리하세요. 목록에는 요약 형태(summary)를 사용하고, 무거운 필드나 자주 사용되지 않는 필드는 항목을 열 때 불러오는 상세 엔드포인트로 옮기세요. 이렇게 하면 전송 바이트가 줄고 JSON 파싱과 모델 업데이트 비용도 내려갑니다. 이 방법은 앱을 깨뜨리지 않으면서 페이로드를 빠르게 줄이는 가장 실용적인 방법입니다.
지수적 백오프와 지터(jitter)를 사용하고 전체 재시도 창을 제한하세요. 이렇게 하면 기기가 몇 초마다 깨어나지 않습니다. 쓰기 작업은 멱등성(idempotent)을 고려해 재시도가 중복 생성이나 중복 청구를 일으키지 않도록 하세요. 또한 서버가 명확한 상태 코드를 반환하면 클라이언트가 더 이상 재시도할 필요가 없는 상황을 판단할 수 있습니다.
빈번한 폴링은 아무 변화가 없어도 라디오와 CPU를 바쁘게 유지합니다. 폴링이 필요하다면 변화가 없을 때 간격을 늘리고 백그라운드에서는 폴링을 중단하세요. 가능하면 이벤트 기반 업데이트로 전환해 새로운 내용이 있을 때만 앱을 깨우도록 하세요.
AppMaster에서는 화면 중심 엔드포인트를 만들고 응답 스키마를 일관되게 유지할 수 있어 배칭과 페이로드 조정이 쉬워집니다. 또한 조건부 요청을 지원하는 헤더를 반환하는 버전 관리 로직을 추가해 클라이언트가 빠른 ‘변경 없음’ 응답을 받도록 도울 수 있습니다. 실용적인 접근법은 트래픽이 많은 한 화면에서 배칭된 엔드포인트와 ETag 지원을 먼저 도입해 요청과 재시도가 얼마나 줄어드는지 측정하는 것입니다.


