Skip to main content
AMP-powered subgraphs are a new kind of subgraphs with SQL data sources that query and index data from AMP servers. They are significantly more efficient than standard subgraphs, reducing indexing time from days and weeks to minutes and hours in most cases.
This feature is available starting from spec version 1.5.0.

Prerequisites

To enable AMP-powered subgraphs, set the following environment variables:

Required

GRAPH_AMP_FLIGHT_SERVICE_ADDRESS="https://amp-flight-service.example.com:443"
Must be set to a valid AMP Flight gRPC service address. Without this, AMP-powered subgraphs are disabled.

Optional (If Authentication Required)

GRAPH_AMP_FLIGHT_SERVICE_TOKEN="your-authentication-token"
Contains a valid authentication token for the AMP Flight gRPC service.

Subgraph Manifest Structure

AMP-powered subgraphs use a different manifest structure than standard subgraphs.

Minimum Spec Version

specVersion: 1.5.0
The minimum spec version for AMP-powered subgraphs is 1.5.0.

Data Source Overview

specVersion: 1.5.0
dataSources:
  - kind: amp
    name: Transfers
    network: ethereum-mainnet
    source:
      dataset: edgeandnode/ethereum_mainnet
      tables:
        - blocks
        - transactions
    transformer:
      apiVersion: 0.0.1
      tables:
        - name: Transfer
          file: <IPFS CID of the SQL query file>

Data Source Configuration

kind (Required)

Every AMP data source must have kind: amp. AMP-powered subgraphs must contain only AMP data sources.
dataSources:
  - kind: amp
    # ...
Mixing AMP and non-AMP data sources in the same subgraph is not supported.

name (Required)

A non-empty string containing only numbers, letters, hyphens, or underscores. Used for observability and identifying progress and errors.
dataSources:
  - kind: amp
    name: Transfers
    # ...

network (Required)

Valid network name used to validate that SQL queries produce results for the expected network.
dataSources:
  - kind: amp
    name: Transfers
    network: ethereum-mainnet
    # ...
Currently, SQL queries must produce results for a single network to maintain compatibility with non-AMP subgraphs.

Source Configuration

The source section describes SQL query behavior.

source.dataset (Required)

Dataset name that SQL queries can access. Validates that queries only use the expected dataset.
source:
  dataset: edgeandnode/ethereum_mainnet
  tables:
    - blocks
    - transactions

source.tables (Required)

List of table names that SQL queries can access. Validates that queries only use expected tables.
source:
  dataset: edgeandnode/ethereum_mainnet
  tables:
    - blocks
    - transactions
    - logs

source.address (Optional)

Contract address for the data source. Enables SQL query reuse through sg_source_address() function calls instead of hard-coding addresses.
source:
  address: "0xc944E90C64B2c07662A292be6244BDf05Cda44a7"
  dataset: edgeandnode/ethereum_mainnet
  tables:
    - logs
In SQL queries:
SELECT * FROM "edgeandnode/ethereum_mainnet".logs
WHERE address = sg_source_address()

source.startBlock (Optional)

Minimum block number for SQL queries. Used as the indexing starting point. Default: 0
source:
  startBlock: 11446769
  dataset: edgeandnode/ethereum_mainnet
  tables:
    - blocks

source.endBlock (Optional)

Maximum block number for SQL queries. Indexing completes when reaching this block. Default: Maximum possible block number
source:
  endBlock: 23847939
  dataset: edgeandnode/ethereum_mainnet
  tables:
    - blocks

Transformer Configuration

The transformer section describes how source tables transform into subgraph entities.

transformer.apiVersion (Required)

Transformer version. Each version may have different features.
Currently, only version 0.0.1 is available.
transformer:
  apiVersion: 0.0.1
  tables:
    - name: Transfer
      file: <IPFS CID>

transformer.abis (Optional)

List of ABIs for extracting event signatures in SQL queries. Enables sg_event_signature('CONTRACT_NAME', 'EVENT_NAME') calls that resolve to full event signatures. Default: Empty list
transformer:
  abis:
    - name: ERC721
      file: <IPFS CID of the JSON ABI file>
  apiVersion: 0.0.1
  tables:
    - name: Transfer
      file: <IPFS CID of SQL query>
In SQL queries:
SELECT * FROM "edgeandnode/ethereum_mainnet".logs
WHERE topic0 = sg_event_signature('ERC721', 'Transfer')

transformer.tables (Required)

List of transformed tables extracting data from source tables into subgraph entities.
transformer:
  apiVersion: 0.0.1
  tables:
    - name: Block
      query: SELECT * FROM "edgeandnode/ethereum_mainnet".blocks;

transformer.tables[i].name (Required)

