Skip to Content
문서제한과 정책

제한과 정책

Deplite는 워크플로우 폭주를 방지하기 위해 여러 종류의 제한을 제공해요.
정의는 워크플로우 YAML의 limits: 블록에 적어요.

Cooldown

마지막 실행 후 지정한 시간 동안 다음 실행을 막아요.

limits: - type: cooldown after: 5m # 5분 on: success # success: 성공한 실행만 카운트 # any: 모든 실행 카운트
  • after: Go duration 문법 (30s, 5m, 1h, 2h30m)
  • on:
    • success — 성공 후에만 쿨다운 시작 (실패는 즉시 재시도 가능)
    • any — 어떤 결과든 쿨다운 시작 (실패 폭주 방지)

리밋이 발동하면 Job은 status: rejected, rejectReason: rate_limited, limitType: cooldown로 기록돼요.
응답에 retryAfterSeconds도 함께 들어와요.

Token Bucket

용량과 충전 속도를 가진 토큰 버킷이에요. 실행마다 1개 토큰을 소비해요.

limits: - type: bucket capacity: 5 # 최대 토큰 5개 refill: 1/1h # 1시간마다 1개 충전
  • capacity: 1 이상의 정수
  • refill: <count>/<duration> 형식 (1/10m, 5/1h)

리밋 발동 시 응답 형태는 cooldown과 같지만 limitType: bucket이에요.

한 워크플로우에 두 종류 함께 쓰기

limits: - type: cooldown after: 1m - type: bucket capacity: 10 refill: 1/5m

cooldown 1개 + bucket 1개까지 허용돼요.
“1분에 한 번 이하 + 시간당 12회 이하”처럼 짧은 보호와 긴 보호를 함께 걸 때 좋아요.

상태 저장 위치

리밋 상태는 Agent 디스크의 ./logs/limits/<workflow-name>.json에 저장돼요.
Agent를 재시작해도 상태가 유지돼요.

{ "cooldown_last_finish_at": "2026-05-31T10:30:00Z", "cooldown_last_finish_status": "success", "bucket_tokens": 2.5, "bucket_updated_at": "2026-05-31T10:29:45Z", "bucket_init": true }

force 우회

리밋을 명시적으로 우회해야 할 때(긴급 핫픽스 등)는 force: true로 호출해요.

curl -X POST .../triggers/<id>/run-manual \ -d '{"ref": "main", "force": true, "forceReason": "hotfix CVE-2026-X"}'
  • owner 권한 + 워크플로우의 force_allowed: true(기본)일 때만 허용
  • Job 기록에 forced: true, forceReason, bypassedLimits로 남음
  • Audit log에 trigger.force_run 액션이 기록

큐잉

Agent는 동시에 처리할 수 있는 Job 수에 제한이 있어요(기본 큐 100).
큐가 가득 차면 새 Job은 즉시 status: rejected, rejectReason: queue_full로 거부돼요.
이때는 Agent를 여러 대로 늘리거나 워크플로우당 동시성을 제어하세요.

중복 제거 (Idempotency)

Webhook 호출 시 Idempotency-Key 헤더를 보내면, 같은 키의 요청은 첫 Job을 그대로 돌려줘요.

curl -X POST .../triggers/<id>/run \ -H "Idempotency-Key: deploy-2026-05-31-001" \ -d '{"ref": "main"}'

같은 키로 2번째 호출이 와도 새 Job이 만들어지지 않고, 첫 Job의 jobId를 반환해요.

서버 측 토큰 레이트 리밋

API Token 발급 시 분/시간/일당 호출 횟수를 제한할 수 있어요.

{ "name": "CI/CD", "scopeType": "trigger", "triggerIds": ["..."], "rateLimitPerMinute": 10, "rateLimitPerHour": 100, "rateLimitPerDay": 1000 }

워크플로우 단위 리밋(Agent 측)과 토큰 단위 리밋(서버 측)은 서로 독립적이에요.

실전 시나리오

시나리오 A — 폭주하는 webhook 보호

PR 머지마다 배포 webhook이 호출되는데, 여러 PR이 동시에 머지되면 동시 빌드가 폭주해요.

name: deploy-prod limits: - type: cooldown after: 90s - type: bucket capacity: 5 refill: 1/3m

90초 안에 두 번째 호출이 들어오면 rejected. 또 시간당 약 20회 이상은 bucket이 마름.

시나리오 B — 헬스체크는 무조건 5분 간격

name: healthcheck limits: - type: cooldown after: 4m on: any # 실패해도 즉시 재시도 금지 steps: - run: curl -fsS https://app.example.com/health

Cron 트리거를 1분 간격으로 걸어도 안전해요. on: any 덕분에 실패 폭주가 막혀요.

시나리오 C — 긴급 핫픽스로 리밋 우회

평소엔 30분 cooldown이지만 보안 패치는 즉시 배포해야 해요.

curl -X POST https://app.deplite.io/api/triggers/<id>/run-manual \ -H "Authorization: Bearer $JWT" \ -d '{ "ref": "hotfix/cve-2026-x", "force": true, "forceReason": "CVE-2026-X 패치 — Sec팀 승인" }'

Job 기록:

{ "id": "j-9ab2", "status": "running", "forced": true, "forceReason": "CVE-2026-X 패치 — Sec팀 승인", "bypassedLimits": ["cooldown"] }

Audit log:

2026-05-31T13:42:18Z trigger.force_run actor: user_alice trigger: deploy-prod metadata: { ref: "hotfix/cve-2026-x", reason: "..." }

거부 응답 형태

리밋에 걸리면 webhook 호출은 즉시 rejected를 받아요.

{ "jobId": "j-9ab3", "status": "rejected", "rejectReason": "rate_limited", "limitType": "cooldown", "retryAfterSeconds": 158 }

대시보드 Jobs 화면에서도 동일한 정보가 보여요. 재시도 자동화 시 retryAfterSeconds만큼 대기 후 다시 호출하면 돼요.

다음으로

  • 트리거 — force 옵션 사용 예
  • API — 토큰 레이트 리밋 설정
최종 수정 일자: