Skip to content

fix(perps): reduce WebSocket subscription overhead and prevent leaks cp-7.63.0 cp-7.64.0#25496

Merged
aganglada merged 2 commits intomainfrom
fix/perps/websocket-subscription-fixes
Feb 2, 2026
Merged

fix(perps): reduce WebSocket subscription overhead and prevent leaks cp-7.63.0 cp-7.64.0#25496
aganglada merged 2 commits intomainfrom
fix/perps/websocket-subscription-fixes

Conversation

@abretonc7s
Copy link
Copy Markdown
Contributor

@abretonc7s abretonc7s commented Feb 2, 2026

Description

This PR addresses WebSocket subscription issues identified during the rate limiting incident investigation. The fixes reduce subscription message volume by ~75% and prevent subscription leaks.

Root Causes Identified

  1. Subscriptions to unregistered DEXs - System subscribed to ALL 8 DEXs from API instead of only the 2 in our allowlist (main + xyz)
  2. Duplicate DEX subscriptions from race conditions - Concurrent calls created 2× subscriptions per DEX
  3. Candle subscription leaks - Cleanup failed when component unmounted before async subscription resolved

Fixes Implemented

1. Filter DEXs by Allowlist on Mainnet (HIGH PRIORITY)

Files: hyperLiquidConfig.ts, HyperLiquidProvider.ts

  • Added MAINNET_HIP3_CONFIG with AutoDiscoverAll: false
  • DEX filtering is now dynamic - extracts DEX names from the allowlistMarkets feature flag patterns
  • Added extractDexsFromAllowlist() method that parses patterns like xyz:*, xyz:TSLA, or xyz
  • Impact: Reduces from 8 DEXs to 2 (main + xyz), ~75% reduction in subscription messages

2. Prevent Duplicate DEX Subscriptions (HIGH PRIORITY)

File: HyperLiquidSubscriptionService.ts

  • Added pendingClearinghouseSubscriptions and pendingOpenOrdersSubscriptions Maps
  • Refactored ensureClearinghouseStateSubscription() and ensureOpenOrdersSubscription() to check for pending promises
  • Concurrent calls now wait for the pending promise instead of creating duplicate subscriptions
  • Impact: Prevents 50% redundant subscriptions from race conditions

3. Fix Candle Subscription Cleanup (HIGH PRIORITY)

File: HyperLiquidClientService.ts

  • Store subscription promise to enable cleanup even when pending
  • Updated cleanup function to wait for pending promise and unsubscribe
  • Impact: Prevents WebSocket subscription leaks when component unmounts before subscription resolves

Test Results

Metric Before After Improvement
DEXs subscribed 8 2 75% reduction
clearinghouseState subscriptions 16 2 87% reduction
openOrders subscriptions 16 2 87% reduction
Candle subscription leaks Yes No Fixed

Changelog

CHANGELOG entry: null

Related issues

Fixes: Rate limiting incident from WebSocket over-subscription

Related: WebSocket Subscription Investigation Report

Manual testing steps

Feature: WebSocket subscription optimization

  Scenario: User connects to perps and only allowlisted DEXs are subscribed
    Given user has the app installed with perps feature enabled
    And WebSocket logging is enabled in dev mode

    When user navigates to Perps home screen
    Then WebSocket logs show subscriptions only for main and xyz DEXs
    And no subscriptions for flx, vntl, hyna, km, abcd, cash DEXs

  Scenario: User navigates between markets without duplicate subscriptions
    Given user is connected to perps
    And WebSocket logging is enabled

    When user navigates from Home to xyz:XYZ100 market details
    And user returns to Home
    And user navigates back to xyz:XYZ100
    Then WebSocket logs show no duplicate clearinghouseState subscriptions
    And WebSocket logs show no duplicate openOrders subscriptions

  Scenario: User views candle chart and subscriptions are properly cleaned up
    Given user is on a market details screen with chart visible

    When user quickly navigates away from the screen
    And user waits for 2 seconds
    Then candle subscriptions are properly unsubscribed
    And no orphaned candle subscriptions exist

Screenshots/Recordings

Before

WebSocket subscription breakdown (full trading flow):

  • clearinghouseState: 16 subscriptions (8 DEXs × 2 duplicates)
  • openOrders: 16 subscriptions (8 DEXs × 2 duplicates)
  • candle: 4 subscriptions, 0 unsubscriptions (leak)

After

WebSocket subscription breakdown (full trading flow):

  • clearinghouseState: 2 subscriptions (main + xyz only)
  • openOrders: 2 subscriptions (main + xyz only)
  • candle: 2 subscriptions, 2 unsubscriptions (balanced)

Total outgoing messages: 44
Total incoming messages: 402 (down from ~750)

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Subscription Breakdown

  • clearinghouseState: 2 (main + xyz)
  • openOrders: 2 (main + xyz)
  • userFills: 1
  • webData3: 1
  • allMids: 1
  • assetCtxs: 2 (xyz only, subscribed/unsubscribed on navigation)
  • activeAssetCtx: 2 (xyz:XYZ100, subscribed/unsubscribed on navigation)
  • candle: 2 (1h + 15m intervals)
  • bbo: 2 (subscribed/unsubscribed during order flow)

Future Optimization Opportunity

