
Before a file becomes a Merkle DAG, it has to get cut into pieces, and how IPFS chooses where to cut matters more than it looks. IPFS's default chunker slices every file into fixed 256 KiB blocks. It also ships two content-defined alternatives, Rabin fingerprinting and Buzhash, that pick cut points based on the data itself instead of a fixed byte count. The difference sounds academic until you edit a file and re-add it, at which point one approach keeps most of the original blocks and the other regenerates almost all of them.
TL;DR:
DefaultSplitter/SizeSplitter in the boxo/chunker packagepinFilesToIPFS() uses whatever chunker the underlying IPFS layer defaults to, which is fixed-size unless configured otherwiseIPFS's default splitter is about as simple as chunking gets: read 262,144 bytes (256 KiB), call that one block, repeat until the file runs out, with the final block being whatever is left over. This is the DefaultSplitter (built on NewSizeSplitter) in IPFS's chunker package, and it is what runs unless you explicitly ask for something else. Fixed-size chunking is fast, predictable, every block except the last is exactly the same size, and simple to reason about.
The weakness shows up the moment a file changes rather than getting uploaded fresh. Insert a single byte near the beginning of a large file and re-chunk it with a fixed-size splitter: every chunk boundary after that insertion point shifts by one byte, which means every block after it now contains different bytes than before, which means every one of those blocks hashes differently. A one-byte edit to a 10 MB file can end up looking, block-by-block, like an almost entirely different file, even though 99.99% of the actual content is unchanged. This is the "byte-shifting problem," and it directly undermines deduplication: IPFS can only skip re-storing a block if that exact block already exists somewhere, and fixed-size chunking after an edit produces mostly-new blocks even when the underlying change was tiny.
IPFS's chunker package also ships two content-defined chunkers: Rabin fingerprinting and Buzhash. Both work on the same underlying idea: instead of counting a fixed number of bytes and cutting, they run a rolling hash over the data and cut whenever that hash matches a pattern, a boundary condition determined by the content itself rather than a byte counter. Because the cut points are anchored to the data, inserting a byte near the start of a file shifts the position of the next boundary but the content-derived boundaries themselves stay in the same relative places relative to unchanged data further into the file. Most blocks after the edit end up identical to before, and only the block or two immediately around the edit actually changes.
The Rabin implementation in IPFS's chunker takes a target average block size and derives a min and max from it (roughly a third of the average as the floor, one and a half times the average as the ceiling), rather than guaranteeing an exact size like the fixed-size splitter does. That is the real tradeoff: content-defined chunking gives up exact, predictable block sizes in exchange for chunk boundaries that survive small edits.
Deduplication on IPFS happens purely at the block level: if two different files (or two versions of the same file) happen to produce an identical block, that block is only stored and transferred once, referenced by both. Fixed-size chunking gets this right for files that are genuinely identical byte-for-byte, and gets it almost entirely wrong for files that are mostly the same but shifted by an insertion or deletion somewhere in the middle. Content-defined chunking is specifically the fix for that second case, at the cost of slightly more complex, slightly slower chunking logic, since computing a rolling hash over every byte costs more than counting to 262,144.
AIOZ Pin's SDK methods (pinFilesToIPFS(), pinFolderToIPFS()) do not expose a chunker choice; they run on whatever the underlying IPFS layer defaults to, fixed-size, 256 KiB blocks. In practice this means: pinning the exact same file twice deduplicates cleanly (identical bytes produce identical blocks either way), but pinning a lightly-edited version of a file you already pinned, a corrected typo in a document, a metadata tweak, a version bump, will likely produce a mostly new set of blocks rather than reusing most of the original ones. If you are building something where minimizing storage across many versions of similar files actually matters, that is a real, practical consequence of the default chunker, not a hypothetical one.
What is IPFS's default chunk size? 262,144 bytes (256 KiB) per block, except the final block of a file, which is whatever is left over. This comes from the DefaultSplitter in IPFS's chunker package.
What is the byte-shifting problem? When fixed-size chunking hits a file that has been edited (a byte inserted or removed), every chunk boundary after the edit point shifts, causing most subsequent blocks to hash differently from before, even though most of the actual content is unchanged.
What is content-defined chunking? An alternative chunking method where cut points are determined by a rolling hash over the data itself rather than a fixed byte count, so most blocks stay identical across small edits to a file instead of shifting entirely.
Does IPFS support content-defined chunking? Yes. IPFS's chunker package includes both Rabin fingerprinting and Buzhash as content-defined alternatives to the default fixed-size splitter.
Which chunker does AIOZ Pin use? AIOZ Pin's SDK does not expose a chunker option; pinning calls use the underlying IPFS layer's default, which is fixed-size, 256 KiB blocks.
Does chunking choice affect a file's CID? Yes, indirectly. Different chunk boundaries produce different blocks, which produce a different Merkle DAG structure, which produces a different root hash, so the same file content chunked two different ways can resolve to two different CIDs.

IPFS defaults to 256 KiB fixed-size chunks, but also ships Rabin and Buzhash content-defined chunkers. Here is why the choice affects deduplication.

An IPFS CID is not a random string. It encodes a version, a codec, and a hash algorithm plus digest. Here is how to decode a real CID piece by piece.

IPFS does not use a B-tree for large directories. It uses a HAMT, a Hash Array Mapped Trie. Here is exactly how it shards a folder once it outgrows one block.

AIOZ Pin image resizing happens straight in the gateway URL, no upload step or separate service. Here is every img- parameter, with real srcset examples.

x402 payments let ERC-8004 weight a paid AI agent interaction more heavily than free work in its reputation score. Here is exactly how that link works.

AIOZ Pin NFT API calls pin an asset and its metadata as two tracked pins under one record. Here is how to automate it directly over REST, no SDK needed.