SaaS 크레딧 과금에서 잔액 컬럼을 직접 수정하는 방식은 빠르지만 위험합니다. 해시스크래퍼는 모든 차감을 이력(원장)으로 기록하고, 잔액은 이력의 합산으로 산출하는 원장 기반 과금 아키텍처를 사용합니다. 이 방식은 과금 투명성, 디버깅 용이성, 대량 동시 처리 성능에서 모두 유리합니다.
TL;DR
- 잔액을 직접 수정(UPDATE)하면 빠르지만, 오차가 나도 원인을 추적할 수 없습니다
- 모든 차감을 이력(원장)으로 기록하면 모든 거래를 증명할 수 있습니다
- row lock(SELECT FOR UPDATE)은 동시 요청에서 병목이 됩니다. 원장 INSERT는 병목이 없습니다
- 해시스크래퍼는 하루 수백만 건 수집, 수십만 건 크레딧 차감 기준, 원장 방식이 속도와 정확성 모두 우위입니다
- 과금 아키텍처는 엔지니어링이 아니라 고객과의 약속입니다
왜 대부분의 SaaS는 잔액을 직접 수정할까요?
크레딧을 차감할 때, 대부분의 SaaS는 이렇게 합니다.
잔액 컬럼을 열고, 숫자를 빼고, 저장합니다.
UPDATE service_tickets SET use_credit = use_credit + 10 WHERE id = ?
빠릅니다.
직관적입니다.
거의 모든 과금 튜토리얼이 이 방식을 가르칩니다.
저희도 처음엔 그랬습니다.
잔액만 보면 무엇을 잃게 될까요?
프로덕션에서 문제가 생겼을 때,
물어볼 곳이 없었습니다.
"이 고객의 크레딧이 왜 3개 부족하지?"
"어제 실패한 요청에서 차감이 됐나, 안 됐나?"
"이 숫자가 맞는 건지 어떻게 검증하지?"
잔액은 결과만 보여줍니다.
과정은 사라져 있습니다.
연필로 쓴 가계부와 같습니다.
지우고 다시 쓰면, 원래 뭐가 적혀 있었는지 알 수 없습니다.
원장 기반 과금이란 무엇인가요?
그래서 저희는 방식을 바꿨습니다.
잔액을 직접 수정하지 않습니다.
모든 차감을 별도의 이력 레코드로 남깁니다.
잔액은 이력의 합산이 만듭니다.
이력 #1: -10 크레딧 (https://example.com, 성공, 2026-03-07 14:32)
이력 #2: -10 크레딧 (https://news.site.com, 성공, 2026-03-07 14:33)
이력 #3: 0 크레딧 (https://blocked.com, 실패, 2026-03-07 14:35)
─────────────────
잔액 = 총 크레딧 - 이력 합산
볼펜으로 쓴 복식부기입니다.
수정할 때도 줄을 긋고, 새 줄에 씁니다.
어떤 거래도 사라지지 않습니다.
한 건의 차감에는 반드시 기록이 따라붙습니다.
언제, 어떤 URL을, 몇 크레딧으로, 성공했는지 실패했는지.
실패한 요청은 차감하지 않습니다.
차감했다면, 반드시 그 이유가 남아 있습니다.
원장 방식이 대량 처리에서도 빠른 이유는?
여기서 의문이 생깁니다.
"이력을 매번 INSERT하면 느리지 않을까?"
해시스크래퍼는 2018년부터 8년간 5,000개 이상 웹사이트에서 데이터를 수집해온 회사입니다.
하루 수백만 건의 데이터를 수집하고, 수십만 건의 크레딧 차감을 처리합니다.
속도를 포기할 수 없습니다.
그런데 역설적으로,
원장 방식이 더 빠릅니다.
잔액을 직접 수정하려면 row lock(SELECT FOR UPDATE)이 필요합니다.
같은 고객의 요청이 동시에 10건 들어오면,
9건은 줄을 서서 기다려야 합니다.
교통경찰이 차를 한 대씩 통과시키는 것과 같습니다.
이력을 남기는 방식은 다릅니다.
INSERT는 다른 행을 잠그지 않습니다.
10건이 동시에 들어와도 10건 모두 바로 기록됩니다.
차선이 10개인 고속도로입니다.
잔액은 나중에 합산하면 됩니다.
| 방식 | 동시 10건 처리 | 병목 | 장애 추적 |
|---|---|---|---|
| 잔액 직접 수정 (row lock) | 순차 처리 (1건씩) | 심각 | 불가능 |
| 원장 기록 (INSERT) | 병렬 처리 (10건 동시) | 없음 | 이력으로 즉시 추적 |
느려 보이는 방식이
대량 처리에서 오히려 병목이 없습니다.
과금 아키텍처는 왜 고객과의 약속일까요?
이건 엔지니어링 취향의 문제가 아닙니다.
과금 아키텍처는 결국 이 질문에 대한 답입니다:
- 고객이 "내 크레딧 어디 갔어?"라고 물었을 때, 즉시 답할 수 있는가?
- 시스템 오류로 잘못 차감됐을 때, 정확히 어디서 틀렸는지 찾을 수 있는가?
- 실패한 요청에는 과금하지 않았음을 증명할 수 있는가?
잔액 컬럼 하나로는 이 질문에 답할 수 없습니다.
이력이 있어야 답할 수 있습니다.
저희는 4명짜리 작은 회사입니다.
작기 때문에 대충 해도 되는 게 아니라,
작기 때문에 더 제대로 해야 합니다.
고객의 크레딧 한 건이 어디에 쓰였는지
언제든 꺼내 보여줄 수 있는 것.
그게 저희가 과금 시스템에 볼펜을 선택한 이유입니다.
잔액을 깎지 마세요. 이력이 잔액을 만들게 하세요.
FAQ
Q. 원장 방식이면 잔액 조회가 느리지 않나요?
잔액은 이력의 합산으로 계산하지만, 실시간으로 매번 집계하지는 않습니다. 주기적으로 캐싱하거나 사후 정산하면 조회 성능에 영향이 없습니다. 이력이 수십만 건이어도 인덱스 기반 합산은 수 밀리초 이내입니다.
Q. 실패한 요청에도 이력을 남기나요?
네. 실패 이력도 기록하되, 차감 금액은 0입니다. "이 요청은 실패했고, 과금하지 않았다"는 사실 자체가 고객 신뢰의 근거가 됩니다.
Q. row lock 방식이 적합한 경우도 있나요?
동시 요청이 거의 없는 소규모 서비스에서는 row lock이 더 단순하고 효과적입니다. 하지만 API 과금처럼 동시 요청이 빈번한 구조에서는 원장 방식이 성능과 추적성 모두에서 유리합니다.
Q. 해시스크래퍼의 과금 단위는 어떻게 되나요?
1 URL 요청 = 10 크레딧이며, 수집과 변환이 성공한 경우에만 차감됩니다. 실패 시 크레딧 손실은 없습니다.




