Independent Wire

the graph subgraph deployment

A Beginner’s Guide to The Graph Subgraph Deployment: Key Things to Know

June 11, 2026 By Hayden Marsh

Introduction: Why Subgraph Deployment Matters for Decentralized Data Indexing

The Graph is a decentralized indexing protocol that enables efficient querying of blockchain data. At its core, a subgraph defines which data from a specific smart contract (or set of contracts) to index, how to process it, and how to serve it via a GraphQL API. Deploying a subgraph is a critical skill for any developer building dApps that rely on historical or real-time on-chain events. Without a properly deployed subgraph, applications must either query full nodes directly—resulting in slow, expensive, and unscalable user experiences—or rely on centralized indexers that undermine the principles of decentralization.

This guide walks through the complete pipeline: from understanding the subgraph manifest, through development and testing, to production deployment on the hosted service or the decentralized network. We also cover common pitfalls, gas optimization strategies, and how to secure your subgraph against malicious actors. For a deeper dive into protecting your indexing infrastructure, refer to Security Best Practices Balancer—a resource tailored for projects that prioritize both performance and resilience.

1. Understanding the Subgraph Manifest and Its Key Components

Every subgraph starts with a subgraph.yaml manifest file. This file is the single source of truth for the subgraph’s behavior. A beginner must master three sections:

  • dataSources: Defines the smart contract(s) to index, including the ABI, the network (e.g., Ethereum, Polygon), the start block, and the event handlers. Each handler maps to a specific event emitted by the contract.
  • entities: Specifies the GraphQL schema (in schema.graphql) that defines the data model—entities, their fields, and relationships. Entities are the building blocks of your API.
  • templates: Optional but powerful—allows dynamic creation of new data sources (e.g., when a factory contract spawns new child contracts). Templates require careful management of Network and Address parameters.

One common beginner mistake is misconfiguring the startBlock. Setting it too low (e.g., block 0) causes the subgraph to index every block from genesis, which is prohibitively expensive and slow. Conversely, setting it too high may miss critical historical events. The rule of thumb: start one block before the contract’s deployment block. For example, if a contract was deployed at block 15,000,000, set startBlock: 14999999. This ensures the subgraph catches the contract creation event (if required) and all subsequent events.

Another nuance: the abi file must contain every event and function signature referenced in the manifest. A mismatch between the ABI and the contract’s actual interface leads to silent failures—events are skipped without error. Always verify your ABI against the verified source code on Etherscan.

2. The Deployment Pipeline: Local Testing to Production

