Cloudflare를 월 5달러 이하로 유지하는 방법 (그리고 청구서를 은근히 늘리는 것들)
요약
Cloudflare Workers를 활용한 웹사이트 운영 비용을 절감하는 방법을 안내합니다. 기본 플랜의 관대함을 이해하고, 정적 파일 서비스, 캐싱, 봇 차단 등을 통해 불필요한 요청과 CPU 사용을 줄일 수 있습니다. 또한 Queues, KV, R2 등 각 서비스별로 비싼 작업(쓰기, 재시도, HeadObject 호출)을 식별하여 비용 최적화 전략을 제시합니다.
핵심 포인트
- 정적 파일은 무료이며 무제한으로 제공되므로 Worker 코드를 통한 라우팅에 주의하세요.
- Queues의 경우 메시지당 쓰기/읽기/삭제 작업이 발생하며, 재시도는 추가 비용을 유발합니다.
- KV 스토리지에서 카운터 업데이트 같은 핫 패스(hot paths)는 쓰기 작업이 비싸므로 배치 처리를 고려해야 합니다.
- R2 사용 시 모든 요청마다 HeadObject나 ListObjects를 호출하는 습관은 피하고 메타데이터를 D1이나 KV에 저장하세요.
저는 Cloudflare의 $5 Workers 플랜을 사용하여 몇 개의 사이트를 운영하고 있습니다. 기본 플랜은 사람들이 예상하는 것보다 훨씬 많은 것을 커버합니다. 제가 읽었던 대부분의 예상치 못한 청구서는 소유자가 인지하지 못하는 것보다 훨씬 더 많은 작업을 수행하는 몇 가지 제품에서 발생합니다. 돈이 어디로 가는지 알려드리겠습니다.
먼저 결제 알림 및 사용량 경고를 켜세요. 통제 불능 루프는 카드 명세서가 아닌 이메일로 표시되어야 합니다.
Workers: 기본 플랜은 관대합니다
유료(Paid) 플랜은 월 $5이며, 10M 요청과 30M CPU 밀리초를 포함합니다. 그 이상은 요청당 백만 개에 $0.30, CPU ms당 백만 개에 $0.02입니다. 대역폭(Bandwidth)은 청구되지 않습니다.
- 정적 파일 서비스: 정적 자산으로 파일을 제공하세요. 정적 자산은 무료이며 무제한입니다. 이를 Worker 코드를 통해 라우팅하면 요청과 CPU를 사용합니다.
- 사용자별로 변경되지 않는 응답 캐싱: Workers Caching에서 캐시 적중(cache hit)도 여전히 요청으로 계산되지만, Worker가 실행되지 않기 때문에 CPU 시간은 건너뜁니다. (Cache API에 대한 청구는 제가 확인하지 못했으므로 별도로 확인하세요.)
- 봇 차단: 봇이 코드에 도달하기 전에 막으세요. WAF rate-limiting 규칙은 Worker가 실행되기 전에 트래픽을 중지시킵니다.
Queues: 메시지당 세 가지 작업
각 메시지는 세 가지 작업을 비용으로 발생시킵니다: 쓰기(write) 1회, 읽기(read) 1회, 삭제(delete) 1회. 유료 플랜은 월 1M 작업을 포함하며, 그 이후는 백만 개당 $0.40입니다.
월 1백만 개의 메시지는 3M 작업이며, 청구 가능한 것은 2M으로 약 $0.80입니다. 저렴하지만 볼륨에 따라 증가하므로 인라인(inline)으로 처리할 수 있는 작업은 큐에 넣지 마세요.
- 배치 처리: 배치 처리가 개수를 줄이지는 않습니다. 작업은 메시지당 계산되므로, 배치 처리는 효율성을 높이지만 청구액을 낮추지는 못합니다.
- 재시도(Retries): 재시도는 추가 비용이 발생합니다. 재시도할 때마다 읽기 1회가 추가됩니다.
KV: 쓰기가 비싼 부분입니다
유료 플랜은 월 10M 읽기와 1M 쓰기를 포함합니다. 그 이후에는 읽기는 백만 개당 $0.50, 쓰기는 백만 개당 $5.00이므로, 쓰기 비용은 읽기 비용의 약 열 배에 달합니다. 삭제(Deletes) 및 목록 조회(list operations) 작업도 1M 초과 시 백만 개당 $5로 청구됩니다.
모든 요청이 KV에서 카운터를 업데이트한다면, 읽기는 저렴해 보여도 월 5M 쓰기만 해도 쓰기 비용으로만 약 $20가 발생할 수 있습니다.
KV에 쓰기 작업(writes)을 핫 패스(hot paths)에서 제외하세요. 업데이트는 배치 처리하거나, 카운터를 D1 또는 Durable Object에 두세요. 요청 경로에서 키를 나열하는 것을 피하세요.
R2: 저렴한 스토리지, 측정 가능한 작업량
무료 티어에서는 월 10 GB의 스토리지, 1M개의 Class A 작업 및 10M개의 Class B 작업을 제공합니다. 이를 초과할 경우, 스토리지는 GB당 $0.015이며, 따라서 100 GB는 약 $1.50입니다.
Class A(쓰기, 나열, 멀티파트 업로드)는 백만 개당 $4.50입니다. Class B(읽기, HEAD)는 백만 개당 $0.36입니다. 삭제는 무료입니다. Workers, S3 API 및 r2.dev를 통해 제공되는 데이터에 대한 이그레스(Egress)는 무료입니다.
비싼 습관은 모든 요청마다 HeadObject 또는 ListObjects를 호출하는 것입니다. 대신 메타데이터를 D1이나 KV에 저장하세요.
D1: 스캔된 행에 대해 비용 지불
유료 플랜에는 월 25B개의 읽기(read) 및 50M개의 쓰기(write)가 포함됩니다. 이를 초과할 경우, 읽은 행은 백만 개당 $0.001이며, 기록된 행은 백만 개당 $1.00입니다.
쿼리가 반환하는 행이 아니라 쿼리가 스캔하는 행에 대해 청구됩니다. 인덱싱되지 않은 컬럼에 필터를 적용하면 세 개의 행을 반환하더라도 전체 테이블을 스캔할 수 있습니다. 자주 필터링하는 컬럼에는 인덱스를 만드세요. 인덱스가 있는 쓰기 작업은 추가적인 쓰인 행 하나를 추가하며, 문서에 따르면 이는 일반적으로 읽은 행의 감소로 상쇄됩니다.
Durable Objects: 유휴 상태는 무료, 활동 상태는 아님
유료 플랜에는 월 1M개의 요청 및 400,000 GB-초가 포함됩니다. 이를 초과할 경우, 요청은 백만 개당 $0.15이며, 지속 시간(duration)은 백만 GB-초당 $12.50입니다.
지속 시간은 메모리를 사용했는지 여부와 관계없이 객체당 128 MB로 청구됩니다. 항상 켜져 있는(always-on) 객체는 월 약 336,000 GB-초를 사용하며, 이는 포함된 양 안에 들어옵니다. 항상 켜져 있는 두 개의 객체는 약 273,000을 초과하여 대략 $3.40입니다.
• 휴면(hibernation) 기능이 없는 WebSockets. accept() 호출은 전체 연결에 대해 비용을 청구합니다. WebSocket Hibernation API를 사용하면 메시지 사이에 객체를 잠재울 수 있습니다.
• 보류 중인 I/O (Pending I/O). 최대 15분 동안 객체를 메모리에 유지할 수 있으며, 이 시간이 청구됩니다.
• 알람(Alarms)은 요청으로 간주됩니다.
• 유휴 상태의 잠재울 수 있는(hibernatable) 객체는 비용이 청구되지 않습니다. 목표는 이를 잠들게 하는 것입니다.
Workers AI: 답변 캐싱하기
Free와 Paid 모두 하루에 10,000 Neurons를 포함합니다. 그 이상은 Paid 플랜의 경우 1,000 Neurons당 $0.011입니다. Free 사용자는 일일 할당량을 초과할 수 없습니다.
@cf/meta/llama-3.2-1b-instruct의 경우, 출력 토큰은 백만 개당 약 18,252 Neurons가 소요되며, 이는 대략 백만 개의 출력 토큰당 $0.20입니다. 입력 토큰은 백만 개당 약 2,457 Neurons가 소요됩니다. 무료 일일 할당량으로는 해당 모델에서 하루에 약 550k개의 출력 토큰을 처리할 수 있습니다. 요금은 모델별로 다르므로 모델 페이지를 확인하세요.
가장 큰 낭비는 동일한 입력으로 매번 모델을 호출하는 것입니다. 결과를 캐싱하고, 임베딩 작업을 배치(batch) 처리하며, 허용 가능한 출력을 제공하는 가장 작은 모델을 선택하세요.
벡터화: 질의 공식은 인덱스 크기에 비례합니다
질의되는 차원과 저장된 차원을 벡터화하세요. 문서에는 쿼리에 대한 다음 공식을 제시하고 있습니다:
((질의된 벡터 + 저장된 벡터) × 차원 × $0.01 / 1,000,000)
따라서 각 질의 비용은 단순히 반환되는 결과의 개수가 아니라 인덱스에 포함된 벡터의 개수에 따라 달라집니다. 저장된 차원은 1억 개당 약 $0.05입니다. 질의는 실행하지 않으면 무료입니다.
배포하기 전에 사용자의 벡터 수와 차원을 사용하여 공식을 계산하고 테스트하세요. 인덱스는 작게 유지하고, 가능하다면 메타데이터로 필터링하세요.
브라우저 렌더링: 브라우저는 비용이 많이 듭니다
Paid 플랜에는 월 10시간의 브라우징 시간이 포함되며, 추가 시간은 시간당 $0.09입니다. Browser Sessions(Puppeteer, Playwright, CDP)의 경우, 동시 접속하는 브라우저가 10개를 초과할 때마다 평균적으로 매월 $2가 비용이 발생합니다.
청구는 월 총액을 가장 가까운 시간 단위로 반올림하며, 30분 이상은 올림 처리됩니다. 따라서 100시간은 청구 가능한 90시간이며, 약 $8.10입니다.
가능할 때는 fetch를 사용하세요. 작업을 마쳤을 때 세션을 종료하세요. 헤드리스 브라우저는 실행 속도가 느리고 열어두는 데 비용이 많이 들므로, 페이지가 JavaScript를 필요로 할 때만 사용하세요.
스트리밍: 누가 보든 안 보든 저장 비용이 발생합니다
저장된 분(Stored minutes)은 1,000분당 $5이며 선불입니다. 전송된 분(Delivered minutes)은 1,000분당 $1입니다. 인그레스(Ingress)와 인코딩은 무료이며, 별도의 대역폭 요금은 없습니다.
재생하지 않는 영상도 저장 공간 비용이 발생합니다. 필요 없는 원본은 삭제하세요.
이미지: 고유 변환(unique transformations)
이미지는 매월 고유 변환 횟수만큼 청구됩니다. Paid 플랜에는 5,000회가 포함되어 있으며, 이후는 1,000회당 $0.50이 부과됩니다. 같은 월에 동일한 변환을 반복 요청해도 다시 청구되지 않습니다.
사용하지 않는 크기로 이미지를 생성할 필요가 없습니다. 바인딩의 .info() 메서드 호출은 비용이 발생하지 않습니다.
체크리스트
- 먼저 결제 알림(billing alerts)을 켜세요.
- 정적 파일은 정적 자산으로 제공하세요.
- 사용자별로 변경되지 않는 것은 캐싱하세요.
- WAF에서 봇에 속도 제한(Rate-limit)을 설정하세요.
- Queues, KV 및 R2의 요청당 작업 횟수를 계산하세요.
- 필터링하는 D1 컬럼을 인덱싱하세요.
- KV 쓰기 작업을 핫 패스(hot paths)에서 제외하세요.
- Durable Objects가 휴면 상태(hibernate)가 되도록 두세요.
- AI 결과를 캐싱하고 작동하는 가장 작은 모델을 사용하세요.
- 출시 전에 실제 숫자로 Vectorize 공식을 계산해 보세요.
- 브라우저 세션을 닫고, fetch로 충분할 때는 브라우저를 사용하지 마세요.
- 사용하지 않는 Stream 비디오를 삭제하고, 아무도 사용하지 않을 이미지 크기 생성은 피하세요.
이러한 대부분의 제품들은 작은 사이트에는 충분한 무료 할당량을 가지고 있습니다. 청구서가 커지는 경우는 단일 제품이 예상치 못한 작업을 수행할 때입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기