IT, MIND & CAREER / EDITORIAL DESK

흐름을 읽고, 다음 선택을 설계합니다.

기술의 변화와 사람의 판단, 그리고 오래 가는 커리어를 한 장의 리포트로 정리합니다.

EDITOR'S SELECTION

지금, 먼저 읽을 리포트

변화의 신호를 읽는 세 편의 이야기

THE ARCHIVE

최근 리포트

IT 최신동향 조회 35

좌석 기반 요금제 버리고 사용량 기반 메터링 구축한 이유

좌석 기반 요금제 버리고 사용량 기반 메터링 구축한 이유

AI 기능을 탑재한 SaaS 제품에서 신규 B2B 고객사를 유치해 매출(ARR)을 늘렸음에도 불구하고, LLM(대형 언어 모델) API 호출 비용이 수백 퍼센트 폭증하며 마진이 무너지는 현상은 현업에서 가장 흔히 발생하는 인프라 및 비즈니스 재앙이다. 전통적인 SaaS처럼 '1인당 월 고정 요금'을 채택했으나, 일부 파워 유저가 하루에 수만 건의 대용량 토큰 추론 프롬프트를 날리면서 유저 1명이 발생시키는 AI 원가가 한 달 구독료의 몇 배를 뛰어넘기 때문이다.

손님이 많이 올수록 손해가 커지는 이 기괴한 구조의 원인은 백엔드 인프라가 단순 HTTP 요청 횟수만 기록할 뿐, 유저가 소모한 입력·출력 토큰의 양과 모델별 가중치를 추적하지 못하기 때문이다. 사용자가 AI 기능을 활발히 쓸수록 제품의 가치는 올라가지만, 회사의 수익성은 밑바닥으로 추락하는 역설에 직면하는 셈이다.

오늘의 핵심을 한 줄로 요약하면, AI 제품에서 전통적인 좌석 기반 요금제를 고집하면 사용자 가치가 증가할수록 회사의 마진이 파괴되는 역설에 직면하므로 사용량 기반(Usage-based) 아키텍처로 조속히 전환해야 한다는 점이다.

무한 리필 뷔페에서 토큰 메터링 기반으로의 전환

전통적인 SaaS 인프라를 '무한 리필 뷔페'에 비유할 수 있다. 손님이 음식을 한 접시 먹든 열 접시 먹든, 매장이 부담하는 한계 비용(Marginal Cost)은 극히 미미하다. 서버 인프라를 일단 구축해 두면 추가 유저가 들어와도 CPU와 메모리 사용량의 증가폭이 완만하기 때문이다. 그래서 전통 SaaS 기업들은 매출 대비 총마진율(Gross Margin)을 80~90% 수준으로 유지할 수 있었다.

반면 AI 우선(AI-first) 기업의 사정은 완전히 다르다. AI 서비스는 '주문할 때마다 고급 한우가 제공되는 고급 레스토랑'과 같다. 유저가 AI에게 질문을 던질 때마다 백엔드에서는 LLM 공급업체(OpenAI, Anthropic 등)나 자체 GPU 서버로 원가가 즉시 발생하는 토큰(Token)을 전송한다.

실제로 최근 업계 데이터에 따르면 AI 우선 기업들의 평균 총마진율은 50~60% 수준에 불과하다. 유저의 입력 토큰 문맥이 길어지고 출력 길이가 길어질수록 비용은 직전 요청 대비 비선형적으로 늘어나기 때문이다.

결국 AI 백엔드 아키텍처는 유저의 모든 행동을 전력계량기처럼 정밀하게 측정하는 '토큰 메터링 엔진'을 내장해야만 한다. API Gateway 단에서 작동하는 실시간 토큰 추적 데이터 구조 예시는 다음과 같다.

{
  "event_id": "evt_98742a12-882f",
  "timestamp": "2026-08-11T09:30:00Z",
  "organization_id": "org_enterprise_01",
  "user_id": "usr_tech_lead",
  "model_name": "claude-3-5-sonnet",
  "metric": {
    "prompt_tokens": 1420,
    "completion_tokens": 350,
    "total_tokens": 1770,
    "raw_cost_usd": 0.00951
  },
  "business_context": {
    "feature_name": "auto_code_review",
    "credit_cost": 12
  }
}
  • 메트릭 분리(Prompt vs Completion): LLM 공급업체마다 입력과 출력 토큰의 단가가 다르므로 이를 엄격히 분리해서 파싱한다.
  • 비동기 이벤팅: 메터링 로직이 메인 추론 API의 응답 지연 시간(Latency)에 영향을 주지 않도록 이벤트 버스로 즉시 이탈시킨다.
  • 가치 기반 크레딧 마핑: 단순 Raw 비용 외에 서비스가 제공한 비즈니스 기능(Code Review, Summary 등)의 가치에 따라 내부 크레딧 차감 수치를 동적으로 계산한다.

