IPNS resolution takes a very long time first time around

I set up an IPFS node, added some content and set up an IPNS hash for it. If I restart the node and attempt to resmove the IPNS hash the first time it resolves it takes a long time; subsequent attempts return pretty much immediately:

$ time ipfs resolve /ipns/QmQ4QZh8nrsczdUEwTyfBope4THUhqxqc1fx6qYhhzZQei
/ipfs/QmP3ouCnU8NNLsW6261pAx2pNLV2E4dQoisB1sgda12Act

real    1m0.047s
user    0m0.020s
sys     0m0.000s
$ time ipfs resolve /ipns/QmQ4QZh8nrsczdUEwTyfBope4THUhqxqc1fx6qYhhzZQei
/ipfs/QmP3ouCnU8NNLsW6261pAx2pNLV2E4dQoisB1sgda12Act

real    0m0.016s
user    0m0.010s
sys     0m0.010s

As this is all (I assume) local I’m at a loss as to why it takes quite so long first time around. The fact that the time is just over 1 minute suggests a timeout of some sort; any ideas? Have I missed a step where I should publish the IPNS hash or similar to make it more visible?

I’m running go-ipfs from master.

1 Like

Your intuition is correct – it is the default value of --dht-timeout.

Resolving an IPNS name means you are looking for latest version of the record. Even if you resolve local key, there is the potential for newer versions to exist, somewhere (eg. if you copy key to other machine and publish newer version from there).

You are experiencing the “1m delay” because go-ipfs is spending up to 1m looking for more than one record to confirm freshness.

You can tweak both timeout and number of needed confirmations via --dht-record-count and dht-timeout. You can also make it “streamable” and return discovered values before waiting for timeout via --stream:

$ ipfs name resolve  --help

[...]

  --dhtrc, --dht-record-count uint   - Number of records to request for DHT resolution.
  --dhtt,  --dht-timeout      string - Max time to collect values during DHT resolution eg "30s". Pass 0 for no timeout.
  -s,      --stream           bool   - Stream entries as they are found.

tl;dr If you are resolving address published with key that is under your control, you may try:

ipfs name resolve --dht-record-count 1  --dht-timeout 1s  <key-id>

Hope this helps!

ps. FYSA we are tracking performance related to IPNS in meta-issue at https://github.com/ipfs/go-ipfs/issues/3860

1 Like

Thanks for the info. Has there been consideration to returning the first value found when starting cold, and then continuing the search for updates in the background? Although not a perfect solution, it probably covers more of the common cases for read/write ratio of content.

Separately, how can I tell the ipfs daemon to drop its timeout and reduce the record count when resolving IPNS? I don’t see any configuration options that marry up with the CLI parameters in the default configuration.

Try enabling experimental IPFS over pubsub. It should make local resolve right after publish instant, and improve IPNS times in general:

$ ipfs daemon --enable-namesys-pubsub

$ ipfs name publish /ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
$ ipfs name resolve QmdWfKs4TKpec5X6ENmaVHEfWg6uvUAPpk3fbF5DMzz6nS # should be instant

IIUC its on purpose to ensure all users of HTTP Gateway get the same security guarantees.
Right now the default global record count for name resolve is 16 confirmations (ipfs name publish creates 20 records in DHT, so resolve requires ack from 80%). You can override it via CLI, but HTTP Gateway always uses the default.

1 Like

@mcdee @lidel the stream option should work for:

It does exactly what you are asking for. PubSub is helpful as well, but not strictly required for this use case.