> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chainstream.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Ordering & Pagination

> Sort query results with the orderBy input object and paginate with limit — naming conventions, defaults, and offset-based pagination

## orderBy InputObject

Each Cube generates an `{Cube}OrderBy` input object with `ascending` and `descending` fields. Each field accepts a `CompareFields` enum value that follows the dimension path joined by underscores:

```
{DimensionGroup}_{DimensionField}
```

For nested dimensions, each level is joined:

```
Block_Time
Trade_Buy_Amount
Trade_Buy_PriceInUSD
```

Usage:

```graphql theme={null}
orderBy: {descending: Block_Time}      # newest first
orderBy: {ascending: Trade_Buy_Amount}  # smallest amount first
```

### Common CompareFields Values

<div style={{ overflowX: 'auto', width: '100%' }}>
  | CompareFields Value    | Example Usage                                 | Cube(s)                                                                           | Description                        |
  | :--------------------- | :-------------------------------------------- | :-------------------------------------------------------------------------------- | :--------------------------------- |
  | `Block_Time`           | `orderBy: {descending: Block_Time}`           | DEXTrades, Transfers, BalanceUpdates, DEXPools, TokenSupplyUpdates, Pairs, Tokens | Newest first                       |
  | `Block_Time`           | `orderBy: {ascending: Block_Time}`            | DEXTrades, Transfers, BalanceUpdates, DEXPools, TokenSupplyUpdates, Pairs, Tokens | Oldest first                       |
  | `Interval_Time_Start`  | `orderBy: {ascending: Interval_Time_Start}`   | Pairs, Tokens                                                                     | Oldest first (interval start time) |
  | `Trade_Buy_Amount`     | `orderBy: {descending: Trade_Buy_Amount}`     | DEXTrades                                                                         | Largest buy amount first           |
  | `Trade_Buy_PriceInUSD` | `orderBy: {descending: Trade_Buy_PriceInUSD}` | DEXTrades                                                                         | Highest USD price first            |
  | `Transfer_AmountInUSD` | `orderBy: {descending: Transfer_AmountInUSD}` | Transfers                                                                         | Largest USD transfer first         |
  | `LatestBalanceUSD`     | `orderBy: {descending: LatestBalanceUSD}`     | TokenHolders                                                                      | Largest holder first               |
  | `BuyVolumeUSDState`    | `orderBy: {descending: BuyVolumeUSDState}`    | WalletTokenPnL                                                                    | Highest buy volume first           |
</div>

