![[PonsWarp 개념 교실 25] 멱등성 — 같은 결제 이벤트를 두 번 처리하지 않는 법](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-idempotent-webhook-cover-imagegen.webp)
[PonsWarp 개념 교실 25] 멱등성 — 같은 결제 이벤트를 두 번 처리하지 않는 법
쉽게 말하면, 멱등성은 같은 요청을 한 번 처리하든 열 번 처리하든 최종 결과가 한 번 처리한 것과 같게 만드는 성질 이다. 결제 Webhook은 네트워크 오류
실시간 통신, 파일 전송, 브라우저 API부터 제품 기획과 운영까지. 관심 있는 주제로 바로 이동하세요.
관심사에 맞춰 핵심 글부터 읽어보세요. 각 주제별로 가장 좋은 출발점을 정리했습니다.
P2P 파일 전송의 설계와 구현, 그리고 문제 해결.
WordPress에 발행된 글을 최신순으로 표시합니다. 새 글이 올라오면 이 영역이 자동으로 갱신됩니다.
![[PonsWarp 개념 교실 25] 멱등성 — 같은 결제 이벤트를 두 번 처리하지 않는 법](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-idempotent-webhook-cover-imagegen.webp)
쉽게 말하면, 멱등성은 같은 요청을 한 번 처리하든 열 번 처리하든 최종 결과가 한 번 처리한 것과 같게 만드는 성질 이다. 결제 Webhook은 네트워크 오류
![[PonsWarp 개념 교실 24] 토큰버킷 — API 요청을 어떻게 일정하게 제한하나](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-token-bucket-cover-imagegen.webp)
쉽게 말하면, 토큰버킷은 요청이 들어올 때마다 토큰을 하나씩 꺼내고, 토큰이 없으면 잠시 기다리거나 거부하는 요청 제한 장치 다. 무조건 초당 N개만 허용하는 고정 창보다 순간 bur
![[PonsWarp 개념 교실 26] 헥사고날 아키텍처 — 외부 기술을 갈아끼우는 구조](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-26-hexagonal-cover-imagegen.webp)
쉽게 말하면, 헥사고날 아키텍처는 핵심 업무 로직이 WebRTC·파일시스템·클라우드 같은 외부 기술을 직접 알지 않게 만드는 구조 다. 외부 기술을 바꾸더라도 안쪽
![[PonsWarp 개념 교실 23] presigned URL — 서버를 거치지 않고 R2에 올리는 법](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-23-presigned-url-cover-imagegen.webp)
Cloud Drop은 서버가 파일을 받아 저장하는 방식이 아니다. 서버가 잠깐 유효한 업로드 URL을 발급하고, 브라우저가 R2에 직접 PUT한다.
![[PonsWarp 개념 교실 22] TURN 자격증명 — coturn REST API와 HMAC-SHA1](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-22-turn-credential-cover-imagegen.webp)
쉽게 말하면, TURN 자격증명은 "잠깐만 쓸 수 있는 릴레이 이용권"이고, username 안에 만료시각을 넣고 그 전체를 HMAC SHA1으로 서명한다. 직접 WebRTC 연결이
![[PonsWarp 개념 교실 21] 시그널링 — 방 모델과 메시지 라우팅](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-21-signaling-room-cover-imagegen.webp)
쉽게 말하면, 시그널링 서버는 파일 운반자가 아니라 두 브라우저를 소개하는 교환원 이다. 파일 바이트는 WebRTC DataChannel로 직접 흐르고, 서버는
![[PonsWarp 개념 교실 20] Resume 커서 — 끊긴 전송을 중간부터 이어가는 법](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-20-resume-cursor-cover-imagegen.webp)
전송이 끊겼을 때 처음부터 다시 보내는 것은 가장 비싼 복구다. PonsWarp는 global offset을 file offset·sequence·next partition으로 바꿔 정확한 위치부터 재개한다.
![[PonsWarp 개념 교실 19] 백프레셔 — high/low watermark로 전송을 보호하는 법](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-19-backpressure-cover-imagegen.webp)
받는 쪽 디스크가 느린데 보내는 쪽이 계속 달리면 버퍼가 쌓인다. PonsWarp는 48MiB에서 PAUSE하고 16MiB까지 내려오면 RESUME하는 high/low watermark를 사용한다.
![[PonsWarp 개념 교실 18] AIMD — 혼잡 제어의 고전](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-18-aimd-cover-imagegen.webp)
네트워크가 괜찮을 때는 조금씩 키우고, 혼잡해지면 한 번에 줄인다. AIMD는 이 단순한 규칙으로 전송량을 안정화한다. PonsWarp는 RTT와 bufferedAmount를 보고 cwnd를 조절한다.
![[PonsWarp 개념 교실 17] 파티션 배리어 — PARTITION_ACK와 연속 프론티어](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-17-partition-barrier-cover-imagegen.webp)
암호화된 파일 조각을 끝없이 보내면 수신측 writer가 따라가지 못한다. PonsWarp는 일정 구간마다 PARTITION 마커를 보내고, 수신측의 연속 오프셋이 그 지점에 도달했을 때 다음 구간을 보낸다.
![[PonsWarp 개념 교실 16] in-flight 윈도우 — BDP와 슬라이딩 윈도우](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-16-sliding-window-cover-imagegen.webp)
보내지 않은 데이터를 무한히 큐에 넣으면 브라우저 버퍼가 터진다. PonsWarp는 네트워크 경로와 RTT를 보고 동시에 날아갈 수 있는 바이트를 정하고, bufferedAmount를 뺀 만큼만 더 요청한다.
![[PonsWarp 개념 교실 15] prepare-ahead 크레딧 — 생산자·소비자 큐](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-15-prepare-ahead-cover-imagegen.webp)
암호화 워커가 파일을 너무 빨리 읽으면 준비된 암호문이 메모리에 쌓인다. PonsWarp는 12MiB 크레딧을 두고 소비된 만큼만 다시 만들게 하는 생산자·소비자 흐름을 구현했다.
![[PonsWarp 개념 교실 14] WebRTC DataChannel — SCTP 신뢰성과 bufferedAmount](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-14-datachannel-cover-imagegen.webp)
WebRTC 연결이 됐다고 파일이 자동으로 안전하게 흐르는 것은 아니다. DataChannel은 SCTP 위에서 신뢰성과 순서를 제공하지만, 애플리케이션은 control/bulk 분리와 bufferedAmount 흐름 제어를 직접 설계해야 한다.
![[PonsWarp 개념 교실 13] Reed-Solomon — GF(2^8) 이레이저 코딩](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-13-reed-solomon-cover-imagegen.webp)
패킷이 손실돼도 원본을 복구할 수 있다면 재전송을 기다릴 필요가 없다. Reed Solomon은 데이터에 패리티를 더해 일부를 잃어도 나머지로 복원하는 FEC다.
![[PonsWarp 개념 교실 12] LZ4 블록 압축 — 속도를 위해 만든 비표준 포맷](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-12-lz4-block-cover-imagegen.webp)
DEFLATE보다 훨씬 빠른 압축이 필요한 순간이 있다. LZ4는 압축률을 희생하고 속도에 올인한 블록 압축이다. PonsWarp는 LZ4를 표준 프레임이 아닌 자체 블록 포맷으로 구현했는데, 그 선택의 이유와 대가를 파헤친다.
![[PonsWarp 개념 교실 11] DEFLATE — zip64 속의 압축 (miniz_oxide)](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-11-deflate-cover-imagegen.webp)
ZIP64 편에서 압축은 옵션이라고 했다. 그 옵션을 켰을 때 실제로 데이터를 줄이는 DEFLATE는 어떤 원리로 동작하고, 스트리밍에서 어떻게 조각 단위로 압축을 이어가는지 파헤친다.
![[PonsWarp 개념 교실 10] ZIP64 스트리밍 — LFH·CEN·EOCD64 구조](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-10-zip64-stream-cover-imagegen.webp)
여러 파일을 묶어 하나의 다운로드로 만들 때, 전체를 메모리에 올리지 않고 스트리밍으로 ZIP을 쓸 수 있다. PonsWarp의 수신측은 ZIP64 구조(LFH→데이터→CEN→EOCD64)를 조각 단위로 만들어 4GB 이상도 무손실로 표현한다.
![[PonsWarp 개념 교실 9] 재정렬 버퍼 — Arena·free-list·BTreeMap·LRU](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-09-reordering-buffer-cover-imagegen.webp)
조각이 순서대로 도착한다는 보장은 없다. 수신측은 뒤섞인 조각을 정렬해 파일 순서대로 디스크에 써야 한다. PonsWarp는 Arena+free list로 메모리를 관리하고, BTreeMap으로 인덱스를 유지하며, 128MiB 한도를 넘으면 LRU로…
![[PonsWarp 개념 교실 8] 청크 크기 16~192KiB — 어떻게 정해졌나](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-08-chunk-size-cover-imagegen.webp)
청크가 크면 패킷 수가 줄어 빨라질 것 같지만, SCTP 메시지 상한과 메모리·재전송 비용이 가로막는다. PonsWarp가 경로별로 16 192KiB를 고르는 기준과, 크면 무조건 빠르다가 아닌 이유를 파헤친다.
![[PonsWarp 개념 교실 7] 22바이트 패킷 헤더 — 한 조각이 자신을 설명하는 법](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-07-packet-header-cover-imagegen.webp)
파일을 조각내 보내면 수신측은 이 조각이 파일의 어디에 붙는지 알아야 한다. PonsWarp는 22바이트 고정 헤더에 그 정보를 담는다. 각 필드가 왜 그 크기인지, 왜 그 순서인지, 그리고 CRC 필드가 0으로 비워진 사연까지 파헤친다.
![[PonsWarp 개념 교실 6] 무결성 3총사 — CRC32 vs SHA-256 vs Merkle Tree](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-06-integrity-trio-cover-imagegen.webp)
데이터가 전송 중 변조되지 않았는지 확인하는 방법은 세 가지 층위가 있다. CRC32는 빠르지만 약하고, SHA 256은 강하지만 무겁고, Merkle 트리는 부분 검증이 가능하다. PonsWarp가 실제로 고른 조합과 그 이유를 파헤친다.
![[PonsWarp 개념 교실 5] HMAC과 상수시간 비교 — 키 확인과 타이밍 공격](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-05-hmac-constant-time-cover-imagegen.webp)
두 브라우저가 같은 키를 가졌는지 확인하려면 문자열 비교로 충분할 것 같지만, 그 비교 방식이 보안 구멍이 될 수 있다. HMAC과 상수시간 비교가 왜 함께 필요한지 파헤친다.
![[PonsWarp 구현 분석 2] 복사하지 않는 게 제일 빠르다 — WASM 메모리와 제로카피](/tistory/ponswarp/implementation/2026-08-21-ponswarp-impl-02-wasm-memory-zero-copy-cover-imagegen.webp)
JS↔WASM 경계를 넘을 때 바이트를 몇 번 복사해야 할까? PonsWarp는 64KB 슬롯 풀을 WASM 메모리에 미리 할당해 쓰기 0회, 읽기 1회 복사를 실현했지만, 실제로는 절반만 제로카피인 지점도 있다.
![[PonsWarp 구현 분석 6] 브라우저끼리 키를 나누는 법 — E2E 암호화의 실제 적용](/tistory/ponswarp/implementation/2026-08-21-ponswarp-impl-06-e2e-crypto-nonce-cover-imagegen.webp)
개념 글에서 다룬 ECDH, HKDF, AES 256 GCM, nonce가 실제 PonsWarp 코드에서 하나의 파이프라인으로 어떻게 연결되는지, 전송 전부터 전송 중, 재개까지 추적한다.
![[PonsWarp 개념 교실 4] GCM nonce — 왜 4B 카운터 + 8B random prefix인가](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-04-gcm-nonce-cover-imagegen.webp)
GCM에서 nonce가 두 번 재사용되면 암호문 두 개를 XOR하는 것만으로 키를 역산할 수 있다. PonsWarp가 nonce를 4바이트 카운터와 8바이트 랜덤 프리픽스로 쪼갠 이유와, 그 설계에 남은 위험이 무엇인지 파헤친다.
![[PonsWarp 개념 교실 3] AES-256-GCM — 암호화의 구조 (CTR + GHASH + tag)](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-03-aes-256-gcm-cover-imagegen.webp)
AES 256 GCM은 암호화와 위변조 감지를 한 번에 해결한다. CTR 모드로 데이터를 섞고, GHASH로 인증 태그를 만들어 붙인다. 이 태그가 16바이트로 파일 무결성을 지키는 이유를 파헤친다.
![[PonsWarp 개념 교실 2] HKDF-SHA256 — 공동 비밀을 안전한 키로 가공하기](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-02-hkdf-sha256-cover-imagegen.webp)
ECDH가 만든 공동 비밀은 좋은 AES 키라고 바로 가정하면 안 된다. 그 사이에 키 제조 공장 하나를 두는데, 그게 HKDF SHA256이다.
![[PonsWarp 개념 교실 1] ECDH P-256 — 둘만 아는 공동 비밀 만들기](/tistory/ponswarp/concept/2026-08-21-ponswarp-concept-01-ecdh-p256-cover-imagegen.webp)
서로 비밀키를 직접 보내지 않고, 두 기기만 똑같은 암호화 키를 만들어내는 방법.

