<titledata-rh="true">Content Topics | Waku Documentation</title><metadata-rh="true"name="viewport"content="width=device-width,initial-scale=1"><metadata-rh="true"name="twitter:card"content="summary_large_image"><metadata-rh="true"property="og:url"content="https://docs.waku.org/learn/concepts/content-topics"><metadata-rh="true"property="og:locale"content="en_GB"><metadata-rh="true"name="docusaurus_locale"content="en-GB"><metadata-rh="true"name="docsearch:language"content="en-GB"><metadata-rh="true"name="keywords"content="waku, web3"><metadata-rh="true"name="image"content="https://docs.waku.org/_og/0bb7639ac9531adb6ff7ae58ff7aea3697efbc9e.png"><metadata-rh="true"name="docusaurus_version"content="current"><metadata-rh="true"name="docusaurus_tag"content="docs-default-current"><metadata-rh="true"name="docsearch:version"content="current"><metadata-rh="true"name="docsearch:docusaurus_tag"content="docs-default-current"><metadata-rh="true"property="og:title"content="Content Topics | Waku Documentation"><metadata-rh="true"name="description"content="Content Topics are metadata strings set by developers on outgoing messages to facilitate protocol-level features like selectively processing incoming messages (Relay or Filter) and retrieving historical messages (Store) that meet specific filtering criteria. Have a look at the WAKU2-TOPICS specification to learn more."><metadata-rh="true"property="og:description"content="Content Topics are metadata strings set by developers on outgoing messages to facilitate protocol-level features like selectively processing incoming messages (Relay or Filter) and retrieving historical messages (Store) that meet specific filtering criteria. Have a look at the WAKU2-TOPICS specification to learn more."><linkdata-rh="true"rel="icon"href="/theme/image/favicon.ico"><linkdata-rh="true"rel="canonical"href="https://docs.waku.org/learn/concepts/content-topics"><linkdata-rh="true"rel="alternate"href="https://docs.waku.org/learn/concepts/content-topics"hreflang="en-GB"><linkdata-rh="true"rel="alternate"href="https://docs.waku.org/learn/concepts/content-topics"hreflang="x-default"><linkrel="alternate icon"type="image/png"href="/theme/image/favicon.png">
<h2class="anchor anchorWithHideOnScrollNavbar_WYt5"id="naming-format">Naming format<ahref="#naming-format"class="hash-link"aria-label="Direct link to Naming format"title="Direct link to Naming format"></a></h2>
<p>Here is the recommended format for content topics:</p>
<li><code>application-name</code>: This is the unique name of your decentralised application (DApp) to prevent conflicts with other DApps.</li>
<li><code>version</code>: Typically starting at <code>1</code>, this field helps track breaking changes in your messages.</li>
<li><code>content-topic-name</code>: The specific name of the content topic used for filtering.</li>
<li><code>encoding</code>: The message encoding or serialisation format, with <ahref="https://protobuf.dev/"target="_blank"rel="noopener noreferrer">Protocol Buffers</a> (<code>proto</code>) being the recommended choice.</li>
</ul>
<p>For example, if your DApp is called <code>SuperCrypto</code> and it allows users to receive notifications and send private messages, you can consider using the following content topics:</p>
<divclass="theme-admonition theme-admonition-tip alert--success admonition_ntHH"><spanclass="admonitionIcon_BGV6"><svgwidth="16"height="16"viewBox="0 0 16 16"xmlns="http://www.w3.org/2000/svg"><pathd="M8 14.6666C7.63333 14.6666 7.31933 14.536 7.058 14.2746C6.79667 14.0133 6.66622 13.6995 6.66667 13.3333H9.33333C9.33333 13.7 9.20267 14.014 8.94133 14.2753C8.68 14.5366 8.36622 14.6671 8 14.6666ZM5.33333 12.6666V11.3333H10.6667V12.6666H5.33333ZM5.5 10.6666C4.73333 10.2111 4.12489 9.59998 3.67467 8.83331C3.22445 8.06665 2.99956 7.23331 3 6.33331C3 4.94442 3.48622 3.76376 4.45867 2.79131C5.43111 1.81887 6.61156 1.33287 8 1.33331C9.38889 1.33331 10.5696 1.81954 11.542 2.79198C12.5144 3.76442 13.0004 4.94487 13 6.33331C13 7.23331 12.7751 8.06665 12.3253 8.83331C11.8756 9.59998 11.2671 10.2111 10.5 10.6666H5.5ZM5.9 9.33331H10.1C10.6 8.97776 10.9862 8.53887 11.2587 8.01665C11.5311 7.49442 11.6671 6.93331 11.6667 6.33331C11.6667 5.31109 11.3111 4.44442 10.6 3.73331C9.88889 3.0222 9.02222 2.66665 8 2.66665C6.97778 2.66665 6.11111 3.0222 5.4 3.73331C4.68889 4.44442 4.33333 5.31109 4.33333 6.33331C4.33333 6.93331 4.46956 7.49442 4.742 8.01665C5.01444 8.53887 5.40045 8.97776 5.9 9.33331Z"fill="currentColor"></path></svg></span><div><spanclass="lsd-typography lsd-typography--body1 admonitionHeading_JPfy">tip</span><spanclass="lsd-typography lsd-typography--body1 admonitionContent_iozl"><p>While you can choose any encoding format for your <code>Content Topic</code>, we highly recommend using Protocol Buffers (<code>proto</code>) because of its efficiency. Choosing a lightweight format ensures optimal performance of your DApp.</p></span></div></div>
<h2class="anchor anchorWithHideOnScrollNavbar_WYt5"id="naming-considerations">Naming considerations<ahref="#naming-considerations"class="hash-link"aria-label="Direct link to Naming considerations"title="Direct link to Naming considerations"></a></h2>
<p>When choosing a content topic, it is essential to consider the privacy implications. Here are several factors to keep in mind:</p>
<h3class="anchor anchorWithHideOnScrollNavbar_WYt5"id="protocols-disclose-content-topics-to-peers">Protocols disclose content topics to peers<ahref="#protocols-disclose-content-topics-to-peers"class="hash-link"aria-label="Direct link to Protocols disclose content topics to peers"title="Direct link to Protocols disclose content topics to peers"></a></h3>
<p>The <code>Filter</code>, <code>Store</code>, and <code>Light Push</code> protocols share content topics with peers, allowing them to link IP and content topic interests. The <code>Relay</code> protocol, using <code>GossipSub</code>, provides recipient anonymity, which can be compromised if the content topic exposes user information.</p>
<p>For example, instead of using Personally Identifiable Information (PII) in the content topic (e.g., a public key), you can create buckets (e.g., based on the first 4 bytes of the public key hash).</p>
<h3class="anchor anchorWithHideOnScrollNavbar_WYt5"id="increasing-k-anonymity-preserves-user-anonymity">Increasing k-anonymity preserves user anonymity<ahref="#increasing-k-anonymity-preserves-user-anonymity"class="hash-link"aria-label="Direct link to Increasing k-anonymity preserves user anonymity"title="Direct link to Increasing k-anonymity preserves user anonymity"></a></h3>
<p>You can increase <ahref="https://www.privitar.com/blog/k-anonymity-an-introduction/"target="_blank"rel="noopener noreferrer">k-anonymity</a> within the network by using a unified content topic across the entire application or targeting specific features like notifications or private messages, allowing multiple users to share it.</p>
<p>We recommend switching functionality using the Protocol Buffer (<code>proto</code>) message format. By doing so, applications can retain a high granularity and functionality while using a single content topic, preserving user privacy. For example:</p>
<divclass="language-js codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><divclass="codeBlockContent_QJqH"><pretabindex="0"class="prism-code language-js codeBlock_bY9V thin-scrollbar"style="color:#F8F8F2;background-color:rgba(var(--lsd-surface-secondary), 0.08)"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain">message </span><spanclass="token maybe-class-name">NotificationPayload</span><spanclass="token plain"></span><spanclass="token punctuation"style="color:rgb(248, 248, 242)">{</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"></span><spanclass="token spread operator">...</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"></span><spanclass="token punctuation"style="color:rgb(248, 248, 242)">}</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain">message </span><spanclass="token maybe-class-name">FeatureAbcPayload</span><spanclass="token plain"></span><spanclass="token punctuation"style="color:rgb(248, 248, 242)">{</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"></span><spanclass="token spread operator">...</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"></span><spanclass="token punctuation"style="color:rgb(248, 248, 242)">}</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"></span><spanclass="token comment"style="color:rgb(98, 114, 164)">// By default, all fields in protobuf are optional so only field may be encoded at a time</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain">message </span><spanclass="token maybe-class-name">Payload</span><spanclass="token plain"></span><spanclass="token punctuation"style="color:rgb(248, 248, 242)">{</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"></span><spanclass="token maybe-class-name">NotificationPayload</span><spanclass="token plain"> notification </span><spanclass="token operator">=</span><spanclass="token plain"></span><spanclass="token number">1</span><spanclass="token punctuation"style="color:rgb(248, 248, 242)">;</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"></span><spanclass="token maybe-class-name">FeatureAbcPayload</span><spanclass="token plain"> feature_abc </span><spanclass="token operator">=</span><spanclass="token plain"></span><spanclass="token number">2</span><spanclass="token punctuation"style="color:rgb(248, 248, 242)">;</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#F8F8F2"><spanclass="token plain"></span><spanclass="token punctuation"style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<h3class="anchor anchorWithHideOnScrollNavbar_WYt5"id="creating-buckets-help-in-distributing-traffic">Creating buckets help in distributing traffic<ahref="#creating-buckets-help-in-distributing-traffic"class="hash-link"aria-label="Direct link to Creating buckets help in distributing traffic"title="Direct link to Creating buckets help in distributing traffic"></a></h3>
<p>When an application uses a single content topic, all users using <ahref="/learn/concepts/network-domains#requestresponse-domain">request/response protocols</a> (<code>Filter</code>, <code>Store</code>) receive all its messages. For heavy traffic, developers can create buckets by hashing a unique identifier (e.g., recipient's ID, public key, or app domain topic) and adding its first byte to the content topic, like <code>/my-app/0/a/proto</code>.</p>
<p>This approach divides traffic into multiple topics, reducing the messages users have to download. Developers can add more first bytes to the content topic over time to improve efficiency and privacy based on messages and user needs.</p>