Firexport블로그

Firebase Remote Config 요금 정리: 내 앱은 얼마를 낼까

2026년 9월 1일부터 Firebase Remote Config는 앱이 설정을 가져오는(fetch) 횟수로 요금이 매겨집니다. 하루 10만 건까지는 모든 요금제에서 무료입니다. 그 위로는 Blaze 프로젝트는 fetch마다 돈을 내고, Spark 프로젝트는 결국 스로틀링(요청 제한)에 걸립니다. 대부분의 앱은 이 선 아래에 머뭅니다. 내 앱이 그 안에 드는지는 사용자 수보다 코드의 설정 하나, 최소 fetch 간격(minimum fetch interval)에 더 달려 있습니다.

요약

  • 프로젝트당 하루 fetch 10만 건 미만이면 Spark든 Blaze든 달라지는 것이 없습니다. 확인하는 법
  • 선을 넘는 기존 Spark 프로젝트는 2026년 11월 15일 전에 Blaze로 올리면 과금 시작이 2026년 12월 1일에서 2027년 2월 1일로 미뤄집니다. 날짜 정리
  • Blaze에서 선을 넘으면 fetch 1만 건당 $0.06, 하루 1,000만 건을 넘는 부분은 1만 건당 $0.01입니다. 하루 100만 건이면 한 달에 약 $162입니다. 내 앱 계산하기
  • 기본값인 12시간 간격이면 기기 한 대의 fetch는 하루 2번 정도로 묶입니다. 짧은 간격, fetch(0), 실시간 업데이트, 서버 쪽 로드가 앱을 선 위로 밀어 올립니다. 줄이는 법

가격

Spark(무료)Blaze(종량제)
하루 fetch 10만 건까지무료무료
하루 100,001~1,000만 건30일 유예 뒤 스로틀링1만 건당 $0.06(건당 $0.000006)
하루 1,000만 건 초과스로틀링1만 건당 $0.01(건당 $0.000001)
A/B Testing, 롤아웃, 개인화포함포함
  • 10만 건은 프로젝트 단위입니다. 같은 프로젝트의 Android 앱, iOS 앱, 웹사이트가 함께 씁니다.
  • 하루 단위이고, 한가한 날이 바쁜 날을 메워 주지 않습니다. fetch가 100만 건 나온 출시일은 나머지 날이 모두 10만 건 아래여도 그날 하루에 $5.40입니다.
  • 코드도 SDK 버전도 바꿀 필요가 없습니다. 두 요금제 모두 fetch는 Firebase 쪽에서 셉니다.

새 요금이 내 프로젝트에 적용되는 날

2026년 9월 1일 전에 Remote Config를 켠 프로젝트는 먼저 전환 기간을 받습니다. 그 기간은 프로젝트의 요금제에 따라 다릅니다.

내 프로젝트새 규칙 적용하루 10만 건을 넘으면
2026년 9월 1일 이후에 Remote Config를 쓰기 시작이미 적용 중Spark: 30일 뒤 스로틀링. Blaze: 과금.
기존 프로젝트, Blaze2027년 2월 1일과금. 할 일은 없습니다.
기존 프로젝트, Spark에서 2026년 11월 15일 전에 Blaze로 업그레이드2027년 2월 1일과금
기존 프로젝트, Spark 유지2026년 12월 1일30일 뒤 스로틀링

요금 문서에는 11월 15일과 12월 1일 사이에 업그레이드한 Spark 프로젝트가 어떻게 되는지 나와 있지 않습니다. 그렇게 할 생각이라면 12월 1일부터 과금된다고 보세요.

11월 15일 전에 업그레이드해야 할까요?

  • 하루 fetch가 10만 건 미만이면 그럴 필요가 없습니다. Spark도 Blaze도 전과 똑같이 동작합니다.
  • 그보다 많거나 가깝다면, 11월 15일 전에 업그레이드하면 무엇이든 청구되기 전에 fetch를 줄일 시간이 12월과 1월, 두 달 더 생깁니다. Spark에 남으면 스로틀링인데, 대부분의 앱에는 몇 달러보다 그쪽이 더 나쁩니다.
  • Blaze는 프로젝트를 Cloud Billing 계정에 연결하고, 지출 상한이 없습니다. 다른 제품의 무료 사용량은 그대로이고, 그것을 넘는 만큼만 냅니다. 업그레이드할 때 예산 알림을 걸어 두세요(아래).

Spark의 스로틀링이란