Name of the transformed table. Must reference a valid entity name from the subgraph schema.
# schema.graphql
type Block @entity(immutable: true) {
  id: ID!
  number: BigInt!
  hash: Bytes!
  timestamp: BigInt!
}
# subgraph.yaml
transformer:
  tables:
    - name: Block  # Matches entity name in schema
      file: <IPFS CID>

transformer.tables[i].query (Optional)

Inline SQL query that executes on the AMP server. Useful for simple queries.
transformer:
  tables:
    - name: Block
      query: |
        SELECT
          number,
          hash,
          timestamp,
          _block_num
        FROM "edgeandnode/ethereum_mainnet".blocks
If query is provided, the file field is ignored.

transformer.tables[i].file (Optional)

IPFS link to a SQL query file that executes on the AMP server.
transformer:
  tables:
    - name: Transfer
      file: QmXYZ...abc
If query is not provided, file is used. One of query or file must be present.

SQL Query Requirements

Reserved Prefix

Table names, column names, and aliases must not start with amp_ - this prefix is reserved for internal use.

Block Numbers (Required)

Every SQL query must return the block number for every row. Graph Node looks for block numbers in these columns (in order):
  • _block_num
  • block_num
  • blockNum
  • block
  • block_number
  • blockNumber
SELECT
  _block_num,  -- Block number (required)
  hash,
  timestamp
FROM "edgeandnode/ethereum_mainnet".blocks

Block Hashes (Expected)

Every SQL query should return the block hash for every row. Graph Node looks for block hashes in:
  • hash
  • block_hash
  • blockHash
SELECT
  _block_num,
  hash,  -- Block hash (expected)
  timestamp
FROM "edgeandnode/ethereum_mainnet".blocks
If a table doesn’t contain the block hash column, retrieve it by joining with another table that has it on the _block_num column. If not provided, Graph Node attempts to fetch it from source tables.

Block Timestamps (Required for Aggregations)

Required for subgraphs using aggregations. Graph Node looks for block timestamps in:
  • timestamp
  • block_timestamp
  • blockTimestamp
SELECT
  _block_num,
  hash,
  timestamp  -- Required for aggregations
FROM "edgeandnode/ethereum_mainnet".blocks
Retrieve via join if the table doesn’t have a timestamp column. Graph Node attempts to fetch from source tables if not provided.

Complete Examples

specVersion: 1.5.0
schema:
  file: ./schema.graphql
dataSources:
  - kind: amp
    name: Blocks
    network: ethereum-mainnet
    source:
      dataset: edgeandnode/ethereum_mainnet
      startBlock: 0
      tables:
        - blocks
    transformer:
      apiVersion: 0.0.1
      tables:
        - name: Block
          query: |
            SELECT
              hash as id,
              number,
              hash,
              timestamp,
              _block_num
            FROM "edgeandnode/ethereum_mainnet".blocks
type Block @entity(immutable: true) {
  id: ID!
  number: BigInt!
  hash: Bytes!
  timestamp: BigInt!
}
specVersion: 1.5.0
schema:
  file: ./schema.graphql
dataSources:
  - kind: amp
    name: USDCTransfers
    network: ethereum-mainnet
    source:
      address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"  # USDC
      dataset: edgeandnode/ethereum_mainnet
      startBlock: 6082465
      tables:
        - logs
    transformer:
      apiVersion: 0.0.1
      abis:
        - name: ERC20
          file: ./abis/ERC20.json
      tables:
        - name: Transfer
          file: ./queries/transfers.sql
-- queries/transfers.sql
SELECT
  transaction_hash || '-' || log_index as id,
  '0x' || encode(substring(topic1 from 13 for 20), 'hex') as "from",
  '0x' || encode(substring(topic2 from 13 for 20), 'hex') as "to",
  ('x' || encode(data, 'hex'))::bit(256)::bigint as value,
  _block_num,
  block_hash as hash,
  block_timestamp as timestamp
FROM "edgeandnode/ethereum_mainnet".logs
WHERE
  address = sg_source_address()
  AND topic0 = sg_event_signature('ERC20', 'Transfer')
type Transfer @entity(immutable: true) {
  id: ID!
  from: Bytes!
  to: Bytes!
  value: BigInt!
}
specVersion: 1.5.0
schema:
  file: ./schema.graphql
dataSources:
  - kind: amp
    name: TransactionDetails
    network: ethereum-mainnet
    source:
      dataset: edgeandnode/ethereum_mainnet
      startBlock: 15000000
      tables:
        - transactions
        - blocks
    transformer:
      apiVersion: 0.0.1
      tables:
        - name: TransactionWithBlock
          file: ./queries/transactions.sql