고정 무제한 요금제가 초래하는 3가지 아키텍처 비극

많은 팀들이 초기 출시 속도를 높이기 위해 "일단 월 $20에 무제한 AI 제공!"이라는 슬로건을 내걸고 시장에 진입하지만, 백엔드 엔지니어링 관점에서 3가지 결정적인 결함과 직면하게 된다.

첫 번째는 헤비 유저의 체리피킹(Cherry-picking)으로 인한 마진 파고 현상이다. 전체 유저의 5%에 불과한 자동화 스크립트 이용자나 기업 헤비 유저들이 전체 LLM API 비용의 70% 이상을 소모한다. 백엔드에 메터링이 없으면 어떤 유저가 시스템을 오용하고 있는지조차 실시간으로 찾아내지 못한다.

두 번째는 동기식 트랜잭션 DB의 병목 및 동사 패턴이다. AI 요청이 들어올 때마다 유저의 잔여 토큰이나 월간 사용량을 일반 RDBMS의 ACID 테이블에 직접 UPDATE 쿼리로 때리는 경우다.
* 트랜잭션 Lock 병목: 동일 유저나 팀이 동시에 여러 AI 에이전트를 돌릴 경우, DB Row Lock이 걸리면서 AI 추론 응답보다 잔여 크레딧 차감 DB 대기 시간이 더 길어진다.
* DB Connection 고갈: 동시 요청 폭증 시 메터링 쓰기 작업이 Connection Pool을 채워 로그인이나 메인 데이터 조회까지 마비시킨다.

세 번째는 정산 투명성 부재로 인한 CS 대란이다. 각 요청별로 어떤 프롬프트가 나갔고 몇 토큰이 소모되었는지에 대한 추적성(Traceability) 로그가 백엔드에 쌓여있지 않으면 정산 분쟁을 해결할 방법이 없다. 한 B2B AI 서비스는 메터링 없이 무제한 구독제를 운용하다가, 한 유저의 루프문 연속 호출로 하룻밤 사이에 1,200만 원의 API 비용이 청구되어 서비스를 일시 중단하는 참사를 겪기도 했다.

마진율을 지키는 사용량 기반 시스템 3단계 개편안

마진율 붕괴를 막고 안정적인 수익을 확보하려면 백엔드 아키텍처를 다음과 같이 개편해야 한다.

Step 1: 비동기 이벤트 스트리밍 기반의 Zero-Latency 메터링 파이프라인

메인 API 서버가 LLM으로부터 응답을 받는 즉시 토큰 카운트 메터링 이벤트를 발행하고, 메인 DB 대신 Kafka나 NATS 같은 메세지 브로커로 던진다.
* 인메모리 버퍼링: Redis의 Atomic Increment(INCRBYFLOAT) 명령을 사용해 실시간 사용량을 메모리상에서 즉시 갱신한다.
* 시계열 시퀀스 저장: 비동기 Worker가 이벤트를 가져와 ClickHouse나 TimescaleDB 같은 시계열 분석 전용 DB에 Batch 저장하여 메인 지연 시간을 0ms에 가깝게 유지한다.

Step 2: 동적 시맨틱 캐싱 및 모델 라우팅 레이어 구축

모든 질문을 최고 성능의 비싼 모델로 보낼 필요는 없다.
* 시맨틱 캐싱(Semantic Caching): Vector DB를 활용해 기존 답변과 유사도가 95% 이상인 요청은 LLM을 다시 호출하지 않고 캐시된 답변을 반환한다 (원가 0원).
* 지능형 모델 라우팅: 요청 난이도를 분류하는 가벼운 SLM(소형 언어 모델)을 프론트에 배치하여 단순 번역은 저렴한 모델로, 고난도 로직 설계만 고성능 모델로 라우팅한다.

Step 3: 하이브리드 크레딧 메커니즘과 서킷 브레이커 적용