Trading operations (order placement, cancellation, modification) currently use HTTP transport:

  • ExchangeClient is configured with httpTransport to avoid 429 rate limiting
  • InfoClient uses wsTransport for info queries (multiplexed over single WS connection)

Now that subscription volume is reduced by 75%, we could consider moving ExchangeClient to WebSocket transport (see follow-up investigation).


Note

Medium Risk
Touches core perps WebSocket subscription and DEX-discovery behavior; bugs could lead to missing market data or stale positions/orders, though changes are localized and defensive.

Overview
Reduces perps WebSocket load by filtering mainnet HIP-3 DEX discovery/subscription based on the allowlistMarkets feature flag, falling back to main DEX only when no HIP-3 patterns are allowlisted (via new MAINNET_HIP3_CONFIG and allowlist DEX parsing in HyperLiquidProvider).

Prevents subscription churn/leaks by deduplicating concurrent clearinghouseState/openOrders subscriptions with pending-promise tracking in HyperLiquidSubscriptionService, and by fixing candle unsubscription when the async subscribe promise hasn’t resolved yet in HyperLiquidClientService.

Written by Cursor Bugbot for commit 73e62ff. This will update automatically on new commits. Configure here.

- Add MAINNET_HIP3_CONFIG to filter DEXs dynamically from allowlist
- Extract DEX names from allowlist patterns (xyz:*, xyz:TSLA, xyz)
- Add pending promise tracking to prevent duplicate subscriptions
- Fix candle subscription cleanup when component unmounts early

Impact:
- 75% reduction in DEX subscriptions (8 → 2)
- Prevents race condition duplicate subscriptions
- Eliminates candle subscription leaks

Co-Authored-By: Claude <noreply@anthropic.com>
@abretonc7s abretonc7s requested a review from a team as a code owner February 2, 2026 01:56
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 2, 2026

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-perps Perps team label Feb 2, 2026
@github-actions github-actions bot added the size-M label Feb 2, 2026
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

@abretonc7s abretonc7s changed the title fix(perps): reduce WebSocket subscription overhead and prevent leaks fix(perps): reduce WebSocket subscription overhead and prevent leaks cp-7.63.0 Feb 2, 2026
@abretonc7s abretonc7s added the skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. label Feb 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 2, 2026

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps
  • Selected Performance tags: @PerformancePreps
  • Risk Level: medium
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes are all within the Perps (Perpetuals trading) module and involve:

  1. hyperLiquidConfig.ts: Added MAINNET_HIP3_CONFIG for mainnet-specific DEX filtering configuration
  2. HyperLiquidProvider.ts: Added mainnet DEX filtering logic and extractDexsFromAllowlist() method to reduce WebSocket subscription overhead
  3. HyperLiquidClientService.ts: Fixed race condition in candle subscription cleanup by tracking subscription promises
  4. HyperLiquidSubscriptionService.ts: Added pending subscription promise tracking to prevent duplicate subscriptions from concurrent calls

These are internal optimizations and bug fixes within the Perps module that:

  • Improve WebSocket subscription management
  • Prevent race conditions and subscription leaks
  • Add mainnet DEX filtering based on allowlist

The SmokePerps tag is the appropriate test suite as it covers perpetuals trading functionality on Arbitrum One, including Add Funds flow, balance verification, and Perps interface interactions. These tests will validate that the subscription management changes don't break the core Perps functionality.

Performance Test Selection:
The changes specifically target WebSocket subscription management and race condition fixes in the Perps module. The MAINNET_HIP3_CONFIG addition is explicitly designed to 'reduce WebSocket subscription overhead' and the subscription service changes prevent duplicate subscriptions. These optimizations could impact Perps performance metrics including market loading, position management, and order execution times. The @PerformancePreps tag is appropriate to validate that these subscription optimizations don't negatively impact performance and potentially measure any improvements.

View GitHub Actions results

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.00000% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.26%. Comparing base (1dd96c3) to head (73e62ff).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...Perps/controllers/providers/HyperLiquidProvider.ts 0.00% 25 Missing ⚠️
...I/Perps/services/HyperLiquidSubscriptionService.ts 92.30% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #25496      +/-   ##
==========================================
- Coverage   80.28%   80.26%   -0.02%     
==========================================
  Files        4261     4261              
  Lines      110173   110228      +55     
  Branches    23475    23486      +11     
==========================================
+ Hits        88452    88478      +26     
- Misses      15513    15541      +28     
- Partials     6208     6209       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Feb 2, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
52.3% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@aganglada aganglada added this pull request to the merge queue Feb 2, 2026
@aganglada aganglada changed the title fix(perps): reduce WebSocket subscription overhead and prevent leaks cp-7.63.0 fix(perps): reduce WebSocket subscription overhead and prevent leaks cp-7.63.0 cp-7.64.0 Feb 2, 2026
Merged via the queue into main with commit 7a0c2a1 Feb 2, 2026
140 of 155 checks passed
@aganglada aganglada deleted the fix/perps/websocket-subscription-fixes branch February 2, 2026 09:35
@github-actions github-actions bot locked and limited conversation to collaborators Feb 2, 2026
@metamaskbot metamaskbot added the release-7.65.0 Issue or pull request that will be included in release 7.65.0 label Feb 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.65.0 Issue or pull request that will be included in release 7.65.0 size-M skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants