Cookbook > Subgraph Best Practice 2: Manage Arrays with @derivedFrom

Subgraph Best Practice 2 - Improve Indexing and Query Responsiveness By Using @derivedFrom

Reading time: 2 min

TLDR

Link to this section

Arrays in your schema can really slow down a subgraph's performance as they grow beyond thousands of entries. If possible, the @derivedFrom directive should be used when using arrays as it prevents large arrays from forming, simplifies handlers, and reduces the size of individual entities, improving indexing speed and query performance significantly.

How to Use the @derivedFrom Directive

Link to this section

You just need to add a @derivedFrom directive after your array in your schema. Like this:

comments: [Comment!]! @derivedFrom(field: "post")

@derivedFrom creates efficient one-to-many relationships, enabling an entity to dynamically associate with multiple related entities based on a field in the related entity. This approach removes the need for both sides of the relationship to store duplicate data, making the subgraph more efficient.

Example Use Case for @derivedFrom

Link to this section

An example of a dynamically growing array is a blogging platform where a “Post” can have many “Comments”.

Let’s start with our two entities, Post and Comment

Without optimization, you could implement it like this with an array:

type Post @entity {
id: Bytes!
title: String!
content: String!
comments: [Comment!]!
}
type Comment @entity {
id: Bytes!
content: String!
}

Arrays like these will effectively store extra Comments data on the Post side of the relationship.

Here’s what an optimized version looks like using @derivedFrom:

type Post @entity {
id: Bytes!
title: String!
content: String!
comments: [Comment!]! @derivedFrom(field: "post")
}
type Comment @entity {
id: Bytes!
content: String!
post: Post!
}

Just by adding the @derivedFrom directive, this schema will only store the “Comments” on the “Comments” side of the relationship and not on the “Post” side of the relationship. Arrays are stored across individual rows, which allows them to expand significantly. This can lead to particularly large sizes if their growth is unbounded.

This will not only make our subgraph more efficient, but it will also unlock three features:

  1. We can query the Post and see all of its comments.

  2. We can do a reverse lookup and query any Comment and see which post it comes from.

  3. We can use Derived Field Loaders to unlock the ability to directly access and manipulate data from virtual relationships in our subgraph mappings.

Adopting the @derivedFrom directive in subgraphs effectively handles dynamically growing arrays, enhancing indexing efficiency and data retrieval.

To learn more detailed strategies to avoid large arrays, read this blog from Kevin Jones: Best Practices in Subgraph Development: Avoiding Large Arrays.

Edit page

Previous
Subgraph Best Practice 1: Pruning with indexerHints
Next
Subgraph Best Practice 3: Using Immutable Entities and Bytes as IDs
Edit page