Spark 프로젝트가 처음으로 하루 10만 건을 넘은 날부터 30일 유예 기간이 시작되고, 그동안은 모든 fetch가 그대로 처리됩니다. 그사이 사용량이 다시 선 아래로 내려가도 카운트다운은 멈추거나 초기화되지 않습니다. 31일째부터는 매일 10만 번째 이후의 fetch가 거부됩니다. 앱은 계속 돌아가지만, fetch가 거부된 기기는 이미 가진 값이나 앱에 넣어 둔 기본값에 머뭅니다. 롤아웃도, A/B 테스트도, 킬 스위치도 그 기기에는 닿지 않습니다. 사용량이 한도에 가까워지면 프로젝트 관리자에게 이메일과 콘솔 배너로 알림이 가니, 그 메일이 왔을 때가 확인할 때입니다.

fetch 수 세기

fetch는 Remote Config 서버에 닿는 요청입니다.

세는 것세지 않는 것
서버로 가는 fetch()와 fetchAndActivate()최소 fetch 간격 안에서 한 같은 호출. SDK가 기기에서 답합니다
실시간 업데이트 뒤의 다운로드실시간 연결을 열어 두는 것
REST API나 Admin SDK로 템플릿을 읽는 것(서버 쪽 Remote Config 포함)activate(), getString() 등 기기에서 값을 읽는 모든 호출

다른 Firebase 제품이 내부에서 하는 호출도 세지 않습니다. 내 프로젝트의 fetch 수는 여기서 봅니다.

  • Firebase 콘솔: 사용량 및 결제(Usage and billing)의 Remote Config 섹션. Spark에서는 할당량 진행 카드(Quota Progress)가 그날의 fetch를 10만 건과 견주어 보여 주고, Blaze에서는 막대 차트가 날마다의 fetch를 가격 구간별로 나눠 보여 줍니다.
  • Google Cloud 콘솔: IAM 및 관리자 > 할당량 및 시스템 한도(IAM & Admin > Quotas & System Limits)에서 firebaseremoteconfig.googleapis.com으로 필터링하면 두 요금제 모두 볼 수 있습니다. Blaze에서는 Cloud Billing 보고서에 Fetch Requests SKU로 청구액이 나옵니다. 2026년 9월 1일 이후에 만든 프로젝트는 37B1-4623-6F54, 그 전에 만든 프로젝트는 598C-0184-404A입니다.

그런 다음 평소 하루의 fetch 수를 그날 Analytics의 활성 사용자 수로 나눕니다. 기본 12시간 간격에 실시간 리스너가 없으면 기기 한 대는 하루 2번 정도를 넘을 수 없으니 결과는 2 이하입니다. 앱을 여러 기기에 깐 사용자나 웹사이트에 여러 브라우저로 들어오는 사용자가 많으면 조금 더 나옵니다. 2를 훌쩍 넘는다면 코드 어딘가가 간격을 건너뛰고 있습니다. 어디를 봐야 할지는 fetch가 늘어나는 원인에 있습니다.

내 앱이 낼 돈

하루 fetch 수는 일일 활성 사용자 수 × 사용자당 하루 fetch 수입니다. 지금 숫자나 출시 뒤에 예상하는 숫자를 넣어 보세요.

Remote Config 비용 계산

기본 fetch 간격 12시간에 실시간 리스너가 없으면, 기기 한 대의 fetch는 하루 많아야 2번 정도입니다.

하루 fetch 수
200,000
Blaze에서
하루 US$0.60
이런 날이 30일이면 US$18.00
Spark에서
한도를 100,000건 넘습니다. 30일 유예 기간이 지나면 이 fetch(그날의 50%)는 스로틀링됩니다.

규모별로, Blaze에서 똑같은 날이 30일 이어진다고 할 때의 한 달 비용입니다.

일일 활성 사용자사용자당 fetch하루 fetchBlaze 한 달
10,000220,000US$0.00
100,0002200,000US$18.00
100,000101,000,000US$162.00
1,000,00022,000,000US$342.00
1,000,0001010,000,000US$1,782.00
1,000,0003030,000,000US$2,382.00

일일 사용자가 100만 명이라면 사용자당 fetch를 10번에서 2번으로 줄이는 것만으로 한 달에 약 $1,440를 아낍니다. 거꾸로, 무료 10만 건 안에 드는 일일 사용자 수는 이렇습니다.

사용자당 하루 fetch무료로 되는 규모
1일일 활성 사용자 약 100,000명
2일일 활성 사용자 약 50,000명
5일일 활성 사용자 약 20,000명
20일일 활성 사용자 약 5,000명

fetch가 늘어나는 원인과 줄이는 법

fetch 메서드는 모두 먼저 최소 fetch 간격을 확인합니다. 간격 안이면 SDK는 이미 가진 값을 돌려주고 요청을 보내지 않습니다. 그래서 앱의 fetch 수는 그 간격을 어떻게 정했는지, 그리고 간격을 비켜 가는 몇 가지에 달려 있습니다. 먼저 코드에서 간격을 정하거나 건너뛰는 곳을 모두 찾아보세요.

