<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>
<divclass="theme-admonition theme-admonition-info alert--info admonition_ntHH"><spanclass="admonitionIcon_BGV6"><svgwidth="16"height="16"viewBox="0 0 16 16"fill="none"xmlns="http://www.w3.org/2000/svg"><pathd="M7.33334 11.3333H8.66668V7.33331H7.33334V11.3333ZM8.00001 5.99998C8.1889 5.99998 8.34734 5.93598 8.47534 5.80798C8.60334 5.67998 8.66712 5.52176 8.66668 5.33331C8.66668 5.14442 8.60268 4.98598 8.47468 4.85798C8.34668 4.72998 8.18845 4.6662 8.00001 4.66665C7.81112 4.66665 7.65268 4.73065 7.52468 4.85865C7.39668 4.98665 7.3329 5.14487 7.33334 5.33331C7.33334 5.5222 7.39734 5.68065 7.52534 5.80865C7.65334 5.93665 7.81157 6.00042 8.00001 5.99998ZM8.00001 14.6666C7.07779 14.6666 6.21112 14.4915 5.40001 14.1413C4.5889 13.7911 3.88334 13.3162 3.28334 12.7166C2.68334 12.1166 2.20845 11.4111 1.85868 10.6C1.5089 9.78887 1.33379 8.9222 1.33334 7.99998C1.33334 7.07776 1.50845 6.21109 1.85868 5.39998C2.2089 4.58887 2.68379 3.88331 3.28334 3.28331C3.88334 2.68331 4.5889 2.20842 5.40001 1.85865C6.21112 1.50887 7.07779 1.33376 8.00001 1.33331C8.92223 1.33331 9.7889 1.50842 10.6 1.85865C11.4111 2.20887 12.1167 2.68376 12.7167 3.28331C13.3167 3.88331 13.7918 4.58887 14.142 5.39998C14.4922 6.21109 14.6671 7.07776 14.6667 7.99998C14.6667 8.9222 14.4916 9.78887 14.1413 10.6C13.7911 11.4111 13.3162 12.1166 12.7167 12.7166C12.1167 13.3166 11.4111 13.7918 10.6 14.142C9.7889 14.4922 8.92223 14.6671 8.00001 14.6666ZM8.00001 13.3333C9.4889 13.3333 10.75 12.8166 11.7833 11.7833C12.8167 10.75 13.3333 9.48887 13.3333 7.99998C13.3333 6.51109 12.8167 5.24998 11.7833 4.21665C10.75 3.18331 9.4889 2.66665 8.00001 2.66665C6.51112 2.66665 5.25001 3.18331 4.21668 4.21665C3.18334 5.24998 2.66668 6.51109 2.66668 7.99998C2.66668 9.48887 3.18334 10.75 4.21668 11.7833C5.25001 12.8166 6.51112 13.3333 8.00001 13.3333Z"fill="currentColor"></path></svg></span><div><spanclass="lsd-typography lsd-typography--body1 admonitionHeading_JPfy">info</span><spanclass="lsd-typography lsd-typography--body1 admonitionContent_iozl"><p>The <strong>k</strong> value of <strong>k-anonymity</strong> equals the number of IDs for which the first character of the hash is <code>"a"</code>. For example, using a single content topic in an application with 10,000 users results in <strong>k = 10,000</strong>. However, using the hash ID's first character, <strong>k</strong> reduces to <strong>10,000 / 16 = 625</strong>.</p></span></div></div></div><footerclass="theme-doc-footer docusaurus-mt-lg"><divclass="row margin-top--sm theme-doc-footer-edit-meta-row"><divclass="col"><ahref="https://github.com/waku-org/docs.waku.org/tree/develop/docs/learn/concepts/content-topics.md"target="_blank"rel="noreferrer noopener"class="theme-edit-this-page"><divclass="icon_S7Kx m_thRi"><svgxmlns="http://www.w3.org/2000/svg"width="16"height="16"fill="none"viewBox="0 0 16 16"><pathfill="#fff"fill-rule="evenodd"d="m12.707 2.393.9.9c.526.52.526 1.367 0 1.887L4.787 14H2v-2.787l6.933-6.94 1.887-1.88c.52-.52 1.367-.52 1.887 0M3.333 12.667l.94.04 6.547-6.554-.94-.94-6.547 6.547z"clip-rule="evenodd"></path></svg></div><spanclass="lsd-typography lsd-typography--body2">Edit this page</span></a></div><divclass="col lastUpdated_JAkA"></div></div></footer></article><navclass="docusaurus-mt-lg pagination-nav"aria-label="Docs pages"><aclass="pagination-nav__link pagination-nav__link--prev"href="/learn/concepts/protocols"><divclass="icon_S7Kx m_thRi"><svgxmlns="http://www.w3.org/2000/svg"width="14"height="14"fill="none"viewBox="0 0 14 14"><pathfill="#fff"d="M11.667 6.417h-7.1L7.83 3.156 7 2.333 2.334 7 7 11.667l.823-.823-3.255-3.26h7.099z"></path></svg></div><spanclass="lsd-typography lsd-typography--body2 pagination-nav__label">Protocols</span></a><aclass="pagination-nav__link pagination-nav__link--next"href="/learn/concepts/network-domains"><spanclass="lsd-typography lsd-typography--body2 pagination-nav__label">Network Domains</span><divclass="icon_S7Kx m_thRi"><svgxmlns="http://www.w3.org/2000/svg"width="14"height="14"fill="none"viewBox="0 0 14 14"><path