관련 글: 2026.03.20 - [프로젝트/OpenCSP] - k3s에 lago 올려보기
k3s에 lago 올려보기
2026.03.20 - [프로젝트] - OpenCSP (1) 프로젝트 내용 정리 OpenCSP (1) 프로젝트 내용 정리진행 중인 오픈소스 프로젝트 OpenCSP의 깃허브 문서가 영어로만 있어서 한글로도 정리해보고 싶어졌다. https://gith
miiml.tistory.com
위 관련 글에서 lago를 Core에 배포했을 때
여러 핵심 기능들이 유료로 막혀있어서 다른 빌링 도구를 찾아보고 있었다.
그런데 찾아봐도 스택에 kafka 등을 필수로 요구하는 경우가 많아 k3s에 올리기 너무 무겁거나 필요한 billing 기능을 일부만 제공해서 적합한게 별로 없는거 같았음 (사실 이런 경우들도 고려해서 개발이 되어야하긴 하는데..)
근데 좀 더 찾아보면서 Lago도 UI만 막혀있고 핵심 API 기능들은 문제 없다는 걸 알게됐다.
이러면 Console에서 별도의 빌링 페이지를 개발하고 데이터만 가져와주면 기존 설계대로 구성이 가능할 거 같다.
처음 생각해본건 비즈니스 로직에서 유료 이벤트가 발생하면 lago의 API Endpoint에 요청을 보내주고,
빌링 페이지에서 조회가 필요한 부분이 있으면 Lago Web의 API로 가져와서 보여주는 방식인데 (이게 지금 시점 MVP에 적용된 방식)
문제는 이렇게 만들면 사용자가 늘어났을 때 불필요한 내부 트래픽이 많이 발생할 거 같기 때문에 (Fan-out Exprosion) 사용자 요청이 있으면 최초에만 불러와서 데이터를 캐싱해두고 이후는 그 데이터를 참조하는 구조를 생각해봤다.
요청은 확실히 줄어들겠지만 여전히 뭔가 부족한 거 같다.
그래서 AI한테 질문해보니까
하나의 트랜젝션(비즈니스 로직에서)이 진행될 때 Lago와 BE DB에 동일한 트렌젝션 ID로 데이터를 미러링해두고
사용자에게 보여주는 데이터는 BE DB(시계열 데이터)에서 실제 청구에 필요한 데이터는 lago에서 가져가는
아래 같은 transactional outbox 패턴을 권장한다고 한다.
def process_business_logic():
with db.transaction():
do_business_work() # 비즈니스 데이터 변경
my_db.insert_event(...) # 미러 (같은 DB면 원자적)
outbox.insert(lago_payload) # 발송 대기열에 기록
# 트랜잭션 커밋 후 워커가 비동기로 Lago에 전송
위 패턴의 장점은
이렇게 해주면 중복 트래픽 대부분이 내부 DB 참조로 바뀌니까 위에서 고민했던 내부 트래픽 문제가 많이 해결된다.
(MSA 내부 트래픽이 BE - DB 트래픽 구간에 합쳐지면서 관리포인트가 1개로 합쳐짐)
결론은 아래 기능들은 Lago가 담당하게 하고 (이미 다 지원해주니까)
위에 기능들 중에 초기화 필요한 부분은 BE에 Seeder로 만들어두고, Metric 값들(갱신이 자주 발생하지 않는)도 캐싱을 해두거나 한다면
BE에도 데이터가 있으니까 lago같은 빌링 서비스가 죽었을 때의 fallback도 어느정도 가능할거 같다. (물론 이러면 fallback이 완벽하지 않고 유실되는 부분도 있을거라 좀 더 고민이 필요)
참고
Lago 기본 제공 메트릭들은 아래 문서를 보면된다.

그리고 BE에서 등록한 메트릭들 예시

| OpenCSP MVP 개발 후기 (Core + Console 프로토타입) (0) | 2026.05.08 |
|---|---|
| Teleport 거쳐서 사용자 리소스(VM) 연결하기 (0) | 2026.04.30 |
| Ansible Semaphore로 VM post-provisioning하기(2) (2) | 2026.04.13 |
| Ansible Semaphore로 VM post-provisioning하기 (0) | 2026.04.03 |
| OpenCSP Console로 VM 생성해보기 (0) | 2026.03.28 |