-- queries/transactions.sql
SELECT
  t.hash as id,
  t."from",
  t."to",
  t.value,
  t.gas,
  t.gas_price,
  b.number as block_number,
  b.timestamp as block_timestamp,
  t._block_num,
  b.hash as hash
FROM "edgeandnode/ethereum_mainnet".transactions t
JOIN "edgeandnode/ethereum_mainnet".blocks b
  ON t._block_num = b._block_num
WHERE t.value > 1000000000000000000  -- > 1 ETH
type TransactionWithBlock @entity(immutable: true) {
  id: ID!
  from: Bytes!
  to: Bytes
  value: BigInt!
  gas: BigInt!
  gasPrice: BigInt!
  blockNumber: BigInt!
  blockTimestamp: BigInt!
}

Advanced Features

Schema Generation

AMP-powered subgraphs support automatic GraphQL schema generation based on SQL query schemas. To enable, remove the schema field from the manifest:
specVersion: 1.5.0
# schema: ./schema.graphql  # Remove this line
dataSources:
  - kind: amp
    # ...
Generated entities are immutable.
For flexibility and control, manually created GraphQL schemas are preferred.

Aggregations

AMP-powered subgraphs fully support subgraph aggregations for complex aggregations on indexed data.
type Transfer @entity(immutable: true) {
  id: ID!
  from: Bytes!
  to: Bytes!
  value: BigInt!
}

type TransferStats @entity @aggregation {
  id: ID!
  totalVolume: BigInt! @aggregate(fn: "sum", arg: "value")
  transferCount: BigInt! @aggregate(fn: "count")
  dimensions:
    timestamp: Int! @aggregate(fn: "datetime", arg: "hour")
}
See the aggregations documentation for details.

Composition

AMP-powered subgraphs fully support subgraph composition for applying complex mappings on top of AMP-indexed data. See the composition example for details.

Environment Variables

Additional configuration for AMP-powered subgraphs:
VariableDescriptionDefault
GRAPH_AMP_FLIGHT_SERVICE_ADDRESSAMP Flight gRPC service addressNone (disables AMP)
GRAPH_AMP_FLIGHT_SERVICE_TOKENAuthentication token for AMP FlightNone (no auth)
GRAPH_AMP_BUFFER_SIZEMax response batches buffered in memory per stream per query1,000
GRAPH_AMP_BLOCK_RANGEMax blocks to request per stream per query100,000
GRAPH_AMP_QUERY_RETRY_MIN_DELAY_SECONDSMin time before retrying failed query1
GRAPH_AMP_QUERY_RETRY_MAX_DELAY_SECONDSMax time before retrying failed query600

Example Configuration

GRAPH_AMP_FLIGHT_SERVICE_ADDRESS="https://amp.example.com:443"
GRAPH_AMP_FLIGHT_SERVICE_TOKEN="your-token-here"
GRAPH_AMP_BUFFER_SIZE=2000
GRAPH_AMP_BLOCK_RANGE=50000
GRAPH_AMP_QUERY_RETRY_MIN_DELAY_SECONDS=2
GRAPH_AMP_QUERY_RETRY_MAX_DELAY_SECONDS=300

Metrics

AMP-powered subgraphs report to existing deployment metrics and add new ones:

Existing Metrics

  • deployment_status: Current deployment status
  • deployment_head: Current block height
  • deployment_synced: Whether deployment is synced
  • deployment_blocks_processed_count: Total blocks processed

New Metrics

  • deployment_target: Maximum block number currently available for indexing
  • deployment_indexing_duration_seconds: Total duration of deployment indexing in seconds

Extended Metrics

  • deployment_sync_secs: Extended with AMP-specific indexing process sections

Monitoring Example

# How far behind is the deployment?
deployment_target - deployment_head

# Indexing rate (blocks per second)
rate(deployment_blocks_processed_count[5m])

# Time to sync
(deployment_target - deployment_head) / rate(deployment_blocks_processed_count[5m])

# Total indexing time
deployment_indexing_duration_seconds

Resources

AMP Subgraph Examples

Complete examples with deployment and query patterns

Aggregations Documentation

Learn about subgraph aggregations feature

Composition Example

Composable subgraph patterns and examples

Configuration File

Advanced TOML configuration reference

Performance Benefits

AMP-powered subgraphs offer significant performance improvements:

Faster Indexing

Reduce indexing time from days/weeks to minutes/hours

Lower Resources

Less compute and storage required

SQL Flexibility

Full SQL power for complex data transformations
Performance gains depend on subgraph complexity and data volume. Simple subgraphs may see 10-100x speedup, while complex ones still see significant improvements.

Build docs developers (and LLMs) love