Using Waku Relay’s Store‑and‑Forward to Retrieve Missed Messages
Learn how to configure a Waku Relay’s store‑and‑forward feature so light clients can query recent messages after going offline, with a step‑by‑step example and notes on trade‑offs.
06 Oct 2026, 21:47 UTC

Problem: Light clients lose messages when they go offline
In a decentralized chat or sensor network built on Waku, a light‑weight client may disconnect for a few minutes or hours. When it reconnects, it needs to catch up on any messages that were published while it was away. Without a persistent archive, the client would miss those updates unless it can ask a peer that still holds them.
Thesis: The Waku Relay’s store capability gives light clients a simple, on‑demand way to query recent messages without running a full node
By enabling the store flag on a Waku Relay, operators create a rolling buffer of recent envelopes indexed by content topic and timestamp. Light clients connect to one or more of these relays, send a StoreQuery specifying a time range and topic filter, and receive matching envelopes over an encrypted Noise XK channel. The feature works over both libp2p and WebSocket transports, making it usable in browsers and native apps.
How the store works in practice
The relay maintains a circular buffer (default ~2 GB, roughly 12 hours of traffic at typical load). Each incoming envelope is gossiped to peers that have advertised the same content topic, so any relay that has seen the message can serve it later. When a light client issues a StoreQuery, the relay scans its buffer for envelopes whose timestamp falls inside the requested range and whose topic hash matches the filter, then returns the matching envelopes in the same WakuMessage format used for live gossip.
Because the buffer is configurable, operators can trade storage cost for retrieval depth. A smaller buffer reduces disk usage but shortens the historic window; a larger buffer increases latency slightly as the relay must scan more data.
Worked example: Setting up a local relay and testing a store query
- Run a relay with store enabled
On a machine with libp2p and Wakunode v0.20.0 or later installed, start a relay that limits its store size to 200 MB (enough for a few minutes of test traffic). You need read/write access to the directory where the buffer will be stored.
wakunode \ --listen-address /ip4/0.0.0.0/tcp/30303 \ --ws-address /ip4/0.0.0.0/tcp/8080 \ --store-enabled \ --store-size 200MB \ --log-level infoRun this command in a terminal; the process must have permission to create files in the current working directory.
- Start two light‑client peers using the JavaScript SDK
In separate Node.js processes (or browser consoles), instantiate a
Wakuobject that connects to the relay’s WebSocket endpoint. No special privileges are required beyond network access tows://localhost:8080/waku/ws.import { Waku } from '@waku/sdk' const wakua = await Waku.create({ libp2p: { addresses: ['/ip4/127.0.0.1/tcp/8080/ws'] } }) const wakub = await Waku.create({ libp2p: { addresses: ['/ip4/127.0.0.1/tcp/8080/ws'] } }) - Publish a message from Peer A
Choose a content topic, for example
my-app/chat. Peer A publishes a short envelope.await wakua.publish({ payload: new TextEncoder().encode('hello store'), contentTopic: 'my-app/chat' })Wait a moment (e.g., 2 seconds) to allow the relay to gossip and store the envelope.
- Shut down Peer A and query from Peer B
Close Peer A’s connection (or stop the process). Peer B, now offline during the publish, issues a store request for the last minute.
const query = { contentTopic: 'my-app/chat', startTime: Date.now() - 60_000, // one minute ago endTime: Date.now() } const envelopes = await wakub.store.query(query) console.log('Received', envelopes.length, 'envelopes')Check that
envelopes.lengthis at least one and that the payload decodes to the original string. Inspect the relay’s console for lines indicating a store handshake (e.g., messages containing "store" and "query") to confirm the request was processed.
Trade‑offs and limitations
- Non‑durable buffer: When the circular buffer rolls over, older messages are permanently lost unless the operator enables external persistence (e.g., mounting a volume or configuring a backend store).
- Query latency: Larger buffers increase the time needed to scan for matches, especially under heavy network load. Operators should monitor latency and adjust
--store-sizeaccordingly. - Malicious or misbehaving relays: A relay can refuse to answer a store query or drop specific topics. Applications should therefore connect to multiple relays, implement retry logic, and treat missing data as a signal to fall back to other discovery mechanisms.
Actionable closing
If your Waku‑based application needs reliable offline retrieval, start by enabling the store capability on a modest‑sized relay, test the round‑trip flow shown above, and observe latency and storage usage in your staging environment. Adjust --store-size based on the historic window you require, and always run at least two relays for redundancy. This approach gives light clients a practical way to catch up on missed messages without the overhead of running a full archive node.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.