nostr:npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft brought up in this interview that one of the big problems with Nostr he acknowledges is the fact it is very data intensive which translates to cost on mobile networks.

I'm trying to get him interested in adding something to the base protocol that could drastically reduce the amount of network chatter between relays and clients, reducing cost, time and energy. I'm not a developer though so I don't know how to do this through the proper channels, please talk to me if you want to take it forward.

Reply to this note

Please Login to reply.

Discussion

The proxy Pablo made is a good solution. Not everyone will run their own node but it could be offered as a temporary service for those travelling with data restrictions. Although, battery consumption is also a reason to optimise.

Proxies belong tight with Fedi instances; it’s the same threat model.

Hi. Thanks for sending me that proposal. The way nostr works, that proposal wouldn’t make much difference; the vast amount of data consumption comes from downloading the same events over and over from multiplier relays.

While there are a lot of low-hanging fruit optimizations left in client development (all stuff I have in #[4]​ ‘s roadmap) there are even more harder optimizations with significant impact to be done here.

Nostr is still very early and the optimizations have yet broadly not been explored.

And yeah, like it’s been said on this thread, in the interim, a proxy approach like I did while I was in Thailand turns the nostr usage to exactly the same model as a Twitter where it’s as efficient as possible (no data duplicates, no local signature verification). The proxy work still needs to be formalized as I never got to write that NIP.

OK 👍 Thanks for reading it anyway!

re.: downloading the same events from multiple relays, this is pretty much the same issue as the one I was describing.

In NIP-01 there is specified a REQ message that contains a JSON object. This object specifies #e, #p, since and until. since and until are great, because since means the opposite of until. But there is no opposite of #e and #p. What is needed are properties that mean:

not-#e: do not give me any of the listed event ids

not-#p: do not give me any events that contain the listed pubkeys

Then the client notes, for each relay it connects to, when it last issued a REQ message, call that t. Any subsequent REQ it sends to that relay will have since:t .

Next, the client will go through its list of relays one at a time, not all at the same time. In order to prevent a situation where any one relay could perform a denial of service on the client, the client can specify a minimum time for relays to respond in and remove relays from the list or put them at the end if they respond too slowly.

The first REQ will have an empty not-#e list. Then for subsequent REQs on later relays in the list, all the event ids retrieved from previous REQs are added to the not-#e list. This ensures that duplicate events are not retrieved from different relays.

In addition we can specify a not-#p on all the REQs containing the pubkeys that the user has specified they are not interested in (blocked, etc). This does the optimization I talked about before.

Once the client has performed this batch of REQs it updates the times t for each relay, so future REQ batches will contain the new since value.

This should ensure that, for requested events:

1. the client only gets newer events

2. the client does not get duplicate events

3. the client does not get events they know they won't be interested in and have to discard

I don't know if new properties can be added to the object and be compliant with the specification NIP-01. If not then a new message type would have to be added that replaces REQ, e.g. "REQ2", in a new NIP, to add the new filter properties.

Next we have the problem of asynchronous events (events issued by the relay after the EOSE message).

During REQ processing, it might be necessary to inform a relay that no new asynchronous events should be sent until the client specifically requests that it is ready for asynchronous events. Otherwise we might still get a duplicate event while the client is processing results from other relays later in the list.

Then we have to specify a new message type sent from the client to the relay, let's call this SEEN. When the client receives an asynchronous event from any relay it is connected to, it immediately sends a SEEN message to all the other relays it is connected to with the event id. That way the other relays know not to send asynchronous events with that id. There may still be a small amount of duplication due to time windows in processing, but it should reduce duplication by a large amount.

What do you think?