원천 토큰 단가를 유저에게 직접 노출하면 사용자 경험이 복잡해진다. 유저에게는 단순한 '크레딧(Credit)' 개념을 제공하고 백엔드에서 토큰 비용을 크레딧으로 환산한다.
* 실시간 서킷 브레이커: 유저가 설정한 일일 한도나 월간 예산을 초과하면 API Gateway 수준에서 요청을 차단하거나 하위 모델로 Fallback 시킨다.
* 성과 기반 과금 마핑: "생성된 리포트 1건당 10 크레딧"처럼 비즈니스 성과와 크레딧을 매핑한다.

지속 가능한 AI 제품을 완성하는 3가지 아키텍처 원칙

AI 시대에는 소프트웨어의 단위 경제학(Unit Economics)이 과거와 다른 규칙으로 움직인다. 오늘부터 실행에 옮겨야 할 3가지 원칙은 다음과 같다.

첫째, 모든 AI 호출의 토큰 로그를 단 1건도 빠짐없이 비동기 추적하라. 추적할 수 없는 비용은 제어할 수 없다.

둘째, 좌석당 고정 요금제에서 탈피하여 사용량과 성과가 비례하는 하이브리드 크레딧 요금제로 아키텍처를 전환하라.

셋째, 시맨틱 캐시와 모델 라우팅을 인프라 레이어에 내장하여 자체적인 원가 절감 태세를 확립하라.


===================================================================
 [AI 사용량 메터링 및 단위 경제성 점검 체크리스트 & Config]
===================================================================

[1. 백엔드 아키텍처 점검 체크리스트]
[ ] 모든 AI API 요청에서 Input/Output 토큰 수가 파싱되고 있는가?
[ ] 메터링 로직이 메인 추론 트랜잭션과 분리된 비동기 이벤트인가?
[ ] 특정 유저의 한도 초과 시 10ms 이내에 차단할 인메모리 Cache가 있는가?
[ ] 동일 프롬프트 재요청 시 비용을 절감할 시맨틱 캐시가 구축되었는가?
[ ] 유저별/조직별 일간 및 월간 토큰 소모량을 시각화하는 대시보드가 있는가?

[2. Envoy/FastAPI 메터링 미들웨어 설정 예시 (Python/FastAPI Concept)]

from fastapi import FastAPI, Request, Response
import redis.asyncio as redis
import json
import time

app = FastAPI()
redis_client = redis.Redis(host='localhost', port=6379, db=0)

@app.middleware("http")
async def ai_token_metering_middleware(request: Request, call_next):
    if not request.url.path.startswith("/v1/ai/generate"):
        return await call_next(request)
        
    user_id = request.headers.get("X-User-ID", "anonymous")
    
    # 1. 예산 초과 여부 즉시 검증 (Redis 읽기)
    current_usage = await redis_client.get(f"usage:{user_id}:daily_cost")
    if current_usage and float(current_usage) > 50.0:  # $50 일간 한도
        return Response(
            content=json.dumps({"error": "Daily AI cost limit exceeded."}), 
            status_code=429,
            media_type="application/json"
        )
        
    start_time = time.time()
    response = await call_next(request)
    
    # 2. 비동기 메터링 이벤트 발행 (응답 헤더 기반 토큰 추출)
    prompt_tokens = int(response.headers.get("X-Prompt-Tokens", 0))
    completion_tokens = int(response.headers.get("X-Completion-Tokens", 0))
    
    # 가상 단가 계산 ($0.0015 / 1k prompt, $0.002 / 1k completion)
    estimated_cost = (prompt_tokens * 0.0000015) + (completion_tokens * 0.000002)
    
    # Redis 사용량 아토믹 업데이트
    await redis_client.incrbyfloat(f"usage:{user_id}:daily_cost", estimated_cost)
    
    # Kafka/Message Queue로 분석 이벤트 발행 (파이프라인 비동기 전송)
    metering_event = {
        "user_id": user_id,
        "prompt_tokens": prompt_tokens,
        "completion_tokens": completion_tokens,
        "cost": estimated_cost,
        "latency_ms": int((time.time() - start_time) * 1000)
    }
    await redis_client.lpush("stream:metering_events", json.dumps(metering_event))
    
    return response
===================================================================

원문 참고 자료

이 글의 사실 확인과 추가 읽기를 위한 원문입니다. GeekNews

테크 아키텍처 데스크
IT & Mind Trends 에디토리얼 팀 — 클라우드 분산 아키텍처 및 행동 과학 트렌드를 연구하고 실무 트레이드오프를 검증하여 전달합니다.
이전 글
다음 글