선언 실행일지 2026 08 08

세션 로그 자동 추출 기반 회고. 포털/데스크 개편, 해외 수집, 선언 시스템.

외주로 살아간다는 다섯 가지 약속. 매일의 실행일지가 이 선언의 증거다.
![[WarpInfra] 남은 일 — mTLS·20GB 실측·Control MVP·그리고 컴퓨트 그리드](/tistory/body-images/2026-08-07-warpinfra-10-remaining-work/cover.webp)
시리즈의 마지막 편은 백로그다. 지금 남은 일의 순서는 우연이 아니라 원칙으로 고정되어 있다. 이 편은 RC1 게이트 뒤의 작업을 Now/Next/Later로 나눠 읽고, 시리즈를 닫는다.
![[WarpInfra] RC1 — 20GB·다중 머신·SHA-256 없으면 출시가 아니다](/tistory/body-images/2026-08-07-warpinfra-09-rc1-gate/cover.webp)
제품이 "완료됐다"고 말하는 순간은 기능이 끝났을 때가 아니라 증거가 갖춰졌을 때다. WarpInfra의 RC1 문서는 이 원칙을 게이트로 박아두었다. 이 편은 그 게이트와 현재 통과 상태를 대조한다.
![[WarpInfra] Phase A를 95%까지 올린 구현 묶음](/tistory/body-images/2026-08-07-warpinfra-08-phase-a-95/cover.webp)
Phase ALAN Grid MVP의 목표는 단순하다. 코디네이터 없이, 같은 LAN에서 앱들이 release를 공유하고 메시 수신한다. 2026 07 18 기준 이 단계는 약 95%다. 이 편은 그 95%를 만든 부품 묶음을 정리한다.
![[WarpInfra] 희소한 조각부터, 여러 피어에게 동시에](/tistory/body-images/2026-08-07-warpinfra-07-rarest-first-piece-race/cover.webp)
여러 Node가 한 파일을 나눠 받을 때, 스케줄러가 "어느 조각을 먼저 요청할지" 고르는 기준이 결과를 가른다. WarpInfra는 rarest first를 택하고, Have fanout으로 조각 보유 정보를 퍼뜨리고, multi peer piec…
![[WarpInfra] 폴더가 단일 스트림으로 줄줄이 나가던 버그](/tistory/body-images/2026-08-07-warpinfra-06-zip-streaming-folder/cover.webp)
폴더 전송은 겉보기엔 단순하다. "파일을 묶어서 보내면 된다." 그런데 zip으로 묶는 순간 메모리와 디스크와 타이밍이 한꺼번에 어긋난다. 이 편은 zip 패키징 실패가 단일 스트림 연속 송신으로 바뀌기까지의 커밋을 읽는다.
![[WarpInfra] WASM을 버리고 네이티브 QUIC로 갈아탄 날](/tistory/body-images/2026-08-07-warpinfra-05-native-quic/cover.webp)
한때 전송 코어는 WASM에 얹혀 있었다. 웹과 데스크톱이 같은 코어를 쓰려는 의도였다. 그런데 데스크톱에선 그 선택이 오히려 발목을 잡았다. 이 편은 WASM 의존을 제거하고 네이티브 QUIC로 전환한 커밋들을 추적한다.
![[WarpInfra] CLI를 1등 시민으로 둔 이유 — CI와 AI 에이전트](/tistory/body-images/2026-08-07-warpinfra-04-cli-first-ai-agents/cover.webp)
GUI를 먼저 만들고 CLI를 "개발자용 부가기능"으로 두는 제품이 많다. WarpInfra는 정반대다. CLIwarp가 1등 시민이고, GUI와 agentd가 같은 코어를 공유한다. 이 선택의 근거는 단순하다. "운영자는 사람이 아니라 파이프라인이…
![[WarpInfra] 컴퓨트 그리드를 일부러 뒤로 미룬 로드맵](/tistory/body-images/2026-08-07-warpinfra-03-roadmap-data-grid-first/cover.webp)
"그리드"라는 단어를 들으면 대부분 분산 연산을 떠올린다. WarpInfra는 반대로 갔다. 분산 전송데이터 그리드을 먼저 끝내고, 분산 연산컴퓨트 그리드은 데이터 그리드가 안정화된 뒤에만 설계하기로 했다. 이 순서 고정이 이 시리즈의 로드맵 편이다.
![[WarpInfra] 파일 바이트는 Control을 지나지 않는다](/tistory/body-images/2026-08-07-warpinfra-02-control-vs-data-plane/cover.webp)
그리드 아키텍처에서 가장 먼저 고정한 원칙이 하나 있다. "파일 payload는 Control이 아니라 Node 간 P2P로 이동한다." 이 한 줄이 coordinator 설계, 라우트 노출, 보안 경계를 모두 결정했다.
![[WarpInfra] 레지스트리 옆 CLI release get — 복제하지 않는 니치](/tistory/body-images/2026-08-07-warpinfra-01-niche-cli-release-get/cover.webp)
분산 파일 전송 제품은 이미 많다. Resilio, Aspera, Signiant. 그런데도 WarpInfra를 처음부터 만들기로 한 이유는 무엇일까. 한 줄로: 전체 미러링 제품을 복제하는 대신, "레지스트리 옆에서 release를 받는 CLI"라…
![[WarpInfra] 데이터 그리드 시리즈를 시작하며 — desktop과 grid, 그리고 이름](/tistory/body-images/2026-08-07-warpinfra-00-series-map/cover.webp)
레포는 두 개다. 이름은 하나다. 이 시리즈는 DeclanJeon/ponswarp desktop146커밋과 DeclanJeon/ponswarp grid29커밋의 커밋 이력을 시간순이 아니라 설계 → 구현 → 남은 일 순서로 다시 읽는 기록이다. 이…
![[PonsWarp Grid] 방을 먼저 열고, direct와 grid를 가르다](/tistory/body-images/2026-08-07-ponswarp-grid-03-room-first-direct-grid/cover.webp)
파일을 고르는 순간 방이 열린다. 전송은 direct직접와 grid그리드로 갈린다. 사용자는 경로를 고르지 않는다. 제품이 고른다. 이 편은 room first 메시 전송과 direct/grid 분기, 그리고 브라우저 대용량 export가 Blob에…
![[PonsWarp Grid] coordinator를 "안전하게" 노출한다는 것](/tistory/body-images/2026-08-07-ponswarp-grid-02-coordinator-routes/cover.webp)
제어면이 바이트를 안 다루기로 했으니, coordinator가 노출하는 라우트는 메타만 다뤄야 한다. 이 편은 ponswarp grid에서 coordinator 라우트를 공개하면서 무엇을 넣고 무엇을 금지했는지, 그리고 mesh 연산을 CLI로 묶은…
![[PonsWarp Grid] 브라우저 그리드 엔진을 처음부터 다시 짜다](/tistory/body-images/2026-08-07-ponswarp-grid-01-engine-from-zero/cover.webp)
desktop이 네이티브 그리드로 가는 동안, 브라우저 쪽에는 별도의 엔진이 필요했다. ponswarp grid 레포다. 이 편은 그 엔진을 처음부터제로베이스 짠 29개 커밋의 시작점을 읽는다.
![[PonsLink] WebRTC 시그널링과 TURN 인프라 구축 회고](/tistory/body-images/2026-08-07-ponslink-webrtc-signaling-turn/cover.webp)
실시간 제품을 만들면 처음엔 영상이 붙는 순간에 환호한다. 그다음 주부터는 NAT 뒤의 사용자, 회사 방화벽, 모바일 전환, 재연결 폭풍을 상대한다. PonsLink의 시그널링·TURN·SFU 구성은 그 실패를 제품 상태로 다루기 위한 결과다.
![[PonsLink] 요청-세션 라이프사이클 설계 — 공개 데스크에서 자동 아카이브까지](/tistory/body-images/2026-08-07-ponslink-request-session-lifecycle/cover.webp)
PonsLink의 핵심 UX 원칙은 다섯 단계다. 방룸은 네 번째 단계에 불과하다. 이 글은 그 다섯 단계가 API·DB·프론트 라우트에 어떻게 내려앉는지 정리한다.
![[PonsLink] 결제 연동과 웹훅 안정성 회고 — 다중 PG와 멱등성](/tistory/body-images/2026-08-07-ponslink-payment-webhook-reliability/cover.webp)
결제는 "성공 페이지를 보여주면 끝나는 일"이 아니다. PonsLink는 Polar를 활성 공급자로 두고, PayPal·LemonSqueezy·Stripe 웹훅 경로를 함께 유지한다. 공급자가 늘수록 문제는 기능이 아니라 중복·지연·재시도다.
글 목록 대신, 실제로 돌고 있는 제품을 GIF로 먼저 보여줍니다. 상세 회고는 Work / Writing 아카이브에서 이어집니다.

요청 → 수락 → 세션으로 이어지는 연결 워크플로
명함 교환 뒤 끊기던 대화를 용건 수집, 일정 조율, 세션룸까지 한 흐름으로 묶은 실시간 제품입니다.

서버 보관 없이 바로 보내는 P2P 파일 전송
중계 저장 없이 브라우저 간 직접 전송으로 대용량 파일을 넘기도록 설계한 전송 도구입니다.
하나의 주제를 깊이 있게 다룬 연재 글들입니다. 처음부터 끝까지 순서대로 읽어보세요.