<Tip>
  Use the [GraphQL IDE](https://ide.chainstream.io) auto-complete to discover all available `CompareFields` values for a Cube — type `orderBy: {descending:` and the IDE will show available fields.
</Tip>

### Usage

Pass an `orderBy` input object with either `descending` or `ascending` set to a `CompareFields` value:

```graphql theme={null}
query {
  Solana {
    DEXTrades(
      orderBy: {descending: Block_Time}
      limit: { count: 10 }
    ) {
      Block { Time }
      Trade { Buy { Amount PriceInUSD } }
    }
  }
}
```

<Note>
  `orderBy` accepts a **single** direction/field pair. Multi-column sorting is not supported — the query is sorted by one dimension at a time.
</Note>

***

## limit Argument

The `limit` argument controls how many rows are returned and supports offset-based pagination:

```graphql theme={null}
input LimitInput {
  count: Int   # Number of rows to return
  offset: Int  # Number of rows to skip
}
```

### Default and Maximum Limits

Each Cube has a **default** limit applied when you omit the `limit` argument, and a **maximum** cap:

| Cube               | Default `count` | Maximum `count` |
| :----------------- | :-------------- | :-------------- |
| DEXTrades          | 25              | 10,000          |
| Transfers          | 25              | 10,000          |
| BalanceUpdates     | 25              | 10,000          |
| DEXPools           | 25              | 10,000          |
| TokenSupplyUpdates | 25              | 10,000          |
| Pairs              | 25              | 10,000          |
| Tokens             | 25              | 10,000          |
| DEXPoolEvents      | 25              | 10,000          |
| TokenHolders       | 25              | 10,000          |
| WalletTokenPnL     | 25              | 10,000          |

<Info>
  If you request a `count` exceeding the maximum, the server silently caps it at the maximum value.
</Info>

***

## Offset-Based Pagination

Use `offset` to page through result sets. The pattern is straightforward:

* **Page 1**: `limit: { count: 50, offset: 0 }`
* **Page 2**: `limit: { count: 50, offset: 50 }`
* **Page 3**: `limit: { count: 50, offset: 100 }`

### Example: Paginated Token Holders

<Tabs>
  <Tab title="Page 1">
    ```graphql theme={null}
    query {
      Solana {
        TokenHolders(
          tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          orderBy: {descending: LatestBalanceUSD}
          limit: { count: 20, offset: 0 }
        ) {
          Holder { Address }
          LatestBalance
          LatestBalanceUSD
        }
      }
    }
    ```
  </Tab>

  <Tab title="Page 2">
    ```graphql theme={null}
    query {
      Solana {
        TokenHolders(
          tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          orderBy: {descending: LatestBalanceUSD}
          limit: { count: 20, offset: 20 }
        ) {
          Holder { Address }
          LatestBalance
          LatestBalanceUSD
        }
      }
    }
    ```
  </Tab>
</Tabs>

### Pagination Tips

<AccordionGroup>
  <Accordion title="Always use orderBy with pagination">
    Without a stable sort order, rows may shift between pages. Always pair `limit` with an `orderBy` that produces a deterministic order.
  </Accordion>

  <Accordion title="Avoid deep offsets">
    Large `offset` values (e.g., 50,000+) may degrade performance since the database must scan and skip rows. For very large datasets, narrow your query with `where` filters instead of paginating deeply.
  </Accordion>

  <Accordion title="Use count to detect end of results">
    If a page returns fewer rows than the requested `count`, you've reached the end of the dataset. Alternatively, use the `count` metric field to get total row count upfront.
  </Accordion>
</AccordionGroup>

***

## Practical Examples

### Latest Large Trades

Fetch the 10 most recent DEX trades on Solana with a buy value over \$10,000:

```graphql theme={null}
query {
  Solana {
    DEXTrades(
      where: {
        Trade: { Buy: { PriceInUSD: { gt: 10000 } } }
      }
      orderBy: {descending: Block_Time}
      limit: { count: 10 }
    ) {
      Block { Time }
      Trade {
        Buy {
          Currency { MintAddress }
          Amount
          PriceInUSD
        }
        Dex { ProtocolName }
      }
    }
  }
}
```

### OHLC Candles — Last 60 Minutes

Fetch 1-minute candles for a token, sorted chronologically:

```graphql theme={null}
query {
  Trading {
    Pairs(
      where: {
        Token: { Address: { is: "So11111111111111111111111111111111111111112" } }
        Market: { Network: { is: "sol" } }
        Block: { Time: { after: "2025-03-27T09:00:00Z" } }
      }
      orderBy: {ascending: Block_Time}
      limit: { count: 60 }
    ) {
      Block { Time }
      Price {
        Ohlc { Open High Low Close }
      }
      Volume { Usd }
      Stats { TradeCount }
    }
  }
}
```

### Top 50 Token Holders

Fetch the top 50 holders sorted by USD balance:

```graphql theme={null}
query {
  Solana {
    TokenHolders(
      tokenAddress: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"
      orderBy: {descending: LatestBalanceUSD}
      limit: { count: 50 }
    ) {
      Holder { Address }
      LatestBalance
      LatestBalanceUSD
      FirstSeen
      LastSeen
    }
  }
}
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Filtering" icon="filter" href="/en/graphql/schema/filtering">
    Combine ordering with filters to build precise analytical queries.
  </Card>

  <Card title="Metrics & Aggregation" icon="chart-simple" href="/en/graphql/schema/metrics-aggregation">
    Aggregate ordered data with count, sum, avg, min, max, uniq.
  </Card>
</CardGroup>