grep -rniE "minimumfetchinterval|fetch\(0|expirationduration|timespan\.zero" \
  --exclude-dir={node_modules,build,Pods,.dart_tool,.gradle} .

1. 프로덕션에 남은 짧은 fetch 간격

기본값은 Android, Apple 플랫폼, 웹, Flutter 모두 12시간입니다. 짧은 값은 개발용 설정과 예제에서 옵니다. Firebase의 Flutter 시작 가이드 코드부터 “자주 새로고침할 수 있도록” 1시간으로 정하고, 많은 튜토리얼이 이것을 그대로 가져다 씁니다. 그대로 출시하면 기기마다 마지막 fetch에서 1시간이 지난 뒤 시작하는 세션마다 한 번씩, 하루 최대 24번까지 fetch합니다. 짧은 값은 디버그 빌드에만 두세요.

// Android (Kotlin). On AGP 8+, BuildConfig.DEBUG needs
// buildFeatures { buildConfig = true } in build.gradle.
Firebase.remoteConfig.setConfigSettingsAsync(
    remoteConfigSettings {
        // 12 hours in release builds
        minimumFetchIntervalInSeconds = if (BuildConfig.DEBUG) 60 else 43200
    }
)
// iOS (Swift)
let settings = RemoteConfigSettings()
#if DEBUG
settings.minimumFetchInterval = 60
#else
settings.minimumFetchInterval = 43200 // 12 hours
#endif
RemoteConfig.remoteConfig().configSettings = settings
// Flutter. kDebugMode is in package:flutter/foundation.dart.
await FirebaseRemoteConfig.instance.setConfigSettings(RemoteConfigSettings(
  fetchTimeout: const Duration(minutes: 1),
  minimumFetchInterval:
      kDebugMode ? const Duration(minutes: 1) : const Duration(hours: 12),
));
// Web. 12 hours is the default, so deleting the line does the same.
const remoteConfig = getRemoteConfig(app);
remoteConfig.settings.minimumFetchIntervalMillis = 12 * 60 * 60 * 1000;

Firebase는 거의 바뀌지 않는 값이라면 24시간이나 48시간까지 늘리라고 권합니다. 변경이 사용자에게 빨리 닿게 하려고 간격을 줄였다면, 실시간 업데이트(4)가 세션마다 한 번이 아니라 변경마다 한 번의 fetch로 같은 일을 합니다.

2. “Remote Config 값이 안 바뀜” 해결책에서 온 fetch(0)

“새 값이 안 보여요”라는 질문에 흔히 달리는 답은 fetch 호출에 간격 0을 넘기는 것입니다. Android와 Apple 플랫폼에서는 이 인자가 설정보다 우선하므로, 간격을 어떻게 설정했든 호출할 때마다 서버로 갑니다.

// Each of these ignores the interval and goes to the server on every call:
remoteConfig.fetch(0)                                // Android
remoteConfig.fetch(withExpirationDuration: 0)        // iOS
remoteConfig.FetchAsync(TimeSpan.Zero)               // Unity

인자를 지우고 설정한 간격을 따르게 하세요. 사용자가 보는 값은 여전히 12시간 안에 바뀌고, 실시간 리스너가 있으면 곧바로 바뀝니다.

3. 화면마다, 복귀마다, 백그라운드에서 깨어날 때마다 하는 fetch

화면마다 하는 초기화, onResume, 컴포넌트 마운트, 그리고 푸시 메시지나 백그라운드 작업이 앱을 깨울 때도 실행되는 Application.onCreate에 넣은 fetch는 간격이 허락하는 만큼을 몇 배로 늘립니다. 간격이 12시간이면 이런 호출은 대부분 기기에서 답하므로 늘어나는 것이 거의 없습니다. 짧은 간격이나 fetch(0)과 만나면 큰 숫자가 여기서 나옵니다. fetch는 앱이 포그라운드에서 시작할 때 한 번만 하고, 나머지 곳에서는 getter로 값을 읽으세요. Firebase는 백그라운드에서 일어나는 fetch를 “유령 fetch(ghost fetches)”라고 부르며 먼저 점검할 것으로 꼽습니다.

4. 실시간 업데이트와 잦은 게시

실시간 리스너는 앱이 포그라운드에 있는 동안 연결을 열어 두고, 연결 자체는 무료입니다. 새 템플릿 버전을 게시하면 듣고 있던 모든 기기가 그것을 내려받는데, 이 다운로드 하나하나가 간격을 무시하는 fetch입니다. 나중에 예전 버전을 가진 채 앱을 여는 기기도 같은 식으로 받습니다. 그래서 게시 한 번은 무엇을 바꾸든, 다음 게시 전까지 앱을 실행하는 기기마다 최대 한 번의 fetch가 듭니다.

