Home>Blog>Your Hyperliquid Bot Keeps Hitting 429. Fix It for Good.
Your Hyperliquid Bot Keeps Hitting 429. Fix It for Good.

Your Hyperliquid Bot Keeps Hitting 429. Fix It for Good.

By @CoinMarketMan - 08-Jul-2026

Hyperliquid 봇이 계속 429를 받는다면. 완전히 해결하는 법.

1초마다 Hyperliquid에서 가격을 폴링하는 봇을 작성한다. 테스트에서는 완벽하게 작동한다. 그러다 두 번째 자산을 추가한다. 그 다음 다섯 개. 그리고 왜 안 되겠냐는 생각에 같은 주기로 포지션과 펀딩도 확인한다. 몇 분 안에 API가 HTTP 429를 반환하기 시작하고, 봇은 최악의 순간에 눈이 멀어버린다.

이것은 새로운 Hyperliquid 빌더들에게 가장 흔한 장애 유형이다. 해결책은 거의 "더 높은 티어로 업그레이드"가 아니다. 문제는 구조적이다. 대부분의 봇은 모든 엔드포인트가 동일한 비용이라고 가정하고, 거의 변하지 않는 데이터를 매 블록마다 움직이는 데이터와 같은 빈도로 폴링하며, Hyperliquid가 REST를 완전히 피할 수 있도록 제공하는 도구들을 무시한다. 웨이트 시스템이 실제로 어떻게 작동하는지 이해하고 나면, 429 오류는 불가피한 것에서 영구적으로 설계로 피할 수 있는 것으로 바뀐다.

이 가이드는 Hyperliquid가 적용하는 모든 속도 제한을 분석하고, 각 엔드포인트 카테고리의 웨이트 계산을 설명하며, 프로덕션 봇을 예산 내에 유지하는 캐싱, WebSocket, 배치 패턴을 살펴본다.

웨이트 예산: 분당 1,200, 하지만 모든 호출이 같지 않다

Hyperliquid의 REST API는 웨이트 기반 시스템을 사용한다. 모든 IP 주소는 분당 1,200 웨이트의 공유 예산을 가진다. 하지만 각 요청의 비용은 어떤 엔드포인트를 호출하느냐에 따라 크게 달라진다.

Exchange API 요청(주문 제출, 취소, 수정)은 1 + floor(batch_length / 40)의 웨이트를 소비한다. 단일 주문은 1이다. 39개 주문의 배치도 1이다. 40개 배치는 2다. 이 때문에 배치는 속도 제한 툴킷에서 가장 효과적인 도구 중 하나다.

Info 엔드포인트는 세 가지 티어로 나뉜다:

| 티어 | 웨이트 | 엔드포인트 | | --- | --- | --- | | 가벼움 | 2 | l2Book, allMids, clearinghouseState, orderStatus, spotClearinghouseState, exchangeStatus | | 무거움 | 20 | 그 외 모든 문서화된 info 요청(포지션, 체결 내역, 펀딩 히스토리, 리더보드) | | 가장 무거움 | 60 | userRole |

일부 엔드포인트는 응답 크기에 따라 웨이트가 증가하기도 한다. recentTrades, historicalOrders, userFills, userFillsByTime, fundingHistory 등 여러 엔드포인트는 반환되는 항목 20개당 추가 웨이트가 붙는다. candleSnapshot 엔드포인트는 항목 60개당 웨이트가 추가된다. Explorer API 요청은 기본 웨이트 40에서 시작하며 blockList의 경우 블록당 1이 추가된다.

이 계산이 사람들을 걸려 넘어뜨린다. 봇이 allMids를 초당 한 번 폴링하면(웨이트 2), 가격 데이터만으로 분당 120 웨이트다. 같은 주기로 clearinghouseState를 확인하면(또 120), 주문 하나 제출하기도 전에 예산의 20%가 날아간다. 여기에 userFills 같은 웨이트 20짜리 엔드포인트를 같은 속도로 추가하면, 체결 내역만으로 분당 1,200 웨이트를 태운다. 예산 소진.

Weight Budget Breakdown

대부분의 빌더가 잊는 주소 기반 제한

IP 기반 속도 제한은 누구나 아는 것이다. 429 오류가 시끄럽게 나타나기 때문이다. 하지만 Hyperliquid는 지갑 주소별로도 별도의 제한을 적용하며, 이것은 더 조용하지만 걸렸을 때는 마찬가지로 고통스럽다.

