동시 접속 (SSE)
가상 탭 N개 × SSE( full-tab 시 presence·호가×2·체결·미체결 ). realtime·Redis·Online 카운터.
- 스크립트
- scripts/load-sse.ts
- Railway
- load-sse
- RPC 영향
- 거의 없음 (RPC 소모 적음)
- 상태
- 실측 진행 중 (2026-08-12)
Load test report · SSE 실측 · 주문 분리
동시 접속(SSE)과 동시 주문을 분리해 측정합니다. 2026-08-12 Railway dev에서 load-sse full-tab 실측 — 500명 100%·1000명 94.6%. realtime 1대 운영 한도는 full-tab 가상 유저 약 900명( SSE ≈4500 )으로 가정.
동접: scripts/load-sse.ts · Railway load-sse. 주문: scripts/load-orders.ts · Railway load-test — 별도 시나리오·별도 RPC 부담.
가상 탭 N개 × SSE( full-tab 시 presence·호가×2·체결·미체결 ). realtime·Redis·Online 카운터.
executeServerPlaceOrder를 count번 동시 호출 (HTTP 없음). 온체인·RPC·trade-api 경로.
가상 탭 1000 × SSE 5 = 5000연결 · 소요 92s · 성공률 94.6%
| 스트림 | opened | fail |
|---|---|---|
| presence | 946 | 54 |
| priceTicker | 946 | 54 |
| priceChart | 944 | 56 |
| fills | 941 | 59 |
| openOrders | 942 | 58 |
Online: before 1001 → peak 633 → after 1
가상 탭 500 × SSE 5 = 2500연결 · 소요 76s · 성공률 100%
| 스트림 | opened | fail |
|---|---|---|
| presence | 500 | 0 |
| priceTicker | 500 | 0 |
| priceChart | 500 | 0 |
| fills | 500 | 0 |
| openOrders | 500 | 0 |
Online: before 501 → peak 472 → after 1
아직 실측 없음. railway up --service load-test로 별도 실행. SSE 테스트와 시간대를 분리해 RPC 경쟁을 줄입니다.
| 항목 | 기본값 | 이유 |
|---|---|---|
| SSE_MAX_CONNECTIONS_GLOBAL | 4000 | full-tab 5스트림 기준 ~800유저 + 여유 (실측 1000유저는 5000 SSE) |
| SSE_MAX_CONNECTIONS_PER_IP | 120 | 통신사 CGNAT·사내망 공유 IP |
| RATE_LIMIT_TX_SEND_PER_MIN | 180 | UI 주문 전송 · 공유 IP 감안 |
| RATE_LIMIT_VERIFY_PER_MIN | 180 | 주문 후 온체인 verify |
| RATE_LIMIT_ORDERS_PER_MIN | 60 | 서버 서명 API — load-orders와 별개 |
SSE 연결 수는 Railway realtime replica로 나눌 수 있습니다. full-tab 기준 1대 ≈ 900유저( SSE ≈4500 )는 2026-08-12 dev 실측 가정입니다.
Online 카운터는 프로세스 메모리 — load-sse가 abort로 끊으면 -1이 안 되어 뻥튀기될 수 있음. 테스트 후 realtime 재시작 권장.
더 키울 때는 아키텍처의 realtime + Redis pub/sub·로드밸런서를 참고하세요.
가상 탭 500 × SSE 5 = 2500연결. ramp 100/2s, hold 60s. 전 스트림 fail=0.
도구: scripts/load-sse.ts, 서비스 load-sse, REALTIME_URL=realtime internal. 소요 ~76s. Online before 501 → peak 472 → after 1.
다음 · 1000명 램프 실측으로 한도 확인 (완료 → l0800).
946/1000 탭 연결. 후반 fetch failed ~54. 80% 통과 기준 충족. 1대당 full-tab ~900명 보수적 운영선.
SSE 5000 목표 중 presence 946 성공. peak Online 633. ingest/RPC는 부하 적음. 5k presence-only(이전)와 달리 full-tab이 실사용에 가깝다.
다음 · 2000명 또는 주문 부하(load-orders)는 SSE와 시간 분리. Online 뻥튀기 시 realtime 재시작.
동시 1000명이면 같은 마켓 WS가 1000개가 되어 RPC가 먼저 한계에 달함.
price/stream·open/stream이 연결마다 onAccountChange를 생성했음. fill watcher는 원래 마켓별 공유.
다음 · 마켓당 구독 1개 + 리스너 fan-out. full-tab 실측으로 RPC 안정성 재확인.
전역 4000·IP 120·tx/verify 180. replica마다 인메모리 한도 별도.
full-tab 1000유저는 raw SSE 5000 — 전역 4000 한도와 정합성 재검토 필요.
다음 · 부하 시 429/503·어느 IP에서 막히는지 로그 확인.
presence + 호가(티커) + 호가(차트, presence=0) + 체결 + 미체결. --no-open-orders 시 4개.
이전 가정(≈3)은 미체결·Online 제외. Zenith load-sse --full-tab이 Trade UI와 동일.
다음 · 멀티탭·지갑 미연결 비율 반영 시 가정 보정.
SSE 연결은 수평 분산 가능. 2000 full-tab 목표면 realtime 3대 안전선.
Online·presence 카운터는 프로세스 메모리 — 비정상 종료 시 +1만 남음(재시작으로 리셋). Redis pub/sub으로 다중 인스턴스 동기화는 이미 사용.
다음 · 로드밸런서 + replica 2대 A/B 실측.
주문 부하·ingest가 RPC 공유. SSE만으로는 크레딧 소모 적음.
5k presence-only 테스트 후 ingest 429 관측 이력 — 주문 부하 전 RPC 여유 확인.
다음 · load-orders 램프 전 Helius 잔량 확인.
동접 SSE와 분리. executeServerPlaceOrder count건 동시 — RPC·온체인 성공률 측정.
Railway load-test 원샷. MAX_CONCURRENT_ORDERS 기본 1000. SSE 테스트와 동시 실행 시 RPC 경쟁.
다음 · LOAD_TEST_COUNT 램프 10→50→100… SSE 안정 구간에서 실행.