Back

Blog details

IPLD Selectors: Fetching Part of a DAG, Not All of It

AIOZ Network
5 min readSeptember 08, 2026
aioz-pin

IPLD Selectors answer a question this series has left open until now: when a DAG is large, how does a client ask for just the part it actually needs instead of everything reachable from the root? The CAR export covered earlier in this series walks a CID's entire reachable graph by default. Selectors are what let that default get replaced with something much narrower, declared precisely, instead of a client fetching a whole directory to read one file.

TL;DR:

  • A Selector is a declarative description of how to traverse an IPLD DAG, and which nodes along the way to include in the result, roughly the DAG equivalent of a regular expression for text
  • Traversal is built from a small set of composable primitives: ExploreAll, ExploreFields, ExploreIndex, ExploreRange, ExploreRecursive, ExploreUnion, and a Matcher that actually marks a node as part of the result
  • ExploreRecursive is what makes a Selector safe to run without an explicit depth limit, since a DAG has no cycles, so a recursive walk is guaranteed to terminate
  • Selectors are what makes a scoped CAR export possible: instead of ipfs dag export walking everything under a root, a Selector can describe exactly the sub-path worth including
  • On AIOZ Pin, this matters most for large pinned directories, since a Selector-aware export can hand someone one file's worth of a huge pinned folder's DAG instead of the entire structure

The Problem: "Everything Under This CID" Is Often Too Much

This series' CAR-files article described exporting a CID's DAG by walking every block reachable from its root, which is exactly the right default for a genuine full backup. It's the wrong default for a much more common case: someone wants one specific file out of a large pinned directory, or one field out of a large structured document, and has no interest in transferring or storing everything else that happens to live under the same root CID. Without a way to describe "just this part," the only options are fetching everything or writing custom, non-portable logic for every different shape of DAG that needs partial access.

What a Selector Actually Is

A Selector is a declarative specification for how to walk an IPLD DAG, roughly analogous to a regular expression for structured graph data instead of text. It doesn't fetch anything itself; it describes a traversal plan, which nodes to walk into and which ones to actually collect as results, and any tool that understands the Selector format, an exporter, a gateway, a custom client, can execute that same plan consistently.

The Building Blocks

Selectors are built from a small set of composable traversal primitives, each handling one specific pattern. ExploreAll walks every child of a node. ExploreFields walks only specific named fields, useful for structured data where only some fields matter. ExploreIndex and ExploreRange walk specific positions or a slice of a list. ExploreUnion lets more than one selector apply at the same node simultaneously, matching a node while also continuing to explore deeper along a different path. A Matcher is the piece that actually marks a node as part of the result set, distinct from the exploration primitives, which only control where the walk goes next without necessarily including what it passes through.

Why Recursive Traversal Is Safe Without a Depth Limit

ExploreRecursive walks a graph without an explicit depth cutoff, continuing until it has covered everything the selector's recursion condition applies to. That would be dangerous on an arbitrary graph, but IPLD DAGs are, by definition, acyclic: this series' hub article covers why a Merkle DAG's hash-linking structure makes cycles impossible in the first place. Because of that guarantee, a recursive Selector is safe to run without bounding it manually; the DAG's own structure is what ensures the walk terminates.

Scoped Exports: Selectors Behind a Narrower CAR File

This is where Selectors connect directly to the CAR file format this series already covered: a plain ipfs dag export uses the simplest possible selector, everything reachable from the root, but a tool built around Selectors can export a CAR file scoped to a much narrower traversal instead, one file inside a large directory, one field inside a large document, without touching the rest of the structure at all. The resulting archive is smaller, faster to produce, and still just as independently verifiable as a full export, since every block it does contain still carries its own CID.

Selectors as a Shared Language, Not a One-Off Format

The reason Selectors are worth learning as their own concept, rather than treating "fetch part of a DAG" as something every tool solves its own way, is portability. A Selector written to describe "this file inside this directory" is a plain, serializable data structure, not a snippet of code specific to one programming language or one IPFS implementation. That means the same Selector can be handed to a Go-based export tool, a JavaScript-based Helia client, or any other IPLD-aware implementation, and each one executes the identical traversal plan. Without a shared, declarative format like this, partial retrieval would mean re-implementing custom traversal logic separately for every tool, every language, and every DAG shape, exactly the kind of fragmentation content addressing's other shared standards, covered throughout this series, exist to avoid.

Where This Fits an AIOZ Pin Workflow

For a large folder pinned on AIOZ Pin via pinFolderToIPFS(), covered in this series' UnixFS article, a full CAR export walks the entire directory tree, every file, every subdirectory, every HAMT shard if the directory is large enough to need one. A Selector-scoped export changes that: someone who only needs one specific file out of that structure can describe exactly that path and get a much smaller, faster archive back, without AIOZ Pin needing to change anything about how the folder is stored or pinned in the first place. The efficiency gain lives entirely in how the export is requested, not in the underlying pinning mechanism.

Frequently Asked Questions

What is an IPLD Selector? A declarative description of how to traverse an IPLD DAG and which nodes to include in the result, similar in spirit to a regular expression, but built for graph-structured data instead of text.

Does a Selector fetch data itself? No. It describes a traversal plan. Any tool that understands the format, an exporter, gateway, or custom client, executes that plan to actually walk and collect data.

What's the difference between exploring a node and matching it? Exploration primitives (like ExploreAll or ExploreFields) control where the traversal goes next. A Matcher is what actually marks a node as part of the returned result, a separate concept from simply walking through it.

Why is recursive traversal safe without a depth limit? Because IPLD DAGs are acyclic by construction, a hash-linked structure can't loop back on itself, so a recursive walk is guaranteed to terminate rather than run forever.

How do Selectors relate to CAR files? A plain CAR export uses the simplest possible selector, everything under a root. A Selector-aware export can scope that same CAR format to a much narrower slice of the DAG instead of the whole thing.

Does using a Selector require AIOZ Pin to store content differently? No. Selectors only change how an export or fetch is requested, walking a narrower path through the same DAG. The underlying pinning and storage stay exactly the same.

References

We only send updates when meaningful changes ship, and you can unsubscribe anytime

Related Content

blog thumbnail

Content Moderation on IPFS: What Actually Happens

Pinning services can remove their own copy of a file. They cannot remove it from IPFS. Here is exactly what a takedown does and does not accomplish.

5 min readSeptember 12, 2026
blog thumbnail

IPFS Transports: TCP vs. QUIC Explained

libp2p connections can run over more than one transport. Here is exactly what changes with QUIC instead of TCP, and why IPFS dials both at once.

5 min readSeptember 11, 2026
blog thumbnail

GossipSub: How IPFS's PubSub Layer Actually Works

The DHT answers who has a CID. GossipSub answers a different question: how do peers push real-time updates to everyone listening, without a lookup at all.

5 min readSeptember 10, 2026
blog thumbnail

Helia: IPFS's Modern JavaScript Implementation

js-ipfs is deprecated. Helia is what replaced it: a modular, TypeScript-first IPFS implementation built for the browser and Node.js. Here is how it fits.

5 min readSeptember 09, 2026
blog thumbnail

IPLD Selectors: Fetching Part of a DAG, Not All of It

Not every retrieval needs the whole DAG. IPLD Selectors describe exactly which nodes to traverse and match, so a client can fetch a slice, not everything.

5 min readSeptember 08, 2026
blog thumbnail

ipfs:// in the Browser: How It Actually Works

Almost no browser understands ipfs:// links natively. Here is exactly why, what IPFS Companion actually does about it, and why gateway URLs took over instead.

5 min readSeptember 07, 2026