기기 20만 대에 하루 10번 게시하면 실시간 업데이트만으로 fetch가 최대 200만 건이고, 1만 건당 $0.06로 그날 약 $12입니다. 작은 수정을 여러 번 게시하지 말고 한 번에 모아 게시하세요. 리스너는 킬 스위치처럼 즉시 바뀌어야 하는 곳에만 다세요.

5. 서버 요청마다 템플릿 불러오기

아직 Preview인 서버 쪽 Remote Config는 Admin SDK로 템플릿 전체를 내려받고, 다운로드 하나가 fetch 하나입니다. Cloud Functions나 Cloud Run 핸들러 안에서 getServerTemplate()을 부르면 요청마다 하나씩이라, 바쁜 엔드포인트 하나만으로도 하루 10만 건을 넘을 수 있습니다. 서버 인스턴스마다 한 번 불러오고 타이머로 새로 고치세요.

import { initializeApp } from "firebase-admin/app";
import { getRemoteConfig } from "firebase-admin/remote-config";

initializeApp();

const DEFAULTS = { welcome_message: "Hello" };
// At most one fetch per server instance every 10 minutes.
const REFRESH_MS = 10 * 60 * 1000;

let templatePromise; // one template per server instance, kept between requests
let loadedAt = 0;

export async function getConfig() {
  if (!templatePromise) {
    loadedAt = Date.now();
    templatePromise = getRemoteConfig()
      .getServerTemplate({ defaultConfig: DEFAULTS })
      .catch((err) => {
        templatePromise = undefined; // try again on the next request
        throw err;
      });
  }

  const template = await templatePromise;

  if (Date.now() - loadedAt > REFRESH_MS) {
    loadedAt = Date.now();
    // Refreshes in the background. Until it lands, requests get the
    // values already loaded.
    template.load().catch((err) => console.error("Refresh failed", err));
  }

  return template.evaluate();
}

10분마다 새로 고치면 트래픽과 상관없이 실행 중인 인스턴스 하나당 하루 144건입니다. REST API로 템플릿을 읽는 스크립트와 CI 작업도 세지만, 문제가 될 만큼 자주 돌지는 않습니다.

Blaze로 옮길 때 예산 알림 걸기

Blaze에는 지출 상한이 없습니다. Google Cloud 콘솔에서 결제 > 예산 및 알림(Billing > Budgets & alerts)을 열고, 위 계산기가 알려 준 금액 근처로 프로젝트 예산을 만드세요. 기본 설정이면 금액의 50%, 90%, 100%에서 결제 관리자에게 이메일을 보냅니다. 지출을 멈추지는 않으니, 첫 메일이 오면 사용량 및 결제 페이지의 Remote Config 차트를 확인하세요.

자주 묻는 질문

Firebase Remote Config는 아직 무료인가요?

프로젝트당 하루 fetch 10만 건까지는 Spark와 Blaze 모두 무료입니다. 기기에서 값을 읽는 것, A/B Testing, 롤아웃, 개인화에는 추가 비용이 없습니다. 하루 10만 건을 넘으면 Blaze 프로젝트는 1만 건당 $0.06를 내고, Spark 프로젝트는 30일 유예 뒤 스로틀링됩니다.

기존 프로젝트는 언제부터 과금되나요?

Blaze 프로젝트는 2027년 2월 1일부터입니다. Spark 프로젝트는 청구되지 않습니다. 대신 2026년 12월 1일부터 하루 10만 건 한도가 적용되고, 2026년 11월 15일 전에 Blaze로 업그레이드하면 과금이 2027년 2월 1일부터 시작됩니다.

10만 건 한도는 앱별인가요, 프로젝트별인가요?

프로젝트별입니다. Firebase 프로젝트에 등록된 앱이 모두 함께 씁니다.

코드를 바꾸거나 SDK를 업데이트해야 하나요?

아니요. 집계는 Firebase 서버에서 하고, Spark와 Blaze를 오가도 앱에서 바꿀 것은 없습니다. 코드를 바꾸는 건 fetch를 줄이고 싶을 때뿐입니다.

실시간 Remote Config는 비용이 더 드나요?

열어 둔 연결은 세지 않습니다. 게시한 뒤 새 템플릿 버전을 내려받는 것은 기기마다 한 번씩 세고, 이 다운로드는 최소 fetch 간격을 무시합니다.

사용자에게 새 Remote Config 값이 안 가는 이유는 뭔가요?

대개는 최소 fetch 간격 때문입니다. 기기는 기본적으로 최대 12시간 동안 값을 그대로 쓰고, 가져온 값은 activate()를 해야 적용됩니다. 새 요금 이후로는 하루 10만 건을 넘은 지 30일이 지나 스로틀링된 Spark 프로젝트일 수도 있습니다. 간격을 줄이기 전에 사용량 및 결제의 Remote Config 섹션부터 확인하세요. 간격을 줄이면 스로틀링이 더 심해집니다.

출처

전체 글 →