Skip to main content

Improved rate limiting and stateless light clients in The Waku Network

7 min read

TLDR: We have just shipped two important features to The Waku Network that offer more granularity for RLN rate-limiting and add support for stateless light clients.

Introduction to The Waku Network

Waku launched The Waku Network last December 2023. A first-of-its-kind decentralized network focused on privacy and censorship resistance, running an opinionated instance of the Waku protocol with the following features:

  • Generalized messaging network, that allows point-to-point or broadcast communications, preserving the identity of the sender, not linking its messages to any identity or IP address.
  • A decentralized and permissionless network acting as a common infrastructure, not controlled by a single actor and open to anyone, both users and operators.
  • Rate-limited to ensure a fair usage of resources. It uses RLN (Rate Limiting Nullifiers) that leverage zero-knowledge cryptography to guarantee users adhere to a rate limit without compromising their privacy. Anyone can register in the smart contract, currently deployed in Sepolia testnet, by paying a small fee.
  • Support for light clients, defined as resource-restricted devices that interact with the protocol without participating in message routing.
  • Incentivized, both non-economic (reputation mechanism already implemented) and economic (crypto incentives currently under research).

Over the last months, we detected a few limitations introduced by the usage of RLN for rate limiting, and we have been working hard to address them. As a result, we are proud to announce that the following new features are live in The Waku Network:

We are excited to announce that last 3rd of July 2024, we introduced the following features, part of release v0.30.1.

  • Better rate-limiting: The previous rate-limiting mechanism (RLN-V1) only allowed to rate limit 1 message every y seconds. This wasn't practical and it's why we have just shipped RLN-V2, which allows nodes to rate limit x messages every y seconds.
  • Stateless light clients: The main problem light clients had, was that they needed to sync and keep track of the Merkle tree that stored all memberships. This was slow and required both bandwidth and resources, a no-go for resource-restricted devices. After some changes in the smart contract, we now store the whole Merkle tree on it, which allows light clients to be stateless. The smart contract now provides all the required information. No need to sync. No need to keep state.

Better rate-limiting

One of the main limitations of the previous rate-limiting mechanism (aka RLN-V1), was that it only allowed to rate limit 1 message every y seconds. This wasn’t practical since a low value would allow too many messages, and a high one would make the network unusable in practice.

Over the last months, we have been working hard in integrating RLN-V2, which allows nodes to rate limit x messages every y seconds. This gives us extra granularity, making it more usable in practice.

The rate-limit was 1 message per second. Now with RLN-V2 The Waku Network allows more granularity, initially set to 100 messages every 10 minutes for each member. There are plans to extend this to different β€œtiers” where each limit will have a different cost.

But how does it work? There are two main components:

  • πŸ—οΈ+πŸ”‘: The RLN membership, which is made of a public (πŸ”‘) and private key (πŸ—οΈ), whose holder can use to β€œsign” messages valid in the network. Anyone can register one in the smart contract.
  • πŸ“§: The RLN proof and nullifier. It allows anyone to verify that a message is valid according to the rules. The nullifier acts as a stamp that is attached to each message and allows nodes to rate-limit the sender, while being privacy-preserving.


Each membership (πŸ—οΈ+πŸ”‘) is virtually given 100 stamps (πŸ“§) every 10 minutes to spend on credits to send messages. Every sent message consumes a stamp. Nodes in the network count them and reject messages with none or repeated ones. And nodes are incentivised via reputation to not relay messages with invalid stamps.

This protects The Waku Network against Denial of Service attacks while preserving the privacy of the sender, since it doesn’t reveal its membership, IP address or any other information to anyone.

The pricing mechanism is yet to be set. By now a user wanting to register a membership just has to pay just the transaction fees. There are plans to extend this to different β€œtiers” where each message limit will have a different cost. Note that the time window y, also called epoch size, is a network parameter common to all nodes that can't be configured individually.

Stateless light clients

We define light-clients as the nodes that interact with The Waku Network to send or receive messages but don’t participate in routing nor offer other capabilities such as storing historical messages. In other words, they are nodes running in resource-restricted devices interacting with the network but not contributing to it. Think of a client running on a phone or browser.

In order to send a message, the light client must attach a proof/stamp (πŸ“§) to the message (πŸ’¬) as explained before. This stamp is in reality an RLN zero-knowledge proof to prove that its valid and respects the rate-limit.

Up until now, there was a lot of friction for light clients, since in order to get the stamp (πŸ“§), they required the whole Merkle tree storing all memberships. Synchronizing this tree consumed resources: bandwidth, storage, and computation, which was a no-go for light clients.

However, we are proud to announce that now the Merkle tree is stored onchain. This removes the need for light clients to sync the tree. The contract provides all the required information. No need to sync. No need to keep state anymore.

The RLN membership Merkle tree is now stored in the smart contract, which allows light clients to be stateless. No need synchronize the Merkle Tree. The contract provides all required information via merkleProofElements() (to generate proofs) and root() (to verify them).

Let's see an example. A membership is represented by two keys:

  • πŸ”‘: A public one, stored as a leaf in a Merkle tree
  • πŸ—οΈ: A private one, that gives the right of the holder to publish valid messages.

Now the smart contract provides both:

  • 🫚: Merkle root of the tree containing all memberships πŸ”‘, accesible by root()
  • 🌲: Merkle proof of a given membership πŸ”‘, accesible by merkleProofElements(leaf)

Since root (🫚) and proofs (🌲) are now publicly available in the smart contract, light clients don’t have to calculate these themselves. These allows seamless proof generation (for publishers) and verification (for subscribers):

  • πŸ—οΈ+🌲 = πŸ“§Β Using its private key (πŸ—οΈ) and the leaf Merkle proof (🌲) a publisher can generate the stamp (πŸ“§) that is attached to the message (πŸ’¬).
  • 🫚+πŸ“§Β = βœ…/❌ The Merkle root (🫚) and the included stamp (πŸ“§) of the message (πŸ’¬), can be used by the subscriber to verify if the message is legit to accept (βœ…) or reject (❌) it.


Note that both merkleProofElements(leaf) and root() are free to call. They are view functions that don’t modify any state. Moreover, they don’t consume much resources and should work in any RPC provider.

Note also that they are lazily evaluated, meaning that they are calculated on each call based on some intermediate stored leafs. This allows to save lots of gas. Insertions are expected to cost between 100k and 200k gas, hitting rarely more than that in 2^n leafs.

The contract is currently deployed in Ethereum Sepolia testnet, but its expected to move to a Layer 2 where gas would be even cheaper.

Join The Waku Network​

Both of these features are live in The Waku Network, so if you want to test them out, join The Waku Network by using nwaku-compose. As simple as cleaning up your previous configuration and running two commands.