PDF 생성 API를 고르는 일은 시작 전에는 쉬워 보입니다. 시장에는 많은 벤더가 있고, 마케팅 문구는 비슷하며, 실제 차이는 수천 개의 문서를 프로덕션에서 렌더링한 뒤에야 드러납니다.
이 체크리스트는 벤더 평가에 바로 쓸 수 있습니다. 특정 벤더에 치우치지 않았고, 조달과 운영, 사후 분석에서 반복적으로 나타난 문제를 바탕으로 했습니다. 8가지 질문에 명확히 답하지 못하면 아직 선택할 정보가 부족합니다.
1. 입력 형식은 HTML, JSON, 템플릿 DSL 중 무엇인가?
가장 중요한 질문입니다. 팀이 무엇을 작성하고, 장애 때 무엇을 디버그할지가 결정됩니다.
- HTML/CSS (Puppeteer, DocRaptor, Prince): 익숙하고 매우 유연하지만 runtime 비용이 높고 deterministic하게 만들기 어렵습니다.
- JSON / 구조화 데이터 (gPdf): 렌더링 비용이 낮고 byte-identical하지만, 데이터 모델에서 문서 모델로 매핑이 필요합니다.
- Template DSL (PDFKit, ReportLab, Apache PDFBox): 완전한 제어와 함께 pagination, layout, font fallback 책임도 모두 가집니다.
모두에게 맞는 정답은 없습니다. 팀에 맞지 않는 답은 있습니다. 3시간짜리 pagination bug를 어느 모델에서 고치고 싶은지 엔지니어에게 물어보세요.
2. Cold-start latency는 얼마이며 예측 가능한가?
WASM이나 native binary는 microseconds 안에 시작할 수 있습니다. Chromium 기반은 seconds가 걸릴 수 있습니다. 이 차이는 트래픽 피크에서 보입니다.
cold worker 첫 요청의 p99, 마지막 요청 후 다시 cold가 되는 시간, status page의 cold-start data 공개 여부를 확인하세요.
3. Render 비용은 어떻게 계산되는가?
흔한 모델:
- 페이지 단가: 예측하기 쉽지만 규모가 커지면 비쌉니다.
- 구독 + 초과 과금: 많은 volume에서 싸지만 usage 예측이 필요합니다.
- Compute 기반: Lambda, container, Chromium memory, cold start 비용을 직접 냅니다.
현재, 5배, 50배 트래픽에서 실제 청구액을 계산하세요. headline price보다 비용 곡선이 중요합니다.
4. 출력은 deterministic한가?
같은 input이면 같은 bytes가 나와야 합니다. CI의 PDF diff, 세금 보관, archive hash, 법무 review에 필요합니다.
Browser-based renderer는 Chromium 버전이 바뀌면 deterministic하지 않은 경우가 많습니다. Native renderer가 보통 유리합니다. engine update 후 bytes가 바뀌는지 직접 물어보세요.
5. Fonts, CJK, RTL을 어떻게 처리하는가?
Font 문제는 PDF production에서 자주 늦게 터집니다. 초기 시장에서는 괜찮다가 다른 script가 필요해지면 □□□□가 보입니다.
어떤 scripts가 기본 포함인지, unknown glyph가 fallback되는지, request 단위 custom font가 가능한지, RTL shaping이 있는지 확인하세요.
6. 어떤 compliance profiles를 지원하는가?
EU invoice, PDF/A archive, XML attachment, digital signature 가능성이 있다면 native support를 확인하세요. “나중에 다른 tool로 변환”은 운영해야 할 pipeline이 하나 더 생긴다는 뜻입니다.
좋은 답은 { profile: "PDF/A-3b" } 또는 { einvoice: { format: "factur-x", xml: "..." } }처럼 구체적입니다.
7. Rendering은 stateless인가? 문서는 어디로 가는가?
Stateless rendering은 request를 받고 PDF를 돌려준 뒤 아무것도 저장하지 않습니다. 저장은 사용자가 관리합니다. 규제가 있는 workload에 적합합니다.
Stateful rendering은 vendor가 PDF를 저장하고 signed URL을 줍니다. 편하지만 제3자가 모든 문서의 copy를 갖게 됩니다.
8. Renderer가 실패하면 어떻게 되는가?
모든 renderer는 실패합니다. structured 4xx/5xx인지, retry가 idempotent인지, 실패 render 과금이 있는지, status page/webhook/region p50-p99/synthetic probe가 있는지 확인하세요.
gPdf의 답변
| # | 질문 | gPdf 답변 |
|---|---|---|
| 1 | Input | JSON DocumentRequest |
| 2 | Cold start | 5-20 ms, V8 isolate, browser 없음 |
| 3 | Cost | 월 $0/$5/$8/$12; $0.00005/page overage |
| 4 | Determinism | 같은 engine version에서 byte-identical |
| 5 | Fonts | NotoSans CJK + Latin fallback embedded |
| 6 | Compliance | PDF/A-1b/2b/3b/4 + Factur-X / ZUGFeRD |
| 7 | Stateless | 예, document storage 없음 |
| 8 | Failure | Public status page, structured errors, idempotent |
입력이 정말 변경할 수 없는 HTML이라면 DocRaptor나 Prince가 더 맞을 수 있습니다.
요약
“최고의 PDF API”를 묻지 마세요. 이 8가지 질문으로 답을 평가하고 실제 workload에 맞는 벤더를 고르세요. invoices, receipts, structured documents라면 Playground에서 gPdf를 빠르게 확인할 수 있습니다.