모든 주소는 10,000 요청의 초기 버퍼로 시작한다. 이후 제한은 거래 거래량에 따라 증가한다. 주소가 생성된 이후 누적 거래된 USDC 1달러당 요청 하나가 추가된다. 평생 $500,000를 거래한 계정은 510,000 요청의 예산을 가진다. 한 번도 거래하지 않은 새 테스트넷 주소는 공격적으로 폴링하면 몇 시간 만에 버퍼를 소진한다.

주소 기반 제한에 걸리면 API는 10초에 한 번으로 속도를 제한한다. 완전 차단이 아니라 목줄이다. 봇은 여전히 작동하지만 기어가는 속도로. 다행인 점은: 취소 작업은 min(limit + 100,000, limit * 2)의 더 넉넉한 예산을 받는다. 나머지 모든 것이 제한되더라도 포지션은 언제든지 청산할 수 있다.

서브 계정은 주소 기반 제한에서 별도의 사용자로 취급된다. 따라서 서브 계정에 걸쳐 작업을 분산하면 도움이 된다. 단, IP 기반 제한과 혼동하지 말자. IP 기반 제한은 어떤 주소가 요청을 보내는지와 무관하게 같은 IP의 모든 트래픽이 공유한다.

WebSocket 제한: 연결당 1,000이 아니라 총 1,000 구독

REST 폴링에서 WebSocket 구독으로 전환하는 것은 대부분의 빌더가 할 수 있는 가장 큰 속도 제한 최적화다. 구독은 무언가 변경될 때 봇에게 데이터를 푸시하므로 REST 웨이트를 전혀 소비하지 않는다. 하지만 WebSocket 연결에도 고유한 제한이 있으며, 가장 흔한 오해는 구독이 어떻게 집계되는가다.

Hyperliquid는 IP당 최대 10개의 동시 WebSocket 연결을 허용한다. 분당 최대 30개의 새 연결도 허용된다. 구독 제한은 모든 연결에 걸쳐 총 1,000개다. 연결 5개를 열어도 5,000개의 구독이 생기지 않는다. 여전히 1,000개를 공유한다.

Websocket Limits Overview

아웃바운드 메시지 제한은 분당 2,000개다. 동시 인플라이트 포스트 메시지는 최대 100개. 사용자별 구독(UserEvents 등)은 IP당 최대 10명의 고유 사용자로 제한된다.

구독 수 계산이 중요하다. Hyperliquid에는 200개 이상의 무기한 선물 계약이 있다. 자산-데이터 유형 조합마다 별도의 구독이 필요하다. 모든 자산에 TradesL2Book을 구독하면 두 가지 데이터 유형만으로 400개 이상의 구독이 필요하다. 하나의 타임프레임으로 Candle을 추가하면 600개를 넘는다. 두 타임프레임이면 1,000 제한을 초과한다.

동적으로 구독 관리하기

프로덕션 봇이 모든 시간에 모든 자산의 모든 피드를 필요로 하는 경우는 드물다. 더 효과적인 접근법은 관심 목록을 유지하고 전략이 실제로 지금 필요한 것을 기반으로 구독을 순환하는 것이다. 모든 가격을 위해 AllMids를 한 번 구독하고(구독 하나), 실제로 거래하거나 진입을 모니터링하는 코인에만 자산별 피드를 추가한다.

자산이 관심 목록을 벗어나면 구독을 해제하고 슬롯을 확보한다. 이 패턴은 유니버스가 수백 개의 자산이더라도 1,000개를 충분히 밑돈다. 어느 시점에서든 활성 세트는 일반적으로 훨씬 작기 때문이다.

429를 받으면 실제로 무슨 일이 생기나

Hyperliquid의 429 응답은 요청이 거부된다는 의미지만, 경고 신호다. API는 응답 본문에 오류 메시지를 반환하며 얼마나 기다려야 하는지 정확히 알려주는 Retry-After 헤더가 포함될 수 있다. 단기적인 속도 제한 이벤트는 요청 거부로 끝나며 계정 밴으로 이어지지 않는다. 하지만 지속적인 남용 트래픽은 더 심각한 결과로 이어질 수 있다.

봇이 429에 반응할 때 가장 나쁜 행동은 빡빡한 루프에서 즉시 재시도하는 것이다. 그러면 더 많은 429 오류가 발생하고, 속도 제한 윈도우가 연장되며, 짧은 문제가 장기 장애로 이어질 수 있다. 지수 백오프가 표준 해결책이다:

  1. Retry-After 헤더를 확인한다. 있으면 정확히 그만큼 기다린다.
  2. 없으면 1초 지연으로 시작한다.
  3. 연속 실패마다 지연을 두 배로 늘린다: 1초, 2초, 4초, 8초, 16초, 32초.
  4. 60초에서 상한을 둔다. 그 시점에서도 429가 계속 오면 더 근본적인 문제가 있는 것이다.
  5. 성공적인 요청 후 백오프 타이머를 리셋한다.
