What is a metadata endpoint?
A metadata endpoint serves as the source of NFT metadata on the Immutable platform. When items are minted, our platform queries this endpoint to retrieve specific metadata for each item. Collection owners have the ability to update this metadata and request a refresh for a specific set of tokens.
Why IPFS?
IPFS (InterPlanetary File System) is a cost-effective solution, particularly for startups and small projects. It eliminates the need to build your own caching or API infrastructure by leveraging Public Gateways like Pinata, Web3.storage, and NFT.storage.
What is IPFS? https://docs.ipfs.tech/concepts/what-is-ipfs/
What is a gateway? https://docs.ipfs.tech/concepts/ipfs-gateway/
Understanding Metadata Endpoints
The metadata endpoint functions as a shared platform service responsible for retrieving asset metadata. Its requirements differ slightly from simply fetching the NFT image. One important aspect to note is that when retrieving assets from an endpoint, there is a 5-second timeout. This timeout ensures a stable service for all platform users. Additional platform limitations can be found in the documentation linked here [deep dive on Immutable metadata].
Deep dive on Immutable metadata: https://docs.x.immutable.com/docs/deep-dive-metadata/
Comparison of Popular Gateways:
Here is a comparison of some popular gateways:
Pinata:
Free Tier: Available
Features: JS SDK, REST API
Limitations: Maximum 500 pinned files, unable to upload directories with more than 5k-10 files, global rate limit of 15 requests per minute per CID, IP address rate limit of 200 requests per minute, does not support IPFS DAG feature.
Useful Links
Web3 Storage:
Free Tier: Available
Features: JS SDK, Go SDK, API
Limitations: 30 requests per 10 seconds per token, 5GB storage limit on the free tier.
Useful Links:
For the latest features and limits, refer to the services' websites.
Performance Experiment:
In our experiment, we uploaded four batches of metadata directories containing 20k, 80k, 120k, and 200k items to both web3.storage and nft.storage. We then queried the files using Python and GoLang to measure the retrieval time for metadata.
If you are interested in performing similar tests or exploring the upload and performance code, you can find the open-source code here.
Conclusions
Using IPFS as a metadata endpoint for large collections that require regular updates is not optimal. Performance is notably impacted when dealing with a large number of files in a directory. The data from our experiment showed that non-cached response times nearly doubled with each increase in batch size. Caching and distribution performance can vary, depending on the cache status of the queried node.
Fortunately, the 5-second timeout should suffice for most use cases, including larger collections, provided the data has been propagated on IPFS. For large directories, it is advisable to upload them well in advance to ensure sufficient time for full archiving on IPFS. Collections with 100k+ items may take up to 48 hours to fully archive for reasonable performance.
Among the gateways tested, NFT Storage proved to be the easiest to work with when using the NFT Up application. It uploaded the entire collection in approximately 30 minutes, although larger collections took longer to archive. Performance-wise, NFT Storage and Web3 Storage exhibited similar results.
We did not test Pinata due to its inability to support large directory uploads. Additionally, GoLang outperformed Python in terms of performance, and leveraging its retry functionality could yield even better results. However, further testing in the same environment as the crawler is required to validate this observation.
Actual Results
NFT Storage
20k Files:
Python | Go |
ID: 60 | ID: 107 |
ID: 9157 | ID: 6630 |
ID: 17073 | ID: 14270 |
ID: 18626 | ID: 16239 |
80k Files:
Python | Go |
ID: 192 | ID: 157 |
ID: 4155 | ID: 4733 |
ID: 36004 | ID: 31051 |
ID: 76076 | ID: 62239 |
120k FIles:
Python | Go |
ID: 45 | ID: 212 |
ID: 30456 | ID: 41511 |
ID: 72444 | ID: 52777 |
ID: 113690 | ID: 118622 |
200k FIles:
Python | Go |
ID: 629 | ID: 882 |
ID: 45017 | ID: 44631 |
ID: 16149 | ID: 129189 |
ID: 199342 | ID: 179927 |
Web3 Storage
20k Files:
Python | Go |
ID: 174 | ID: 12 |
ID: 5451 | ID: 6437 |
ID: 10963 | ID: 11200 |
ID: 19369 | ID: 17832 |
80k Files:
Python | Go |
ID: 451 | ID: 45 |
ID: 3355 | ID: 4439 |
ID: 32685 | ID: 37054 |
ID: 78456 | ID: 78889 |
120k FIles:
Python | Go |
ID: 231 | ID: 212 |
ID: 44787 | ID: 41511 |
ID: 59177 | ID: 52777 |
ID: 113778 | ID: 118622 |
200k FIles:
Python | Go |
ID: 149 | ID: 1933 |
ID: 44588 | ID: 45611 |
ID: 57000 | ID: 98229 |
ID: 111681 | ID: 197907 |