Docs

aggregations

Complex aggregation queries examples

Coming soon: Need support for this? Email support@dwellir.com and we will enable it for you.

GraphQL aggregations enable powerful analytical queries on Aptos blockchain data, allowing you to compute statistics, counts, sums, and other aggregate functions across large datasets. These queries are essential for building analytics dashboards, generating reports, and understanding on-chain activity patterns without processing individual records.

Overview

The Aptos GraphQL indexer provides aggregate functions that operate on filtered datasets, enabling you to answer questions like "How many transactions occurred today?", "What's the total trading volume?", or "Who are the top gas consumers?" These aggregations run efficiently on indexed data, providing fast results even for complex queries spanning millions of records.

Common Aggregate Functions

The GraphQL API supports standard aggregate operations:

count: Total number of records matching criteria sum: Sum of numeric field values avg: Average of numeric values max: Maximum value in dataset min: Minimum value in dataset stddev: Standard deviation of values variance: Variance of values

Example Queries

Transaction Volume Analysis

graphql
query TransactionMetrics($startTime: timestamp!, $endTime: timestamp!) {
  user_transactions_aggregate(
    where: {
      timestamp: { _gte: $startTime, _lte: $endTime }
    }
  ) {
    aggregate {
      count
      sum { gas_used }
      avg { gas_used }
      max { gas_used }
      min { gas_used }
    }
  }
}

Top Gas Consumers

graphql
query TopGasUsers($limit: Int!) {
  user_transactions_aggregate {
    aggregate { count }
  }
  user_transactions(
    order_by: { gas_used: desc },
    limit: $limit
  ) {
    sender
    gas_used
    version
    timestamp
  }
}

Daily Active Users

graphql
query DailyActiveUsers($date: date!) {
  user_transactions_aggregate(
    distinct_on: sender,
    where: {
      timestamp: {
        _gte: $date,
        _lt: "${date + 1 day}"
      }
    }
  ) {
    aggregate {
      count(distinct: true, columns: sender)
    }
  }
}

Token Transfer Statistics

graphql
query TokenTransferStats($token_type: String!) {
  coin_activities_aggregate(
    where: {
      coin_type: { _eq: $token_type },
      activity_type: { _eq: "0x1::coin::WithdrawEvent" }
    }
  ) {
    aggregate {
      count
      sum { amount }
      avg { amount }
    }
  }
}

NFT Collection Analytics

graphql
query CollectionMetrics($collection_id: String!) {
  current_token_ownerships_v2_aggregate(
    where: {
      current_token_data: {
        collection_id: { _eq: $collection_id }
      }
    }
  ) {
    aggregate {
      count
    }
  }

  token_activities_v2_aggregate(
    where: {
      token_data_id: { _like: "${collection_id}%" },
      type: { _eq: "0x3::token::MintTokenEvent" }
    }
  ) {
    aggregate {
      count
    }
  }
}

Real-World Use Cases

  1. Protocol Analytics: Track total value locked, transaction volumes, user growth, and other key metrics for DeFi protocols and dApps.

  2. User Behavior Analysis: Understand user engagement patterns, identify power users, and analyze transaction frequency distributions.

  3. Gas Optimization Research: Analyze gas consumption patterns to identify optimization opportunities and compare efficiency across different contract designs.

  4. Market Intelligence: Aggregate trading volumes, price movements, and liquidity metrics for tokens and NFT collections.

  5. Network Health Monitoring: Track transaction success rates, average confirmation times, and network utilization over time.

  6. Revenue Reporting: Calculate total fees collected, transaction counts by type, and other financial metrics for business reporting.

Best Practices

Use Appropriate Filters: Apply WHERE clauses to reduce dataset size before aggregation for better performance.

Leverage Indexed Fields: Aggregations on indexed fields (addresses, timestamps, types) perform significantly faster.

Batch Time-Series Queries: For dashboards displaying multiple time periods, batch queries together to reduce API calls.

Cache Results: Aggregate statistics change slowly - implement appropriate caching strategies to reduce load.

Pagination for Details: When showing aggregate summaries plus details, paginate the detail results appropriately.

Use Variables: Parameterize queries with GraphQL variables for reusable, type-safe queries.

Performance Considerations

  • Aggregations on large unfiltered tables can be slow - always use WHERE clauses
  • Distinct counts are more expensive than simple counts
  • Complex nested aggregations should be avoided or split into multiple queries
  • Consider using materialized views for frequently accessed aggregations
  • Time-range queries on timestamp fields are well-optimized

Combining Aggregates with Details

graphql
query DashboardMetrics($limit: Int!) {
  # Overall statistics
  metrics: user_transactions_aggregate {
    aggregate {
      count
      avg { gas_used }
      sum { gas_used }
    }
  }

  # Top performers
  top_users: user_transactions(
    order_by: { gas_used: desc },
    limit: $limit,
    distinct_on: sender
  ) {
    sender
    gas_used
  }

  # Recent activity
  recent: user_transactions(
    order_by: { timestamp: desc },
    limit: $limit
  ) {
    hash
    sender
    timestamp
    success
  }
}

TypeScript Integration

TypeScript
import { ApolloClient, gql } from "@apollo/client";

const client = new ApolloClient({
  uri: "https://api-aptos-mainnet.n.dwellir.com/YOUR_API_KEY/v1/graphql"
});

const TRANSACTION_STATS = gql`
  query TransactionStats {
    user_transactions_aggregate {
      aggregate {
        count
        avg { gas_used }
      }
    }
  }
`;

const { data } = await client.query({ query: TRANSACTION_STATS });
console.log(`Total transactions: ${data.user_transactions_aggregate.aggregate.count}`);
console.log(`Average gas: ${data.user_transactions_aggregate.aggregate.avg.gas_used}`);