async def request_with_backoff(endpoint, payload, max_retries=6):
    delay = 1
    for attempt in range(max_retries):
        response = await client.post(endpoint, json=payload)
        if response.status_code != 429:
            return response
        retry_after = response.headers.get("Retry-After")
        wait = int(retry_after) if retry_after else delay
        await asyncio.sleep(wait)
        delay = min(delay * 2, 60)
    raise RateLimitExceeded(f"Still 429 after {max_retries} retries")

배치: 가장 덜 활용되는 최적화

Hyperliquid의 배치 시스템은 놀라울 만큼 관대하다. 최대 39개의 exchange API 요청(주문, 취소, 수정)을 배치하면 단일 요청과 같은 비용인 웨이트 1이다. 40개 배치는 웨이트 2다. 79개 배치도 여전히 웨이트 2다. 즉, 30개 주문을 개별적으로 보내는 봇은 30 웨이트를 소비하지만, 단일 배치로 보낸 같은 30개 주문은 1 웨이트만 소비한다.

단, 주소 기반 제한에서 중요한 차이가 있다. 배치 요청은 IP 기반 속도 제한에서는 하나의 요청으로 집계되지만, 주소 기반 속도 제한에서는 n개의 요청으로 집계된다. 배치는 IP 예산을 절약하지만 주소별 예산은 절약하지 않는다. 대부분의 빌더에게는 IP 제한이 주요 병목이므로 배치는 여전히 가장 큰 효과를 낸다. 다만 분당 수백 개의 배치 주문을 보내는 고빈도 봇은 여전히 주소 기반 버퍼를 소진할 수 있다는 점을 알아두자.

캐싱: 거의 변하지 않는 데이터를 반복 조회하지 말자

Hyperliquid의 펀딩 레이트는 한 시간에 한 번 정산된다. 미결제약정은 매 블록마다 업데이트되지만 대부분의 자산에서 초 단위로 의미 있게 움직이지 않는다. 거래소 메타데이터(자산 목록, 스펙, 마진 파라미터)는 새 종목이 상장될 때 일주일에 한 번 정도 변경된다. 그런데도 대부분의 봇은 이 모든 것을 가격 데이터에 쓰는 것과 같은 공격적인 주기로 폴링한다.

TTL 기반 만료를 적용한 로컬 캐시 레이어가 이런 중복 호출 대부분을 없애준다:

  • 가격 (allMids): WebSocket으로 전환한다. REST 웨이트 제로.
  • 포지션 (clearinghouseState): 몇 초마다 폴링하고(예: 5~15초), 폴링 사이에 캐시한다.
  • 펀딩 레이트: 몇 분 단위로 캐시한다(예: 10~15분). 레이트는 시간마다 정산되므로 15분 캐시도 정산 윈도우당 최대 4번만 확인한다.
  • 체결 내역 (userFills): 실시간 업데이트는 UserEvents WebSocket으로 구독한다. REST 폴링은 대조 폴백으로만 사용한다.
  • 메타데이터 (자산 목록, 스펙): 공격적으로 캐시한다(메타데이터는 자주 변하지 않는다). 시작 시 한 번 확인하고 주기적으로 갱신한다.

빠르게 변하는 데이터에는 WebSocket 구독, 느리게 변하는 데이터에는 캐시된 REST 폴링을 조합하면 단순 폴링 구조 대비 REST 웨이트 소비를 일반적으로 90% 이상 줄일 수 있다. 대부분의 봇에서 이는 분당 1,200 웨이트 예산이 제한에 걸리지 않고 수년간의 성장을 뒷받침하기에 충분하다는 의미다.

Request Reduction Flow

데이터 예산과 거래 예산을 분리하라

Hyperliquid 문서는 info 엔드포인트와 exchange 엔드포인트 카테고리의 제한이 별도라고 명시한다. 이것은 중요한 구조적 통찰이다. 시장 데이터 쿼리가 주문 제출의 속도 제한 여유를 두고 경쟁해서는 안 된다.

실제로는 봇을 두 개의 별도 요청 경로로 구성하는 것을 의미한다. 하나는 데이터 수집용(info 엔드포인트, 분석, 모니터링), 다른 하나는 실행용(주문, 취소, 수정). 데이터 레이어에 버그가 생겨 요청이 폭발해도, 거래 경로는 영향받지 않는다. 실행 레이어가 청산 이벤트 중 대량 일괄 취소를 처리하는 동안에도, 데이터 피드는 계속 흐른다.

