Skip to main content

Batch Where Possible

Several Codex endpoints accept multiple inputs in a single request. Use these instead of making separate calls:
EndpointBatching Support
getTokenPricesUp to 25 tokens per request
onPricesUpdatedUp to 25 tokens per subscription
filterTokensUp to 200 results per page
tokensMultiple token inputs in one call
getDetailedPairsStatsMultiple pair inputs in one call
One getTokenPrices call with 25 tokens = 1 request. Twenty-five individual calls = 25 requests.

Request Only the Fields You Need

GraphQL lets you specify exactly which fields to return. Requesting fewer fields means smaller payloads, faster responses, and less data to parse.
# Instead of requesting everything...
query {
  filterTokens(input: { limit: 25 }) {
    results {
      token { name symbol address networkId decimals createdAt creatorAddress
              isScam socialLinks { discord telegram twitter website }
              info { circulatingSupply totalSupply } }
      priceUSD volume24 liquidity holders marketCap
      change1 change4 change12 change24
      txnCount1 txnCount4 txnCount12 txnCount24
      uniqueBuys1 uniqueBuys4 uniqueBuys12 uniqueBuys24
    }
  }
}

# ...request only what you'll actually display
query {
  filterTokens(input: { limit: 25 }) {
    results {
      token { name symbol address networkId }
      priceUSD volume24 liquidity change24
    }
  }
}

Use Subscriptions Instead of Polling

If you’re calling a query on a timer to check for updates, switch to a subscription. It’s faster and often more efficient.
PatternRequests Used
Polling getTokenPrices every 5 seconds for 1 hour720 requests
Subscribing to onPriceUpdated for 1 hour (assuming ~1 update/sec)~3,600 requests
Subscribing to onPriceUpdated for 1 hour (low-volume token, ~1 update/min)~60 requests
Subscriptions are more efficient for low-to-medium frequency updates. For very high-frequency data (e.g. SOL trade events), subscriptions may actually generate more requests than polling — so consider your token’s volume when choosing.
See Queries vs Subscriptions to find the right approach for your use case.

Proxy Subscriptions Through Your Backend

If multiple users are viewing the same data, don’t create a separate subscription for each user. Instead, subscribe once on your backend and fan out the data to connected clients.
Without proxy: 100 users viewing SOL price = 100 subscriptions
With proxy:    100 users viewing SOL price = 1 subscription
This applies to any shared data: charts, trade feeds, token stats, holder lists.

Cache Data That Doesn’t Change Often

Some data changes rarely and doesn’t need to be fetched on every request:
DataHow Often It ChangesCache Duration
Token metadata (name, symbol, decimals)RarelyHours to days
Social links, imagesOccasionallyHours
Network list (getNetworks)Very rarelyDays
Token pricesConstantlyDo not cache
Trade eventsConstantlyDo not cache
Cache on your backend and serve from cache to avoid unnecessary API calls.

Use Filters to Reduce Noise

Codex indexes 75M+ tokens across 100+ networks — most of which aren’t useful for most applications. Always apply filters to narrow results:
# Filter for tokens with meaningful activity
query {
  filterTokens(
    input: {
      limit: 25
      filters: {
        liquidity: { gte: 10000 }
        volume24: { gte: 5000 }
        txnCount24: { gte: 50 }
      }
      rankings: { attribute: trendingScore24, direction: DESC }
    }
  ) {
    results {
      token { name symbol address networkId }
      priceUSD volume24 liquidity
    }
  }
}
Without filters, you’ll get results dominated by inactive, low-liquidity, or spam tokens.

Manage Subscription Lifecycle

Idle subscriptions still consume requests. Implement these patterns to avoid wasting your limit:
  • Idle detection — pause subscriptions when users are inactive using hooks like useIdle, and resume when they return
  • Page visibility — unsubscribe when the browser tab is hidden, resubscribe when it becomes visible
  • Component cleanup — always unsubscribe in cleanup/unmount handlers to prevent orphaned subscriptions
// React example: pause subscription when tab is hidden
const isVisible = // ...determine if this component is in view

useEffect(() => {
  const handleVisibility = () => {
    if (!isVisible) {
      subscription.unsubscribe();
    } else {
      subscription.resubscribe();
    }
  };
  document.addEventListener("visibilitychange", handleVisibility);
  return () => document.removeEventListener("visibilitychange", handleVisibility);
}, [isVisible]);

Use the Right Endpoint for the Job

Some endpoints are more efficient than others depending on what you need:
NeedEfficientLess Efficient
Price for 1 tokengetTokenPricesfilterTokens (returns much more data)
Top pair for a tokenlistPairsForTokenfilterPairs with phrase search
Historical OHLCVgetBars / getTokenBarsReconstructing from getTokenEvents
Token discoveryfilterTokens with filters + rankingsFetching all tokens and filtering client-side
Multiple token metadatatokens (batch)Individual token calls

Paginate Large Result Sets

For endpoints that return many results, use cursor-based pagination rather than trying to fetch everything at once:
# First page
query {
  filterTokens(input: { limit: 50 }) {
    results { token { name address } priceUSD }
    cursor
  }
}

# Next page — pass the cursor from the previous response
query {
  filterTokens(input: { limit: 50, cursor: "eyJ..." }) {
    results { token { name address } priceUSD }
    cursor
  }
}
Fetch only the pages you need. Don’t paginate through the entire dataset if you only need the first few pages.