Your Hyperliquid Bot Keeps Hitting 429. Fix It for Good.
By @CoinMarketMan - 08-Jul-2026
Hyperliquid Botが429を連発する。完全に解決する方法。
毎秒Hyperliquidの価格をポーリングするBotを書く。テストでは完璧に動く。次に2つ目のアセットを追加する。さらに5つ。ついでに同じ頻度でポジションとファンディングもチェックする。数分後、APIはHTTP 429を返し始め、最悪のタイミングでBotが盲目になる。
これはHyperliquidの新規Builderに最も多く見られる障害パターンだ。解決策はほぼ「上位プランにアップグレードする」ではない。問題はアーキテクチャにある。多くのBotはすべてのエンドポイントを同じコストとして扱い、ほとんど変化しないデータをブロックごとに変動するデータと同じ頻度でポーリングし、RESTを完全に回避するためにHyperliquidが提供するツールを無視している。ウェイトシステムの実際の仕組みを理解すれば、429エラーは避けられないものから、永続的に回避できるものへと変わる。
このガイドでは、Hyperliquidが適用するすべてのレート制限を分解し、各エンドポイントカテゴリのウェイト計算を説明し、本番Botをバジェット内に収めるキャッシュ・WebSocket・バッチ処理のパターンを解説する。
ウェイトバジェット:1分あたり1,200。ただし、すべての呼び出しが同じコストではない
HyperliquidのREST APIはウェイトベースのシステムを採用している。すべてのIPアドレスが1分あたり1,200ウェイトの共有バジェットを持つ。ただし、各リクエストのコストは呼び出すエンドポイントによって大きく異なる。
Exchange APIリクエスト(注文、キャンセル、変更)のウェイトは 1 + floor(batch_length / 40) だ。注文1件は1ウェイト。39件のバッチも1ウェイト。40件のバッチは2ウェイトになる。バッチ処理はレート制限対策の中で最も効果的なツールの一つだ。
Infoエンドポイントは3段階に分かれる:
| 段階 | ウェイト | エンドポイント |
| --- | --- | --- |
| 軽量 | 2 | l2Book, allMids, clearinghouseState, orderStatus, spotClearinghouseState, exchangeStatus |
| 重量 | 20 | その他すべての文書化されたinfoリクエスト(ポジション、約定履歴、ファンディング履歴、リーダーボード) |
| 最重量 | 60 | userRole |
レスポンスサイズによってウェイトが増加するエンドポイントもある。recentTrades、historicalOrders、userFills、userFillsByTime、fundingHistoryなどへの呼び出しは、返される20件ごとにウェイトが加算される。candleSnapshotエンドポイントは60件ごとにウェイトが加算される。Explorer APIリクエストは40ウェイトから始まり、blockListの場合はブロックごとに1が加算される。
計算が落とし穴になる。Botが毎秒allMidsをポーリングすると(各2ウェイト)、価格データだけで1分あたり120ウェイトを消費する。同じ頻度でclearinghouseStateのチェックを追加すると(さらに120)、注文1件も出す前にバジェットの20%を使い果たす。さらにウェイト20のuserFillsを同じ頻度で呼び出せば、約定だけで1分あたり1,200ウェイトを燃やすことになる。バジェット終了。
ほとんどのBuilderが見落とすアドレスベースの制限
IPベースのレート制限は誰もが知っている。429エラーが大きなシグナルを発するからだ。しかしHyperliquidはウォレットアドレスごとに別の制限も適用している。こちらは目立たないが、ぶつかったときの痛みは同じくらいだ。
すべてのアドレスは10,000リクエストのバッファから始まる。その後、制限は取引量に基づいて増加する。アドレス作成以来の累計USDC取引量1ドルごとにリクエスト1件が追加される。生涯取引額$500,000のアカウントは510,000リクエストのバジェットを持つ。取引実績のない新しいテストネットアドレスは、積極的にポーリングすると数時間でバッファを使い果たす。
アドレスベースの制限に達すると、APIは10秒に1リクエストに絞り込む。ハードブロックではなく、リードだ。Botは動き続けるが、ほぼ止まっているも同然の速度になる。明るい面もある。キャンセル操作には min(limit + 100,000, limit * 2) というより寛大なバジェットが与えられる。他のすべてがレート制限されていても、ポジションを必ず解消できる。
サブアカウントはアドレスベースの制限では別ユーザーとして扱われる。つまり、サブアカウント間で操作を分散させることが有効だ。ただし、IPベースの制限と混同しないこと。IPベースはリクエストを行うアドレスに関係なく、同じIPからのすべてのトラフィックで共有される。
WebSocket制限:1,000サブスクリプション、1接続あたりではない
RESTポーリングからWebSocketサブスクリプションへの移行は、多くのBuilderが取れる最大のレート制限最適化だ。サブスクリプションは何か変化があったときにデータをBotにプッシュし、RESTウェイトをゼロ消費する。ただしWebSocket接続には独自の制限があり、最も多い誤解はサブスクリプションのカウント方法だ。
HyperliquidはIP毎に最大10本の同時WebSocket接続を許可する。1分あたり30本の新規接続が上限だ。サブスクリプション制限はすべての接続にわたって合計1,000だ。5本の接続を開いても5,000サブスクリプションにはならない。1,000を共有するだけだ。
送信メッセージの制限は1分あたり2,000だ。同時飛行中のpostメッセージの最大数は100だ。ユーザー固有のサブスクリプション(UserEventsなど)はIP毎に最大10ユニークユーザーに制限される。
サブスクリプションの計算が重要だ。Hyperliquidには200以上の無期限契約がある。アセットとデータタイプの各ペアに独自のサブスクリプションが必要だ。すべてのアセットにTradesとL2Bookをサブスクライブすると、2つのデータタイプだけで400以上のサブスクリプションになる。Candleを1つのタイムフレームで追加すると600以上になる。2つのタイムフレームで1,000の制限を超える。
サブスクリプションを動的に管理する
本番Botが常にすべてのアセットのすべてのフィードを必要とすることは稀だ。より効果的なアプローチは、ウォッチリストを維持し、戦略が実際に今必要とするものに基づいてサブスクリプションをローテーションすることだ。すべての価格にAllMidsを一度サブスクライブし(1サブスクリプション)、アクティブに取引または監視しているコインにのみアセット固有のフィードを追加する。
アセットがウォッチリストから外れたら、サブスクライブを解除してスロットを解放する。このパターンにより、ユニバースが数百アセットに渡っていても1,000を大きく下回ることができる。特定の瞬間のアクティブセットは通常はるかに小さいからだ。
429が返ってきたときに実際に何が起きるか
HyperliquidからのHTTP 429レスポンスはリクエストが拒否されていることを意味するが、これは警告ショットだ。APIはレスポンスボディにエラーメッセージを返し、正確な待機時間を伝えるRetry-Afterヘッダーを含む場合もある。短時間のレート制限イベントはリクエストの拒否をもたらすが、アカウントのBANではない。ただし、継続的な乱用的トラフィックはより深刻な結果につながる可能性がある。
Botがやってはいけない最悪の対応は、タイトなループで即座にリトライすることだ。それはさらに多くの429エラーを生み出し、レート制限ウィンドウを延長し、短い障害を長期停止に変える。指数バックオフが標準的な解決策だ:
Retry-Afterヘッダーを確認する。存在する場合は、正確にその時間だけ待つ。- 存在しない場合は、1秒の遅延から始める。
- 連続失敗ごとに遅延を2倍にする:1秒、2秒、4秒、8秒、16秒、32秒。
- 60秒で上限を設ける。その時点でまだ429が続くなら、より深い問題がある。
- リクエスト成功後にバックオフタイマーをリセットする。
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件の注文を個別に出すBotは30ウェイトを消費するが、同じ30件を1つのバッチにまとめると1ウェイトしかかからない。
ただし、アドレスベースの制限には重要な注意点がある。バッチリクエストはIPベースのレート制限では1リクエストとしてカウントされるが、アドレスベースのレート制限ではnリクエストとしてカウントされる。つまり、バッチ処理はIPバジェットを節約するが、アドレスごとのバジェットは節約しない。多くのBuilderにとってIPの制限が拘束条件なので、バッチ処理は最大の効果をもたらす。ただし、1分あたり数百のバッチ注文を送信する高頻度Botは、アドレスベースのバッファを着実に消費することを意識しておくべきだ。
キャッシュ:ほとんど変化しないデータを再取得するのをやめる
Hyperliquidのファンディングレートは1時間に1回精算される。Open Interestはブロックごとに更新されるが、ほとんどのアセットで毎秒単位の動きは意味のある変化ではない。取引所のメタデータ(アセットリスト、スペック、証拠金パラメータ)は新しいリスティングが追加されるときに週1回程度変わる。しかし多くのBotは、これらすべてを価格データと同じ積極的な頻度でポーリングしている。
TTLベースの有効期限を持つローカルキャッシュレイヤーがこれらの冗長な呼び出しの大半を排除する:
- 価格 (
allMids): WebSocketに移行する。RESTウェイトはゼロ。 - ポジション (
clearinghouseState): 数秒ごとにポーリングし(例:5〜15秒)、ポーリング間はキャッシュを使用する。 - ファンディングレート: 数分間キャッシュする(例:10〜15分)。レートは毎時精算されるため、15分キャッシュでも1精算ウィンドウあたり最大4回のチェックになる。
- 約定 (
userFills): リアルタイム更新にはUserEventsWebSocketでサブスクライブする。RESTポーリングは照合のフォールバックとしてのみ使用する。 - メタデータ(アセットリスト、スペック): 積極的にキャッシュする(メタデータは変更頻度が低い)。起動時に一度チェックし、定期的に更新する。
高速変動データにWebSocketサブスクリプション、低速変動データにキャッシュRESTポーリングを組み合わせることで、通常ナイーブなポーリングアーキテクチャと比較してRESTウェイト消費量を90%以上削減できる。多くのBotにとって、これは1分あたり1,200ウェイトのバジェットが、制限にぶつかることなく何年もの成長に十分であることを意味する。
データバジェットと取引バジェットを分離する
Hyperliquidのドキュメントは、infoエンドポイントとexchangeエンドポイントカテゴリの制限が別々であることを明記している。これはアーキテクチャ上の重要な洞察だ。マーケットデータのクエリは決して注文の執行とレート制限の余裕を奪い合ってはいけない。
実践的には、Botを2つの独立したリクエストパスで構成することを意味する。データ取り込み用(infoエンドポイント、アナリティクス、モニタリング)と執行用(注文、キャンセル、変更)だ。データレイヤーにバグがあってリクエストのバーストを送信しても、取引パスは影響を受けない。清算イベント中に執行レイヤーが高速バッチキャンセル処理中でも、データフィードは維持される。
事前計算されたアナリティクスを使用するBuilderにとって、この分離はさらにクリーンになる。数百のアドレスの約定を引っ張り、コホート集計を計算し、リーダーボードの変化を追跡するといった生データ処理にinfoエンドポイントのバジェットを燃やす代わりに、専用レイヤーを通じてそれらのアナリティクスを消費できる。HyperTrackerのAPIはコホートポジショニング、Smart Moneyの集計、清算リスクスコアリングを事前計算されたエンドポイントとして提供する。BotのHyperliquidレート制限バジェットを、Hyperliquidだけが提供できるデータ、価格、自分のポジション、注文執行だけに集中させることができる。
速く構築し、ポーリングを減らす
HyperTrackerは16の行動セグメントにわたるコホートアナリティクスを計算するため、Botが数百のウォレットをスクレイピングする必要がない。1回のAPIコールが数千のポジションクエリを置き換える。無料プランから始めよう。
本番環境でバジェットを監視する
「テストでは動く」Botと本番環境で安定して動くBotの違いはモニタリングだ。HyperliquidはuserRateLimit infoエンドポイントを提供しており、現在のアドレスベースのレート制限状況、残りバジェット、使用量を返す。これを定期的にクエリする(例:30秒ごと)ことで、上限に達する前に早期警告が得られる。
Hyperliquidのビルトインエンドポイントに加え、Botが追跡すべき指標:
- エンドポイントタイプ別の1分あたりリクエスト数: どのエンドポイントが最も多くのウェイトを消費するかを把握する。
- 429の頻度: ゼロ以外の値はバジェット計算が誤っていることを意味する。
- WebSocket再接続率: 頻繁な再接続は、1分あたり30本の新規接続制限を消費するドロップ接続を示す可能性がある。
- キャッシュヒット率: 低いヒット率はTTLが短すぎるか、キャッシュすべきエンドポイントをキャッシュしていないことを意味する。
- レスポンスレイテンシーパーセンタイル(p50、p95、p99): レイテンシーの上昇は429が実際に発生する前にレート制限への接近を示すシグナルになりうる。
これらの指標をログに記録し、アラートを設定し、週次でレビューする。アセットや戦略を追加するにつれてレート制限に向かって徐々に漂流するBotは、最終的にそれを超える。相場が荒れているセッション中に発見するより、早めにトレンドを把握して調整する方がずっといい。
スケールするレート制限アーキテクチャ
追跡するアセット数に関係なく、本番のHyperliquid Botをバジェット内に収めるスタックを以下に示す:
- WebSocketを優先する: 価格には
AllMids、アクティブアセットの板情報にはL2Book、約定にはUserEventsを使う。これにより最も高頻度のRESTポーリングを排除できる。 - 低速なものはすべてキャッシュする: ファンディングレート、メタデータ、過去のクエリにはローカルTTLキャッシュを使う。需要ではなくスケジュールに基づいて更新する。
- すべての書き込みをバッチ処理する: 注文、キャンセル、変更をバッチにまとめる。ウェイト計算式によると、40件未満のバッチはウェイト1だ。
- データと執行を分離する: 独立したモニタリングを持つ別々のリクエストマネージャーを使う。データのバグが取引をブロックしてはいけない。
- アナリティクスをオフロードする: コホートインテリジェンスはHyperTrackerのような事前計算APIに任せる。HyperliquidバジェットはHyperliquidにしか提供できないものに使う。
- 監視とアラートを設定する: エンドポイントごとのウェイト消費量を追跡し、429のトレンドに注目し、制限に達する前にTTLやサブスクリプション数を調整する。
すべてのHyperliquid Builderは少なくとも一度は429にぶつかる。長続きするプロダクトを構築する人たちは、それが二度と起きないようにアーキテクチャを再設計する。ツールはすべて揃っている。ウェイトベースのバジェット管理、寛大なバッチ処理、ネイティブWebSocketサポート、そして自分の現在地を正確に教えてくれるuserRateLimitエンドポイント。これらを活用すれば、レート制限は決して触れることのないガードレールになる。