사전 계산된 분석을 활용하는 빌더에게는 이 분리가 더욱 깔끔해진다. 수백 개 주소의 체결 내역을 가져오고, 코호트 집계를 계산하고, 리더보드 변화를 추적하는 데 info 엔드포인트 예산을 소진하는 대신, 전용 레이어를 통해 그 분석을 소비할 수 있다. HyperTracker의 API는 코호트 포지셔닝, Smart Money 집계, 청산 위험 점수를 사전 계산된 엔드포인트로 제공한다. 봇의 Hyperliquid 속도 제한 예산은 Hyperliquid만이 줄 수 있는 것, 즉 가격, 내 포지션, 주문 실행에 온전히 집중된다.

더 빠르게 빌드하고, 덜 폴링하라

HyperTracker는 16개의 행동 세그먼트에 걸쳐 코호트 분석을 계산한다. 봇이 수백 개의 지갑을 스크래핑할 필요가 없다. API 호출 하나로 수천 개의 포지션 쿼리를 대체한다. 무료 티어로 시작해보자.

API 살펴보기

프로덕션에서 예산 모니터링하기

"테스트에서는 잘 되는" 봇과 프로덕션에서 안정적으로 운영되는 봇의 차이는 모니터링이다. Hyperliquid는 userRateLimit info 엔드포인트를 제공한다. 현재 주소 기반 속도 제한 상태, 남은 예산, 사용량을 반환한다. 이것을 주기적으로 쿼리하면(예: 30초마다) 한계에 부딪히기 전에 조기 경고를 받을 수 있다.

Hyperliquid의 내장 엔드포인트 외에도 봇에 다음 항목을 계측하라:

  • 엔드포인트 유형별 분당 요청 수: 어떤 엔드포인트가 가장 많은 웨이트를 소비하는지 파악한다.
  • 429 빈도: 0이 아닌 수치가 나오면 예산 계산이 틀린 것이다.
  • WebSocket 재연결 횟수: 잦은 재연결은 분당 30개의 새 연결 허용량을 소비하는 연결 끊김을 나타낼 수 있다.
  • 캐시 히트율: 낮은 히트율은 TTL이 너무 짧거나 캐시해야 할 엔드포인트를 캐시하지 않는 것이다.
  • 응답 지연 백분위수 (p50, p95, p99): 지연 증가는 429가 실제로 발생하기 전에 속도 제한 근접을 신호할 수 있다.

이런 지표를 로그로 남기고, 알림을 설정하고, 매주 검토하라. 자산이나 전략을 추가할수록 서서히 속도 제한에 다가가는 봇은 결국 그것을 넘게 된다. 변동성 높은 시장 세션 중에 발견하는 것보다 추세를 일찍 발견하고 조정하는 편이 낫다.

규모를 키워도 버티는 속도 제한 아키텍처

추적하는 자산 수와 무관하게 프로덕션 Hyperliquid 봇을 예산 내에 유지하는 스택이다:

  1. WebSocket 우선: 가격에는 AllMids, 활성 자산의 호가창에는 L2Book, 체결 내역에는 UserEvents를 사용한다. 고빈도 REST 폴링이 사라진다.
  2. 느린 것은 모두 캐시한다: 펀딩 레이트, 메타데이터, 히스토리 쿼리는 로컬 TTL 캐시를 사용한다. 온디맨드가 아니라 스케줄에 따라 갱신한다.
  3. 모든 쓰기는 배치로: 주문, 취소, 수정을 배치로 묶는다. 웨이트 공식에 따라 40개 미만의 배치는 웨이트 1이다.
  4. 데이터와 실행을 분리한다: 독립적인 모니터링이 있는 별도의 요청 매니저를 사용한다. 데이터 버그가 거래를 막아서는 안 된다.
  5. 분석은 외부에 맡긴다: 코호트 인텔리전스는 HyperTracker 같은 사전 계산 API에 맡긴다. Hyperliquid만이 줄 수 있는 것에 Hyperliquid 예산을 쓴다.
  6. 모니터링하고 알림을 설정한다: 엔드포인트별 웨이트 소비를 추적하고, 429 추세를 관찰하며, 제한에 걸리기 전에 TTL이나 구독 수를 조정한다.

Hyperliquid 빌더라면 누구나 한 번은 429를 맞는다. 오래 살아남는 제품을 만드는 사람들은 그것이 다시는 일어나지 않도록 아키텍처를 재설계하는 이들이다. 도구는 이미 다 있다. 웨이트 기반 예산, 관대한 배치, 네이티브 WebSocket 지원, 그리고 현재 상태를 정확히 알려주는 userRateLimit 엔드포인트. 이것들을 활용하면 속도 제한은 결코 닿지 않는 가드레일이 된다.