Skip to content

feat: 일일 토큰 한도 집행 - #51

Merged
yessjun merged 1 commit into
mainfrom
feat/llm-daily-quota
Aug 11, 2026
Merged

feat: 일일 토큰 한도 집행#51
yessjun merged 1 commit into
mainfrom
feat/llm-daily-quota

Conversation

@yessjun

@yessjun yessjun commented Aug 11, 2026

Copy link
Copy Markdown
Member

📝 작업내용

  • 승인이 부여한 일일 토큰 한도를 실제로 집행
    • 종전에는 그 값이 결정 기록에만 저장되고 키에도 게이트웨이에도 가지 않음
    • 승인 화면은 한도가 걸렸다고 말하고 아무것도 집행하지 않던 상태
  • 긴 창 한도는 api가 판단하고 게이트웨이는 거부만 함, 두 서비스 사이의 약속대로
    • 짧은 창은 요청의 시작과 끝을 보는 쪽 몫이지만, 하루 누적은 게이트웨이가 갖지 않기로 한 영속 상태를 요구
    • 게이트웨이 쪽은 이미 구현되어 있어 변경 없음
  • 플래그를 조회 시 계산하지 않고 컬럼으로 저장
    • 게이트웨이는 세대가 움직일 때만 문서를 받고 세대는 쓰기에만 움직임
    • 조회 시 계산하면 DB에서는 맞으면서 게이트웨이에는 한 번도 도달하지 않음
  • 변화가 있을 때만 세대를 올림
    • 무조건 올리면 5분마다 전체 문서를 넘기게 되어 미변경 경로가 무의미해짐
  • 자정 초기화는 별도 장치 없이 평소 스윕이 처리
    • 00시 이후 그날 합계가 0이므로 스윕이 자기가 세운 플래그를 스스로 내림
    • 그래서 아무도 쓰지 않을 때도 계속 돌아야 함, 스윕은 키를 푸는 쪽이지 잠그는 쪽이 아님
  • Flyway V84, 기존 승인의 부여 값도 함께 이관

⭐️ 검증

  • 검증 스크립트 통과
  • 전용 스위트 6건, 세대를 올리는 경우와 올리지 않는 경우를 각각 고정
    • 둘 다 조용히 실패하는 종류라 양방향을 함께 검사

💬 리뷰 포인트

  • 집행은 전송 주기와 폴링만큼 늦어 배치 하나만큼 초과 가능, 사후 계수의 본질적 한계
  • 키가 풀리지 않은 이벤트는 어느 한도에도 계상하지 않음, 한 사람의 잘못된 키 반복이 남의 한도를 소진하면 안 되므로

The granted daily figure lived only in the record of what was decided.
The approval screen said a limit had been granted; nothing carried it to
the key, the gateway has no daily concept at all, and so nothing enforced
it. Both parties believed a limit was in place.

The api counts and the gateway refuses, as the internal contract already
specified: short-window limits belong where request start and end are
observed, but a day's running total would need durable per-key state the
gateway was built not to have -- and every usage event arrives here
anyway.

The flag is a column rather than something computed inside the sync
query, and that is the load-bearing choice. The gateway is handed a
document only when the generation moves, and only a write moves it. A
quota computed at read time would be perfectly correct in the database
and would never once reach the gateway.

Which also means bumping only when a row actually changed: an
unconditional sweep would hand out a full document every five minutes
forever, defeating the unchanged path. Both directions are covered by
tests because both fail silently.

Midnight needs no separate reset -- after 00:00 KST the day's sum is zero
and the ordinary sweep clears what it set. That is why the sweep must
keep running while nothing is being used: it is what releases a key, not
what locks one.

Enforcement lags by a shipping window plus a poll, so a key can overshoot
by roughly one batch. That is inherent to counting after the fact.
@yessjun
yessjun merged commit fef2c61 into main Aug 11, 2026
1 check passed
@yessjun
yessjun deleted the feat/llm-daily-quota branch August 11, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant