Files
SpacetimeDB/docs/build/subscriptions/semantics/index.html
T
Julien Lavocat c20c30524b Remove old docs
2025-10-21 12:12:01 +02:00

132 lines
24 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-Subscriptions/Subscription-Semantics" data-has-hydrated="false">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v3.9.1">
<title data-rh="true">Subscription Semantics | SpacetimeDB docs</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://docs.spacetimedb.com/subscriptions/semantics"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Subscription Semantics | SpacetimeDB docs"><meta data-rh="true" name="description" content="This document describes the subscription semantics maintained by the SpacetimeDB host over WebSocket connections. These semantics outline message ordering guarantees, subscription handling, transaction updates, and client cache consistency."><meta data-rh="true" property="og:description" content="This document describes the subscription semantics maintained by the SpacetimeDB host over WebSocket connections. These semantics outline message ordering guarantees, subscription handling, transaction updates, and client cache consistency."><link data-rh="true" rel="icon" href="/images/favicon.ico"><link data-rh="true" rel="canonical" href="https://docs.spacetimedb.com/subscriptions/semantics"><link data-rh="true" rel="alternate" href="https://docs.spacetimedb.com/subscriptions/semantics" hreflang="en"><link data-rh="true" rel="alternate" href="https://docs.spacetimedb.com/subscriptions/semantics" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://QBC7Z9KXS2-dsn.algolia.net" crossorigin="anonymous"><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Subscription Semantics","item":"https://docs.spacetimedb.com/subscriptions/semantics"}]}</script><link rel="search" type="application/opensearchdescription+xml" title="SpacetimeDB docs" href="/opensearch.xml"><link rel="stylesheet" href="/assets/css/styles.0cb9f7a7.css">
<script src="/assets/js/runtime~main.d71df0f5.js" defer="defer"></script>
<script src="/assets/js/main.31d95d83.js" defer="defer"></script>
</head>
<body class="navigation-with-keyboard">
<svg style="display: none;"><defs>
<symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol>
</defs></svg>
<script>document.documentElement.setAttribute("data-theme","light"),document.documentElement.setAttribute("data-theme-choice","light"),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><link rel="preload" as="image" href="https://spacetimedb.com/images/brand.png"><div role="region" aria-label="Skip to main content"><a class="skipToContent_6jFv" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="https://spacetimedb.com/images/brand.png" alt="SpacetimeDB Logo" class="themedComponent_rvet themedComponent--light_mbAJ"><img src="https://spacetimedb.com/images/brand.png" alt="SpacetimeDB Logo" class="themedComponent_rvet themedComponent--dark_Ncy6"></div></a><div class="navbarSearchContainer_AesG"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search (Command+K)"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href="https://spacetimedb.com/install" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Install</a><a href="https://spacetimedb.com/pricing" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Pricing</a><a href="https://spacetimedb.com/maincloud" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Maincloud</a><a href="https://spacetimedb.com/blog" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Blog</a><a href="https://spacetimedb.com/community" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Community</a></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_hV_y"><div class="docsWrapper_f07g"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_MJiz" type="button"></button><div class="docRoot_Gd2s"><aside class="theme-doc-sidebar-container docSidebarContainer_fSpF"><div class="sidebarViewport_YElg"><div class="sidebar_kjg4"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_AG0n"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/"><span title="Intro" class="categoryLinkLabel_EDYQ">Intro</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/deploying/maincloud"><span title="Deploying" class="categoryLinkLabel_EDYQ">Deploying</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/unity"><span title="Unity tutorial" class="categoryLinkLabel_EDYQ">Unity tutorial</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/unreal"><span title="Unreal Tutorial" class="categoryLinkLabel_EDYQ">Unreal Tutorial</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/cli-reference"><span title="CLI Reference" class="categoryLinkLabel_EDYQ">CLI Reference</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/modules"><span title="Server Module Languages" class="categoryLinkLabel_EDYQ">Server Module Languages</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/sdks"><span title="Client SDK Languages" class="categoryLinkLabel_EDYQ">Client SDK Languages</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/sql"><span title="SQL" class="categoryLinkLabel_EDYQ">SQL</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" role="button" aria-expanded="true" href="/subscriptions"><span title="Subscriptions" class="categoryLinkLabel_EDYQ">Subscriptions</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/subscriptions"><span title="Subscription Reference" class="linkLabel_dpMB">Subscription Reference</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/subscriptions/semantics"><span title="Subscription Semantics" class="linkLabel_dpMB">Subscription Semantics</span></a></li></ul></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/rls"><span title="Row Level Security" class="linkLabel_dpMB">Row Level Security</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/how-to/incremental-migrations"><span title="How-To" class="categoryLinkLabel_EDYQ">How-To</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/spacetimeauth"><span title="SpacetimeAuth" class="categoryLinkLabel_EDYQ">SpacetimeAuth</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/http/authorization"><span title="HTTP API" class="categoryLinkLabel_EDYQ">HTTP API</span></a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_ggI5 menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/webassembly-abi"><span title="Internals" class="categoryLinkLabel_EDYQ">Internals</span></a></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/appendix"><span title="Appendix" class="linkLabel_dpMB">Appendix</span></a></li></ul></nav></div></div></aside><main class="docMainContainer_dkUT"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_w2oE"><div class="docItemContainer_f71m"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_xsLZ" aria-label="Breadcrumbs"><ul class="breadcrumbs"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_oyay"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><span class="breadcrumbs__link">Subscriptions</span></li><li class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link">Subscription Semantics</span></li></ul></nav><div class="tocCollapsible_dqme theme-doc-toc-mobile tocMobile_Z34P"><button type="button" class="clean-btn tocCollapsibleButton_QMSE">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>SpacetimeDB Subscription Semantics</h1></header>
<p>This document describes the subscription semantics maintained by the SpacetimeDB host over WebSocket connections. These semantics outline message ordering guarantees, subscription handling, transaction updates, and client cache consistency.</p>
<h2 class="anchor anchorWithStickyNavbar_wKCU" id="websocket-communication-channels">WebSocket Communication Channels<a href="#websocket-communication-channels" class="hash-link" aria-label="Direct link to WebSocket Communication Channels" title="Direct link to WebSocket Communication Channels" translate="no"></a></h2>
<p>A single WebSocket connection between a client and the SpacetimeDB host consists of two distinct message channels:</p>
<ul>
<li><strong>Client → Server:</strong> Sends requests such as reducer invocations and subscription queries.</li>
<li><strong>Server → Client:</strong> Sends responses to client requests and database transaction updates.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_wKCU" id="ordering-guarantees">Ordering Guarantees<a href="#ordering-guarantees" class="hash-link" aria-label="Direct link to Ordering Guarantees" title="Direct link to Ordering Guarantees" translate="no"></a></h3>
<p>The server maintains the following guarantees:</p>
<ol>
<li>
<p><strong>Sequential Response Ordering:</strong></p>
<ul>
<li>Responses to client requests are always sent back in the same order the requests were received. If request A precedes request B, the response to A will always precede the response to B, even if A takes longer to process.</li>
</ul>
</li>
<li>
<p><strong>Atomic Transaction Updates:</strong></p>
<ul>
<li>Each database transaction (e.g., reducer invocation, INSERT, UPDATE, DELETE queries) generates exactly zero or one update message sent to clients. These updates are atomic and reflect the exact order of committed transactions.</li>
</ul>
</li>
<li>
<p><strong>Atomic Subscription Initialization:</strong></p>
<ul>
<li>When subscriptions are established, clients receive exactly one response containing all initially matching rows from a consistent database state snapshot taken between two transactions.</li>
<li>The state snapshot reflects a committed database state that includes all previous transaction updates received and excludes all future transaction updates.</li>
</ul>
</li>
</ol>
<h2 class="anchor anchorWithStickyNavbar_wKCU" id="subscription-workflow">Subscription Workflow<a href="#subscription-workflow" class="hash-link" aria-label="Direct link to Subscription Workflow" title="Direct link to Subscription Workflow" translate="no"></a></h2>
<p>When invoking <code>SubscriptionBuilder::subscribe(QUERIES)</code> from the client SDK:</p>
<ol>
<li>
<p><strong>Client SDK → Host:</strong></p>
<ul>
<li>Sends a <code>Subscribe</code> message containing the specified QUERIES.</li>
</ul>
</li>
<li>
<p><strong>Host Processing:</strong></p>
<ul>
<li>Captures a snapshot of the committed database state.</li>
<li>Evaluates the QUERIES against this snapshot to determine matching rows.</li>
</ul>
</li>
<li>
<p><strong>Host → Client SDK:</strong></p>
<ul>
<li>Sends a <code>SubscribeApplied</code> message containing the matching rows.</li>
</ul>
</li>
<li>
<p><strong>Client SDK Processing:</strong></p>
<ul>
<li>Receives and processes the message.</li>
<li>Locks the client cache and inserts all rows atomically.</li>
<li>Invokes relevant callbacks:<!-- -->
<ul>
<li><code>on_insert</code> callback for each row.</li>
<li><code>on_applied</code> callback for the subscription.<!-- -->
<div class="theme-admonition theme-admonition-note admonition_scYj alert alert--secondary"><div class="admonitionHeading_zhQc"><span class="admonitionIcon_kfZz"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_O7JJ"><p>No relative ordering guarantees are made regarding the invocation order of these callbacks.</p></div></div>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<h2 class="anchor anchorWithStickyNavbar_wKCU" id="transaction-update-workflow">Transaction Update Workflow<a href="#transaction-update-workflow" class="hash-link" aria-label="Direct link to Transaction Update Workflow" title="Direct link to Transaction Update Workflow" translate="no"></a></h2>
<p>Upon committing a database transaction:</p>
<ol>
<li>
<p><strong>Transaction Results in a State Delta:</strong></p>
<ul>
<li>The result of a transaction is a state delta, i.e. an unordered set of inserted and deleted rows.</li>
</ul>
</li>
<li>
<p><strong>Host Evaluates Queries:</strong></p>
<ul>
<li>Evaluates the QUERIES against the state delta to determine matching altered rows.</li>
</ul>
</li>
<li>
<p><strong>Host → Client SDK:</strong></p>
<ul>
<li>Sends a <code>TransactionUpdate</code> message if relevant updates exist, containing affected rows and transaction metadata.</li>
</ul>
</li>
<li>
<p><strong>Client SDK Processing:</strong></p>
<ul>
<li>Receives and processes the message.</li>
<li>Locks the client cache, applying deletions and insertions atomically.</li>
<li>Invokes relevant callbacks:<!-- -->
<ul>
<li><code>on_insert</code>, <code>on_delete</code>, <code>on_update</code> callbacks for modified rows.</li>
<li>Reducer callbacks, if the transaction was the result of a reducer.<!-- -->
<div class="theme-admonition theme-admonition-note admonition_scYj alert alert--secondary"><div class="admonitionHeading_zhQc"><span class="admonitionIcon_kfZz"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_O7JJ"><p>No relative ordering guarantees are made regarding the invocation order of these callbacks.</p></div></div>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<h2 class="anchor anchorWithStickyNavbar_wKCU" id="multiple-subscription-sets">Multiple Subscription Sets<a href="#multiple-subscription-sets" class="hash-link" aria-label="Direct link to Multiple Subscription Sets" title="Direct link to Multiple Subscription Sets" translate="no"></a></h2>
<p>If multiple subscription sets are active, updates across these sets are bundled together into a single <code>TransactionUpdate</code> message.</p>
<h2 class="anchor anchorWithStickyNavbar_wKCU" id="client-cache-guarantees">Client Cache Guarantees<a href="#client-cache-guarantees" class="hash-link" aria-label="Direct link to Client Cache Guarantees" title="Direct link to Client Cache Guarantees" translate="no"></a></h2>
<ul>
<li>The client cache always maintains a consistent and correct subset of the committed database state.</li>
<li>Callback functions invoked due to events have guaranteed visibility into a fully updated cache state.</li>
<li>Reads from the client cache are effectively free as they access locally cached data.</li>
<li>During callback execution, the client cache accurately reflects the database state immediately following the event-triggering transaction.</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_wKCU" id="pending-callbacks-and-cache-consistency">Pending Callbacks and Cache Consistency<a href="#pending-callbacks-and-cache-consistency" class="hash-link" aria-label="Direct link to Pending Callbacks and Cache Consistency" title="Direct link to Pending Callbacks and Cache Consistency" translate="no"></a></h3>
<p>While processing a <code>TransactionUpdate</code> message, callbacks are queued within the SDK and deferred until the cache updates (inserts/deletes) from a transaction are fully applied. This ensures all callbacks see the fully consistent state of the cache, preventing callbacks from observing an inconsistent intermediate state.</p></div></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/subscriptions"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">Subscription Reference</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/rls"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Row Level Security</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_Ea_L thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#websocket-communication-channels" class="table-of-contents__link toc-highlight">WebSocket Communication Channels</a><ul><li><a href="#ordering-guarantees" class="table-of-contents__link toc-highlight">Ordering Guarantees</a></li></ul></li><li><a href="#subscription-workflow" class="table-of-contents__link toc-highlight">Subscription Workflow</a></li><li><a href="#transaction-update-workflow" class="table-of-contents__link toc-highlight">Transaction Update Workflow</a></li><li><a href="#multiple-subscription-sets" class="table-of-contents__link toc-highlight">Multiple Subscription Sets</a></li><li><a href="#client-cache-guarantees" class="table-of-contents__link toc-highlight">Client Cache Guarantees</a><ul><li><a href="#pending-callbacks-and-cache-consistency" class="table-of-contents__link toc-highlight">Pending Callbacks and Cache Consistency</a></li></ul></li></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer"><div class="container container-fluid"></div></footer></div>
</body>
</html>