How to use IPNS in a local-first setting?

My intention is to use IPFS as a distributed database with a local-first approach. Programs store and retrieve data (as IPLD nodes) via the IPFS daemon on single computer, and if that computer happens to have a network connection, the same database access works across the network. The main point is that everything should work locally without a network connection (think mobile devices).

This works very well for storing and retrieving data via CIDs. But I do need mutable references as well, and I started to play with IPNS, but so far this has mainly resulted in frustration.

When I publish a new binding for a name, and my computer happens to have no network connection, I get Error: failed to find any peer in table. I thought that --allow-offline would let me do this, but it doesn’t (see https://github.com/ipfs/go-ipfs/issues/6458). The behavior I need is the daemon storing the new binding locally, and broadcasting it asynchronously when possible. Is that doable somehow?

Resolving names is also problematic, because it takes a long time even for keys hosted on the same machine. This makes IPNS unusable as a replacement for a local filesystem, for communication between programs running on the same computer. I do understand that this is due to the possibility of a key being used by several IPFS peers in parallel. However, this is not required for my use case and could safely be considered an error. I’d much prefer local names to be resolved immediately, in particular when there is no network connection. Can this be achieved somehow? I was hoping to use --dhtt with a very short timeout, but that doesn’t seem to work.

1 Like

I believe in the current iteration of IPNS requires that you have DHT/peer connections to work and distribute the records. You might be able to try using IPNS PubSub, I’m not sure if this also has the same issue, but I’m pretty sure it does. Currently IPNS does have some speed issues, however using IPNS PubSub can alleviate most of the issues, and drastically improves performance. Granted, this still isn’t “sufficient” for your usecase.

If you want a “hacky” solution to your issue and be able to still publish records “offline”, I wrote a IPNS publishing library that spins up an extremely lightweight libp2p host just to use for IPNS publishing, so you could spin this one up alongside your node, peer them together, and you’ll have a way to publish IPNS records without needing to require 2 running IPFS nodes, just 1 IPFS node, and a “dedicated” publishing subsystem. The code is on github

1 Like

Thanks for your reply! You confirm what I figured out about how IPNS works today. PubSub won’t change that because it only accelerates the transmission of changes in IPNS bindings to peers who have already resolved a name a first time.

Your workaround is indeed a bit hacky, but does look very useful. If I understand correctly, the basic idea is to have two nodes running on the same machine, so neither one will feel lonely. That should get rid of the “no peers found” error message. Your lightweight node is then just an optimization, right?

Yup that’s pretty much the basic idea, and it will definitely get rid of the no peers found error message. It’s an optimization yea, basically it’s just the bare-minimum components needed to do IPNS publishing (libp2p host, datastore, peerstore, keystore), as opposed to go-ipfs which has all of that, but also has a bunch of extra features that aren’t needed just for IPNS publishing.

The advantage of this is that its minutely faster to publish and republish IPNS records than go-ipfs is, but it also lets you resolve issues like the one you’re having without needing to run two complete IPFS instances.

OK, thanks for confirming my suspicion. I’ll try compiling your lightweight daemon and see if I can get it to work!

Not a problem, if you want an example of how I use it within my own products, here’s an implementation of it within my pinning service https://github.com/RTradeLtd/Temporal/blob/master/queue/ipns.go

1 Like

Thanks for answering the question for which I was just about to create another thread: are there any pinning services that also propose IPNS? I’ll check out temporal.cloud!

I have a MongoDB-backed WebApp that is kind of a mix between Social Media, Wiki, CMS, etc. It’s a tree-like DB. My vision (IPFS is not yet fully integrated), is to have the MongoDB be the “cache” where information pulled from IPFS web is stored. I am soon planning to write a whitepaper on what I want my technology to be but you can find it at: SubNode.org. Just hoping it might help you or influence you, and if you’re interested in being a member in the testing/prelaunch of the site contact me at the github page.

https://temporal.cloud is a pinning service that supports it :smile: AFAIK there’s not many that do, mostly because IPNS can be pretty slow at times.

I set up my user account on temporal.cloud and started pinning an publishing. Works fine, the interface is overall clear. Except for the “TTL” parameter for publishing, but then the IPFS documentation isn’t that much more explicit about it either.

What surprises me with IPNS is the obsession with limited lifetimes. What I’d expect as the default behavior when publishing a hash is that it remains valid until the name is redefined. But both the IPFS API and the Web app at temporal.cloud make it seem as if shorter lifetimes are generally desirable. Given that it can take half a day for a new entry to be visible elsewhere, why would I want to set a lifetime of only one day?

Magik6k has a response to a question I asked here and has a pretty good summary of what TTL is used for.

Thanks, that makes sense. I higher TTL value should then improve access times to a key whose contents don’t change often.