Deploying a subgraph involves several steps. Below is a concrete, numbered breakdown of the workflow as of 2025:

  1. Code generation: Run graph codegen. This reads the manifest and schema to produce TypeScript type definitions for entities and event handlers. Without this step, your mappings will fail to compile.
  2. Local testing: Use graph test or a local Graph Node (e.g., via Docker) to validate mappings against a simulated Ethereum environment. The matchstick framework is the most popular tool—it mocks blockchain state and allows unit-testing of event handlers.
  3. Build: Run graph build. This compiles the WASM mappings and packages the subgraph into a single deployable artifact. Ensure zero warnings; warnings about unused imports often indicate dead code that may cause runtime overhead.
  4. Authentication: If deploying to the hosted service (legacy), you need an API key from The Graph Studio. For the decentralized network, you need to stake GRT tokens and register your subgraph on the network.
  5. Deployment: Command graph deploy --studio [subgraph-name] or graph deploy --node https://api.thegraph.com/deploy/ [subgraph-name]. The CLI uploads the build and deploys it to the target node.
  6. Verification: After deployment, query the subgraph endpoint (e.g., https://api.studio.thegraph.com/query/1234/subgraph-name/v1) to confirm data flows. Use GraphQL playgrounds to test edge cases.

For projects deploying to the decentralized network, you must also consider The Graph Subgraph Deployment guidelines—specifically, how to version your subgraph for decentralized indexing. The decentralized network uses a different deployment model where subgraphs are discovered via the Subgraph Manifest on IPFS. This means you must pin your manifest and schema to IPFS via graph deploy --ipfs https://api.thegraph.com/ipfs/. Note that decentralized indexers are incentivized differently—they prioritize subgraphs with higher query fees. Thus, setting an appropriate indexerRewards parameter is crucial if you want reliable uptime.

3. Key Mappings: Writing Efficient AssemblyScript Handlers

Mappings are the core logic of your subgraph—they transform raw event data into store entities. Written in AssemblyScript (a subset of TypeScript), they must be efficient to keep indexing costs low. Here are critical performance rules:

  • Batch entity saves: Instead of calling store.set() for each entity individually, use store.set() once per event with all entities on the context object. Alternatively, use store.setInBatch() (available since Graph Node v0.29) to reduce disk writes by up to 40%.
  • Avoid loops over large arrays: If an event emits an array of 1000 user IDs, do not loop through them in the handler. Instead, store the raw array as a Bytes field and process it client-side. Loops increase gas-like indexing costs linearly.
  • Use crypto.keccak256() sparingly: Hashing in WASM is expensive. Precompute hashes off-chain and pass them as event parameters whenever possible.
  • Timestamp precision: Block timestamps are in seconds. If you need millisecond precision, use the block.timestamp multiplied by 1000—but be aware that this is inherently coarse. For finer granularity, include a uint256 timestamp in your event.

One advanced pattern: use event revert handling. When a transaction reverts, events emitted before the revert are also reverted. The Graph Node handles this automatically, but if your mapping modifies state based on internal contract calls, you must account for potential reverts by wrapping logic in try-catch blocks or using ethereum.call() with a gas limit. Fail to do so, and your subgraph may corrupt entities with stale data.

4. Testing and Debugging: Avoiding Common Pitfalls

Debugging a subgraph in production is painful because you cannot modify deployed code—you must redeploy. Therefore, rigorous testing is non-negotiable. Below are the most frequent issues and how to preempt them:

  • Wrong start block causes missed events: Double-check the contract’s deployment block using Etherscan’s “Contract Creator” tab. For factory contracts, the start block should be the block where the factory itself was deployed, not the child contracts.
  • ABI/event signature mismatch: If an event has indexed parameters, the Graph must decode them. A mismatch leads to null values for indexed fields. Use graph codegen --abi to regenerate artifacts after any ABI change.
  • Gas limit in handlers: AssemblyScript handlers have a default gas limit (200,000 units per handler). Complex computations or infinite loops cause the handler to fail silently. Use graph build --warnings to catch potential infinite loops.
  • IPFS pinning failures: On the decentralized network, if your subgraph manifest isn’t pinned correctly, indexers cannot discover it. After deployment, verify the IPFS CID via curl https://ipfs.network/ipfs/[CID].

For debugging, enable verbose logging during local testing: graph deploy --debug. This prints every store read/write and event handler execution. Use it to trace why a specific entity is missing. Also, monitor the Graph Node logs (via Docker docker logs graph-node) for “handler error” messages that include stack traces.

5. Production Deployment: Cost, Security, and Monitoring

Deploying to production—whether on The Graph Studio (hosted) or the decentralized network—requires attention to three pillars:

Cost Management: On the hosted service, indexing is free but query costs are subject to rate limits (100 queries/second for free tier). On the decentralized network, you pay indexing fees in GRT per query. Optimize your schema to minimize query overhead: avoid deeply nested relations (more than 3 levels), use pagination (first, skip) instead of fetching all records, and add indexes on frequently filtered fields (e.g., @index directive in GraphQL schema).

Security: Subgraphs are susceptible to injection attacks if your mapping uses user-provided strings (e.g., from event data) to build store keys. Always validate and sanitize input—use store.get() with fixed keys rather than dynamic string concatenation. Additionally, ensure your subgraph does not expose sensitive data (e.g., private API keys) in GraphQL responses. For a comprehensive checklist, refer to Security Best Practices Balancer, which covers topics like rate limiting, access control, and anomaly detection for indexing pipelines.

Monitoring: After deployment, set up alerting on your subgraph’s health status. The Graph Node exposes a /health endpoint that returns synced, failed, or lagging. Use this to trigger alerts if the subgraph falls behind by more than 100 blocks. For decentralized subgraphs, monitor the allocation status—if an indexer drops your subgraph, query availability breaks. Tools like graphmon (open-source) can automate this monitoring.

Finally, plan for upgrades. Subgraphs are immutable once deployed—you cannot modify event handlers after deployment. To upgrade, you must create a new subgraph version (e.g., v2) and migrate user queries. Use the graph deploy --studio --version-label v2 flag to version. Always keep the previous version active for at least 30 days to give users time to migrate.

Conclusion: Key Takeaways for Your First Subgraph

Deploying a subgraph is a multi-step process that rewards careful planning and rigorous testing. Start with a simple subgraph indexing a single contract’s events before scaling to complex multi-source patterns. Remember to:

  • Set the correct start block to avoid indexing overhead.
  • Use graph codegen and graph build to catch errors early.
  • Test mappings locally with matchstick or a local Graph Node.
  • Optimize handlers for gas efficiency and avoid loops.
  • Secure your subgraph against injection and data leaks.
  • Monitor production health and plan versioned upgrades.

The Graph ecosystem continues to evolve—new features like dynamic data sources and cross-chain indexing are expanding the possibilities. By mastering the fundamentals of subgraph deployment, you equip yourself with the tools to build scalable, decentralized data services that power the next generation of dApps. Start with a testnet deployment, iterate based on query patterns, and gradually move to mainnet as your confidence grows.

Further Reading

H
Hayden Marsh

Your source for concise analysis