summary refs log tree commit diff
path: root/latest/print.html
diff options
context:
space:
mode:
authoranoadragon453 <anoadragon453@users.noreply.github.com>2022-03-22 16:30:53 +0000
committeranoadragon453 <anoadragon453@users.noreply.github.com>2022-03-22 16:30:53 +0000
commit7c5dd6ffb85f208632f7a2018a922b5ef2083c18 (patch)
treee511372fa26074d6f1a27993266296c529dcc9ff /latest/print.html
parentdeploy: 2177e356bc4b62e7a84c6fbee1d48de1abc940b5 (diff)
downloadsynapse-7c5dd6ffb85f208632f7a2018a922b5ef2083c18.tar.xz
deploy: 6b26536a52f77aa5573b4d2afedae448fac31b7c
Diffstat (limited to 'latest/print.html')
-rw-r--r--latest/print.html299
1 files changed, 245 insertions, 54 deletions
diff --git a/latest/print.html b/latest/print.html
index 038329652d..9558290e01 100644
--- a/latest/print.html
+++ b/latest/print.html
@@ -101,7 +101,7 @@
 
         <nav id="sidebar" class="sidebar" aria-label="Table of contents">
             <div class="sidebar-scrollbox">
-                <ol class="chapter"><li class="chapter-item expanded affix "><li class="part-title">Introduction</li><li class="chapter-item expanded "><a href="welcome_and_overview.html">Welcome and Overview</a></li><li class="chapter-item expanded affix "><li class="part-title">Setup</li><li class="chapter-item expanded "><a href="setup/installation.html">Installation</a></li><li class="chapter-item expanded "><a href="postgres.html">Using Postgres</a></li><li class="chapter-item expanded "><a href="reverse_proxy.html">Configuring a Reverse Proxy</a></li><li class="chapter-item expanded "><a href="setup/forward_proxy.html">Configuring a Forward/Outbound Proxy</a></li><li class="chapter-item expanded "><a href="turn-howto.html">Configuring a Turn Server</a></li><li class="chapter-item expanded "><a href="delegate.html">Delegation</a></li><li class="chapter-item expanded affix "><li class="part-title">Upgrading</li><li class="chapter-item expanded "><a href="upgrade.html">Upgrading between Synapse Versions</a></li><li class="chapter-item expanded affix "><li class="part-title">Usage</li><li class="chapter-item expanded "><a href="federate.html">Federation</a></li><li class="chapter-item expanded "><a href="usage/configuration/index.html">Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/homeserver_sample_config.html">Homeserver Sample Config File</a></li><li class="chapter-item expanded "><a href="usage/configuration/logging_sample_config.html">Logging Sample Config File</a></li><li class="chapter-item expanded "><a href="structured_logging.html">Structured Logging</a></li><li class="chapter-item expanded "><a href="templates.html">Templates</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/index.html">User Authentication</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/index.html">Single-Sign On</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="openid.html">OpenID Connect</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/cas.html">CAS</a></li><li class="chapter-item expanded "><a href="sso_mapping_providers.html">SSO Mapping Providers</a></li></ol></li><li class="chapter-item expanded "><a href="password_auth_providers.html">Password Auth Providers</a></li><li class="chapter-item expanded "><a href="jwt.html">JSON Web Tokens</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/refresh_tokens.html">Refresh Tokens</a></li></ol></li><li class="chapter-item expanded "><a href="CAPTCHA_SETUP.html">Registration Captcha</a></li><li class="chapter-item expanded "><a href="application_services.html">Application Services</a></li><li class="chapter-item expanded "><a href="server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="consent_tracking.html">Consent Tracking</a></li><li class="chapter-item expanded "><a href="development/url_previews.html">URL Previews</a></li><li class="chapter-item expanded "><a href="user_directory.html">User Directory</a></li><li class="chapter-item expanded "><a href="message_retention_policies.html">Message Retention Policies</a></li><li class="chapter-item expanded "><a href="modules/index.html">Pluggable Modules</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/writing_a_module.html">Writing a module</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/spam_checker_callbacks.html">Spam checker callbacks</a></li><li class="chapter-item expanded "><a href="modules/third_party_rules_callbacks.html">Third-party rules callbacks</a></li><li class="chapter-item expanded "><a href="modules/presence_router_callbacks.html">Presence router callbacks</a></li><li class="chapter-item expanded "><a href="modules/account_validity_callbacks.html">Account validity callbacks</a></li><li class="chapter-item expanded "><a href="modules/password_auth_provider_callbacks.html">Password auth provider callbacks</a></li><li class="chapter-item expanded "><a href="modules/background_update_controller_callbacks.html">Background update controller callbacks</a></li><li class="chapter-item expanded "><a href="modules/porting_legacy_module.html">Porting a legacy module to the new interface</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="workers.html">Workers</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="synctl_workers.html">Using synctl with Workers</a></li><li class="chapter-item expanded "><a href="systemd-with-workers/index.html">Systemd</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="usage/administration/index.html">Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/administration/admin_api/index.html">Admin API</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="admin_api/account_validity.html">Account Validity</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/background_updates.html">Background Updates</a></li><li class="chapter-item expanded "><a href="admin_api/delete_group.html">Delete Group</a></li><li class="chapter-item expanded "><a href="admin_api/event_reports.html">Event Reports</a></li><li class="chapter-item expanded "><a href="admin_api/media_admin_api.html">Media</a></li><li class="chapter-item expanded "><a href="admin_api/purge_history_api.html">Purge History</a></li><li class="chapter-item expanded "><a href="admin_api/register_api.html">Register Users</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/registration_tokens.html">Registration Tokens</a></li><li class="chapter-item expanded "><a href="admin_api/room_membership.html">Manipulate Room Membership</a></li><li class="chapter-item expanded "><a href="admin_api/rooms.html">Rooms</a></li><li class="chapter-item expanded "><a href="admin_api/server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="admin_api/statistics.html">Statistics</a></li><li class="chapter-item expanded "><a href="admin_api/user_admin_api.html">Users</a></li><li class="chapter-item expanded "><a href="admin_api/version_api.html">Server Version</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/federation.html">Federation</a></li></ol></li><li class="chapter-item expanded "><a href="manhole.html">Manhole</a></li><li class="chapter-item expanded "><a href="metrics-howto.html">Monitoring</a></li><li class="chapter-item expanded "><a href="usage/administration/understanding_synapse_through_grafana_graphs.html">Understanding Synapse Through Grafana Graphs</a></li><li class="chapter-item expanded "><a href="usage/administration/useful_sql_for_admins.html">Useful SQL for Admins</a></li><li class="chapter-item expanded "><a href="usage/administration/database_maintenance_tools.html">Database Maintenance Tools</a></li><li class="chapter-item expanded "><a href="usage/administration/state_groups.html">State Groups</a></li><li class="chapter-item expanded "><a href="usage/administration/request_log.html">Request log format</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_faq.html">Admin FAQ</a></li><li class="chapter-item expanded "><div>Scripts</div></li></ol></li><li class="chapter-item expanded "><li class="part-title">Development</li><li class="chapter-item expanded "><a href="development/contributing_guide.html">Contributing Guide</a></li><li class="chapter-item expanded "><a href="code_style.html">Code Style</a></li><li class="chapter-item expanded "><a href="development/releases.html">Release Cycle</a></li><li class="chapter-item expanded "><a href="development/git.html">Git Usage</a></li><li class="chapter-item expanded "><div>Testing</div></li><li class="chapter-item expanded "><a href="opentracing.html">OpenTracing</a></li><li class="chapter-item expanded "><a href="development/database_schema.html">Database Schemas</a></li><li class="chapter-item expanded "><a href="development/experimental_features.html">Experimental features</a></li><li class="chapter-item expanded "><div>Synapse Architecture</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="log_contexts.html">Log Contexts</a></li><li class="chapter-item expanded "><a href="replication.html">Replication</a></li><li class="chapter-item expanded "><a href="tcp_replication.html">TCP Replication</a></li></ol></li><li class="chapter-item expanded "><a href="development/internal_documentation/index.html">Internal Documentation</a></li><li><ol class="section"><li class="chapter-item expanded "><div>Single Sign-On</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="development/cas.html">CAS</a></li></ol></li><li class="chapter-item expanded "><a href="development/room-dag-concepts.html">Room DAG concepts</a></li><li class="chapter-item expanded "><div>State Resolution</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="auth_chain_difference_algorithm.html">The Auth Chain Difference Algorithm</a></li></ol></li><li class="chapter-item expanded "><a href="media_repository.html">Media Repository</a></li><li class="chapter-item expanded "><a href="room_and_user_statistics.html">Room and User Statistics</a></li></ol></li><li class="chapter-item expanded "><div>Scripts</div></li><li class="chapter-item expanded affix "><li class="part-title">Other</li><li class="chapter-item expanded "><a href="deprecation_policy.html">Dependency Deprecation Policy</a></li><li class="chapter-item expanded "><a href="other/running_synapse_on_single_board_computers.html">Running Synapse on a Single-Board Computer</a></li></ol>
+                <ol class="chapter"><li class="chapter-item expanded affix "><li class="part-title">Introduction</li><li class="chapter-item expanded "><a href="welcome_and_overview.html">Welcome and Overview</a></li><li class="chapter-item expanded affix "><li class="part-title">Setup</li><li class="chapter-item expanded "><a href="setup/installation.html">Installation</a></li><li class="chapter-item expanded "><a href="postgres.html">Using Postgres</a></li><li class="chapter-item expanded "><a href="reverse_proxy.html">Configuring a Reverse Proxy</a></li><li class="chapter-item expanded "><a href="setup/forward_proxy.html">Configuring a Forward/Outbound Proxy</a></li><li class="chapter-item expanded "><a href="turn-howto.html">Configuring a Turn Server</a></li><li class="chapter-item expanded "><a href="delegate.html">Delegation</a></li><li class="chapter-item expanded affix "><li class="part-title">Upgrading</li><li class="chapter-item expanded "><a href="upgrade.html">Upgrading between Synapse Versions</a></li><li class="chapter-item expanded affix "><li class="part-title">Usage</li><li class="chapter-item expanded "><a href="federate.html">Federation</a></li><li class="chapter-item expanded "><a href="usage/configuration/index.html">Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/homeserver_sample_config.html">Homeserver Sample Config File</a></li><li class="chapter-item expanded "><a href="usage/configuration/logging_sample_config.html">Logging Sample Config File</a></li><li class="chapter-item expanded "><a href="structured_logging.html">Structured Logging</a></li><li class="chapter-item expanded "><a href="templates.html">Templates</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/index.html">User Authentication</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/index.html">Single-Sign On</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="openid.html">OpenID Connect</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/cas.html">CAS</a></li><li class="chapter-item expanded "><a href="sso_mapping_providers.html">SSO Mapping Providers</a></li></ol></li><li class="chapter-item expanded "><a href="password_auth_providers.html">Password Auth Providers</a></li><li class="chapter-item expanded "><a href="jwt.html">JSON Web Tokens</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/refresh_tokens.html">Refresh Tokens</a></li></ol></li><li class="chapter-item expanded "><a href="CAPTCHA_SETUP.html">Registration Captcha</a></li><li class="chapter-item expanded "><a href="application_services.html">Application Services</a></li><li class="chapter-item expanded "><a href="server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="consent_tracking.html">Consent Tracking</a></li><li class="chapter-item expanded "><a href="development/url_previews.html">URL Previews</a></li><li class="chapter-item expanded "><a href="user_directory.html">User Directory</a></li><li class="chapter-item expanded "><a href="message_retention_policies.html">Message Retention Policies</a></li><li class="chapter-item expanded "><a href="modules/index.html">Pluggable Modules</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/writing_a_module.html">Writing a module</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/spam_checker_callbacks.html">Spam checker callbacks</a></li><li class="chapter-item expanded "><a href="modules/third_party_rules_callbacks.html">Third-party rules callbacks</a></li><li class="chapter-item expanded "><a href="modules/presence_router_callbacks.html">Presence router callbacks</a></li><li class="chapter-item expanded "><a href="modules/account_validity_callbacks.html">Account validity callbacks</a></li><li class="chapter-item expanded "><a href="modules/password_auth_provider_callbacks.html">Password auth provider callbacks</a></li><li class="chapter-item expanded "><a href="modules/background_update_controller_callbacks.html">Background update controller callbacks</a></li><li class="chapter-item expanded "><a href="modules/porting_legacy_module.html">Porting a legacy module to the new interface</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="workers.html">Workers</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="synctl_workers.html">Using synctl with Workers</a></li><li class="chapter-item expanded "><a href="systemd-with-workers/index.html">Systemd</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="usage/administration/index.html">Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/administration/admin_api/index.html">Admin API</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="admin_api/account_validity.html">Account Validity</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/background_updates.html">Background Updates</a></li><li class="chapter-item expanded "><a href="admin_api/delete_group.html">Delete Group</a></li><li class="chapter-item expanded "><a href="admin_api/event_reports.html">Event Reports</a></li><li class="chapter-item expanded "><a href="admin_api/media_admin_api.html">Media</a></li><li class="chapter-item expanded "><a href="admin_api/purge_history_api.html">Purge History</a></li><li class="chapter-item expanded "><a href="admin_api/register_api.html">Register Users</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/registration_tokens.html">Registration Tokens</a></li><li class="chapter-item expanded "><a href="admin_api/room_membership.html">Manipulate Room Membership</a></li><li class="chapter-item expanded "><a href="admin_api/rooms.html">Rooms</a></li><li class="chapter-item expanded "><a href="admin_api/server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="admin_api/statistics.html">Statistics</a></li><li class="chapter-item expanded "><a href="admin_api/user_admin_api.html">Users</a></li><li class="chapter-item expanded "><a href="admin_api/version_api.html">Server Version</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/federation.html">Federation</a></li></ol></li><li class="chapter-item expanded "><a href="manhole.html">Manhole</a></li><li class="chapter-item expanded "><a href="metrics-howto.html">Monitoring</a></li><li class="chapter-item expanded "><a href="usage/administration/understanding_synapse_through_grafana_graphs.html">Understanding Synapse Through Grafana Graphs</a></li><li class="chapter-item expanded "><a href="usage/administration/useful_sql_for_admins.html">Useful SQL for Admins</a></li><li class="chapter-item expanded "><a href="usage/administration/database_maintenance_tools.html">Database Maintenance Tools</a></li><li class="chapter-item expanded "><a href="usage/administration/state_groups.html">State Groups</a></li><li class="chapter-item expanded "><a href="usage/administration/request_log.html">Request log format</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_faq.html">Admin FAQ</a></li><li class="chapter-item expanded "><div>Scripts</div></li></ol></li><li class="chapter-item expanded "><li class="part-title">Development</li><li class="chapter-item expanded "><a href="development/contributing_guide.html">Contributing Guide</a></li><li class="chapter-item expanded "><a href="code_style.html">Code Style</a></li><li class="chapter-item expanded "><a href="development/releases.html">Release Cycle</a></li><li class="chapter-item expanded "><a href="development/git.html">Git Usage</a></li><li class="chapter-item expanded "><div>Testing</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/demo.html">Demo scripts</a></li></ol></li><li class="chapter-item expanded "><a href="opentracing.html">OpenTracing</a></li><li class="chapter-item expanded "><a href="development/database_schema.html">Database Schemas</a></li><li class="chapter-item expanded "><a href="development/experimental_features.html">Experimental features</a></li><li class="chapter-item expanded "><div>Synapse Architecture</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="log_contexts.html">Log Contexts</a></li><li class="chapter-item expanded "><a href="replication.html">Replication</a></li><li class="chapter-item expanded "><a href="tcp_replication.html">TCP Replication</a></li></ol></li><li class="chapter-item expanded "><a href="development/internal_documentation/index.html">Internal Documentation</a></li><li><ol class="section"><li class="chapter-item expanded "><div>Single Sign-On</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="development/cas.html">CAS</a></li></ol></li><li class="chapter-item expanded "><a href="development/room-dag-concepts.html">Room DAG concepts</a></li><li class="chapter-item expanded "><div>State Resolution</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="auth_chain_difference_algorithm.html">The Auth Chain Difference Algorithm</a></li></ol></li><li class="chapter-item expanded "><a href="media_repository.html">Media Repository</a></li><li class="chapter-item expanded "><a href="room_and_user_statistics.html">Room and User Statistics</a></li></ol></li><li class="chapter-item expanded "><div>Scripts</div></li><li class="chapter-item expanded affix "><li class="part-title">Other</li><li class="chapter-item expanded "><a href="deprecation_policy.html">Dependency Deprecation Policy</a></li><li class="chapter-item expanded "><a href="other/running_synapse_on_single_board_computers.html">Running Synapse on a Single-Board Computer</a></li></ol>
             </div>
             <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
         </nav>
@@ -795,9 +795,9 @@ space on disk after porting to Postgres.</p>
 <p>Firstly, shut down the currently running synapse server and copy its
 database file (typically <code>homeserver.db</code>) to another location. Once the
 copy is complete, restart synapse. For instance:</p>
-<pre><code class="language-sh">./synctl stop
+<pre><code class="language-sh">synctl stop
 cp homeserver.db homeserver.db.snapshot
-./synctl start
+synctl start
 </code></pre>
 <p>Copy the old config file into a new config file:</p>
 <pre><code class="language-sh">cp homeserver.yaml homeserver-postgres.yaml
@@ -820,10 +820,10 @@ run:</p>
 </code></pre>
 <p>Once that has completed, change the synapse config to point at the
 PostgreSQL database configuration file <code>homeserver-postgres.yaml</code>:</p>
-<pre><code class="language-sh">./synctl stop
+<pre><code class="language-sh">synctl stop
 mv homeserver.yaml homeserver-old-sqlite.yaml
 mv homeserver-postgres.yaml homeserver.yaml
-./synctl start
+synctl start
 </code></pre>
 <p>Synapse should now be running against PostgreSQL.</p>
 <h2 id="troubleshooting"><a class="header" href="#troubleshooting">Troubleshooting</a></h2>
@@ -1374,8 +1374,9 @@ turn_allow_guests: True
 <p>After updating the homeserver configuration, you must restart synapse:</p>
 <ul>
 <li>If you use synctl:
-<pre><code class="language-sh">cd /where/you/run/synapse
-./synctl restart
+<pre><code class="language-sh"># Depending on how Synapse is installed, synctl may already be on
+# your PATH. If not, you may need to activate a virtual environment.
+synctl restart
 </code></pre>
 </li>
 <li>If you use systemd:
@@ -1603,7 +1604,7 @@ pip install --upgrade .
 </li>
 <li>
 <p>Restart Synapse:</p>
-<pre><code class="language-bash">./synctl restart
+<pre><code class="language-bash">synctl restart
 </code></pre>
 </li>
 </ol>
@@ -1638,6 +1639,37 @@ dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
 </code></pre>
 </li>
 </ul>
+<h1 id="upgrading-to-v1560"><a class="header" href="#upgrading-to-v1560">Upgrading to v1.56.0</a></h1>
+<h2 id="groupscommunities-feature-has-been-deprecated"><a class="header" href="#groupscommunities-feature-has-been-deprecated">Groups/communities feature has been deprecated</a></h2>
+<p>The non-standard groups/communities feature in Synapse has been deprecated and will
+be disabled by default in Synapse v1.58.0.</p>
+<p>You can test disabling it by adding the following to your homeserver configuration:</p>
+<pre><code class="language-yaml">experimental_features:
+  groups_enabled: false
+</code></pre>
+<h1 id="upgrading-to-v1550"><a class="header" href="#upgrading-to-v1550">Upgrading to v1.55.0</a></h1>
+<h2 id="synctl-script-has-been-moved"><a class="header" href="#synctl-script-has-been-moved"><code>synctl</code> script has been moved</a></h2>
+<p>The <code>synctl</code> script
+<a href="https://github.com/matrix-org/synapse/pull/12140">has been made</a> an
+<a href="https://packaging.python.org/en/latest/specifications/entry-points/">entry point</a>
+and no longer exists at the root of Synapse's source tree. If you wish to use
+<code>synctl</code> to manage your homeserver, you should invoke <code>synctl</code> directly, e.g. 
+<code>synctl start</code> instead of <code>./synctl start</code> or <code>/path/to/synctl start</code>. </p>
+<p>You will need to ensure <code>synctl</code> is on your <code>PATH</code>.</p>
+<ul>
+<li>This is automatically the case when using
+<a href="https://packages.matrix.org/debian/">Debian packages</a> or
+<a href="https://hub.docker.com/r/matrixdotorg/synapse">docker images</a>
+provided by Matrix.org.</li>
+<li>When installing from a wheel, sdist, or PyPI, a <code>synctl</code> executable is added 
+to your Python installation's <code>bin</code>. This should be on your <code>PATH</code>
+automatically, though you might need to activate a virtual environment
+depending on how you installed Synapse.</li>
+</ul>
+<h2 id="compatibility-dropped-for-mjolnir-131-and-earlier"><a class="header" href="#compatibility-dropped-for-mjolnir-131-and-earlier">Compatibility dropped for Mjolnir 1.3.1 and earlier</a></h2>
+<p>Synapse v1.55.0 drops support for Mjolnir 1.3.1 and earlier.
+If you use the Mjolnir module to moderate your homeserver,
+please upgrade Mjolnir to version 1.3.2 or later before upgrading Synapse.</p>
 <h1 id="upgrading-to-v1540"><a class="header" href="#upgrading-to-v1540">Upgrading to v1.54.0</a></h1>
 <h2 id="legacy-structured-logging-configuration-removal"><a class="header" href="#legacy-structured-logging-configuration-removal">Legacy structured logging configuration removal</a></h2>
 <p>This release removes support for the <code>structured: true</code> logging configuration
@@ -2904,7 +2936,8 @@ release of Synapse.</p>
 <h2 id="running-a-demo-federation-of-synapses"><a class="header" href="#running-a-demo-federation-of-synapses">Running a demo federation of Synapses</a></h2>
 <p>If you want to get up and running quickly with a trio of homeservers in a
 private federation, there is a script in the <code>demo</code> directory. This is mainly
-useful just for development purposes. See <a href="https://github.com/matrix-org/synapse/tree/develop/demo/">demo/README</a>.</p>
+useful just for development purposes. See
+<a href="https://matrix-org.github.io/synapse/develop/development/demo.html">demo scripts</a>.</p>
 <div id="chapter_begin" style="break-before: page; page-break-before: always;"></div><h1 id="configuration-1"><a class="header" href="#configuration-1">Configuration</a></h1>
 <p>This section contains information on tweaking Synapse via the various options in the configuration file. A configuration
 file should have been generated when you <a href="usage/configuration/../../setup/installation.html">installed Synapse</a>.</p>
@@ -4865,8 +4898,14 @@ saml2_config:
 #
 #             localpart_template: Jinja2 template for the localpart of the MXID.
 #                 If this is not set, the user will be prompted to choose their
-#                 own username (see 'sso_auth_account_details.html' in the 'sso'
-#                 section of this file).
+#                 own username (see the documentation for the
+#                 'sso_auth_account_details.html' template). This template can
+#                 use the 'localpart_from_email' filter.
+#
+#             confirm_localpart: Whether to prompt the user to validate (or
+#                 change) the generated localpart (see the documentation for the
+#                 'sso_auth_account_details.html' template), instead of
+#                 registering the account right away.
 #
 #             display_name_template: Jinja2 template for the display name to set
 #                 on first login. If unset, no displayname will be set.
@@ -5647,6 +5686,38 @@ redis:
   # Optional password if configured on the Redis instance
   #
   #password: &lt;secret_password&gt;
+
+
+## Background Updates ##
+
+# Background updates are database updates that are run in the background in batches.
+# The duration, minimum batch size, default batch size, whether to sleep between batches and if so, how long to
+# sleep can all be configured. This is helpful to speed up or slow down the updates.
+#
+background_updates:
+    # How long in milliseconds to run a batch of background updates for. Defaults to 100. Uncomment and set
+    # a time to change the default.
+    #
+    #background_update_duration_ms: 500
+
+    # Whether to sleep between updates. Defaults to True. Uncomment to change the default.
+    #
+    #sleep_enabled: false
+
+    # If sleeping between updates, how long in milliseconds to sleep for. Defaults to 1000. Uncomment
+    # and set a duration to change the default.
+    #
+    #sleep_duration_ms: 300
+
+    # Minimum size a batch of background updates can be. Must be greater than 0. Defaults to 1. Uncomment and
+    # set a size to change the default.
+    #
+    #min_batch_size: 10
+
+    # The batch size to use for the first iteration of a new background update. The default is 100.
+    # Uncomment and set a size to change the default.
+    #
+    #default_batch_size: 50
 </code></pre>
 <div id="chapter_begin" style="break-before: page; page-break-before: always;"></div><h1 id="logging-sample-configuration-file"><a class="header" href="#logging-sample-configuration-file">Logging Sample Configuration File</a></h1>
 <p>Below is a sample logging configuration file. This file can be tweaked to control how your
@@ -5902,6 +5973,10 @@ already available as part of Jinja 2:</p>
 <p>Turns a <code>mxc://</code> URL for media content into an HTTP(S) one using the homeserver's
 <code>public_baseurl</code> configuration setting as the URL's base.</p>
 <p>Example: <code>message.sender_avatar_url|mxc_to_http(32,32)</code></p>
+<pre><code class="language-python">localpart_from_email(address: str) -&gt; str
+</code></pre>
+<p>Returns the local part of an email address (e.g. <code>alice</code> in <code>alice@example.com</code>).</p>
+<p>Example: <code>user.email_address|localpart_from_email</code></p>
 <h2 id="email-templates"><a class="header" href="#email-templates">Email templates</a></h2>
 <p>Below are the templates Synapse will look for when generating the content of an email:</p>
 <ul>
@@ -6065,8 +6140,11 @@ for the brand of the IdP</li>
 <li><code>user_attributes</code>: an object containing details about the user that
 we received from the IdP. May have the following attributes:
 <ul>
-<li>display_name: the user's display_name</li>
-<li>emails: a list of email addresses
+<li><code>display_name</code>: the user's display name</li>
+<li><code>emails</code>: a list of email addresses</li>
+<li><code>localpart</code>: the local part of the Matrix user ID to register,
+if <code>localpart_template</code> is set in the mapping provider configuration (empty
+string if not)
 The template should render a form which submits the following fields:</li>
 </ul>
 </li>
@@ -8270,6 +8348,35 @@ it will be included in this state.</p>
 into the room, which means this callback cannot be used to deny persisting the event. To
 deny an incoming event, see <a href="modules/spam_checker_callbacks.html#check_event_for_spam"><code>check_event_for_spam</code></a> instead.</p>
 <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
+<h3 id="check_can_shutdown_room"><a class="header" href="#check_can_shutdown_room"><code>check_can_shutdown_room</code></a></h3>
+<p><em>First introduced in Synapse v1.55.0</em></p>
+<pre><code class="language-python">async def check_can_shutdown_room(
+    user_id: str, room_id: str,
+) -&gt; bool:
+</code></pre>
+<p>Called when an admin user requests the shutdown of a room. The module must return a
+boolean indicating whether the shutdown can go through. If the callback returns <code>False</code>,
+the shutdown will not proceed and the caller will see a <code>M_FORBIDDEN</code> error.</p>
+<p>If multiple modules implement this callback, they will be considered in order. If a
+callback returns <code>True</code>, Synapse falls through to the next one. The value of the first
+callback that does not return <code>True</code> will be used. If this happens, Synapse will not call
+any of the subsequent implementations of this callback.</p>
+<h3 id="check_can_deactivate_user"><a class="header" href="#check_can_deactivate_user"><code>check_can_deactivate_user</code></a></h3>
+<p><em>First introduced in Synapse v1.55.0</em></p>
+<pre><code class="language-python">async def check_can_deactivate_user(
+    user_id: str, by_admin: bool,
+) -&gt; bool:
+</code></pre>
+<p>Called when the deactivation of a user is requested. User deactivation can be
+performed by an admin or the user themselves, so developers are encouraged to check the
+requester when implementing this callback. The module must return a
+boolean indicating whether the deactivation can go through. If the callback returns <code>False</code>,
+the deactivation will not proceed and the caller will see a <code>M_FORBIDDEN</code> error.</p>
+<p>The module is passed two parameters, <code>user_id</code> which is the ID of the user being deactivated, and <code>by_admin</code> which is <code>True</code> if the request is made by a serve admin, and <code>False</code> otherwise.</p>
+<p>If multiple modules implement this callback, they will be considered in order. If a
+callback returns <code>True</code>, Synapse falls through to the next one. The value of the first
+callback that does not return <code>True</code> will be used. If this happens, Synapse will not call
+any of the subsequent implementations of this callback.</p>
 <h3 id="on_profile_update"><a class="header" href="#on_profile_update"><code>on_profile_update</code></a></h3>
 <p><em>First introduced in Synapse v1.54.0</em></p>
 <pre><code class="language-python">async def on_profile_update(
@@ -9043,8 +9150,10 @@ streams (such as events) off of the main process to a particular worker. (This
 is only supported with Redis-based replication.)</p>
 <p>To enable this, the worker must have a HTTP replication listener configured,
 have a <code>worker_name</code> and be listed in the <code>instance_map</code> config. The same worker
-can handle multiple streams. For example, to move event persistence off to a
-dedicated worker, the shared configuration would include:</p>
+can handle multiple streams, but unless otherwise documented, each stream can only
+have a single writer.</p>
+<p>For example, to move event persistence off to a dedicated worker, the shared
+configuration would include:</p>
 <pre><code class="language-yaml">instance_map:
     event_persister1:
         host: localhost
@@ -9057,8 +9166,8 @@ stream_writers:
 be routed to the workers handling that stream. See below for the currently supported
 streams and the endpoints associated with them:</p>
 <h5 id="the-events-stream"><a class="header" href="#the-events-stream">The <code>events</code> stream</a></h5>
-<p>The <code>events</code> stream also experimentally supports having multiple writers, where
-work is sharded between them by room ID. Note that you <em>must</em> restart all worker
+<p>The <code>events</code> stream experimentally supports having multiple writers, where work
+is sharded between them by room ID. Note that you <em>must</em> restart all worker
 instances when adding or removing event persisters. An example <code>stream_writers</code>
 configuration with multiple writers:</p>
 <pre><code class="language-yaml">stream_writers:
@@ -9067,30 +9176,30 @@ configuration with multiple writers:</p>
         - event_persister2
 </code></pre>
 <h5 id="the-typing-stream"><a class="header" href="#the-typing-stream">The <code>typing</code> stream</a></h5>
-<p>The following endpoints should be routed directly to the workers configured as
-stream writers for the <code>typing</code> stream:</p>
+<p>The following endpoints should be routed directly to the worker configured as
+the stream writer for the <code>typing</code> stream:</p>
 <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/typing
 </code></pre>
 <h5 id="the-to_device-stream"><a class="header" href="#the-to_device-stream">The <code>to_device</code> stream</a></h5>
-<p>The following endpoints should be routed directly to the workers configured as
-stream writers for the <code>to_device</code> stream:</p>
+<p>The following endpoints should be routed directly to the worker configured as
+the stream writer for the <code>to_device</code> stream:</p>
 <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/sendToDevice/
 </code></pre>
 <h5 id="the-account_data-stream"><a class="header" href="#the-account_data-stream">The <code>account_data</code> stream</a></h5>
-<p>The following endpoints should be routed directly to the workers configured as
-stream writers for the <code>account_data</code> stream:</p>
+<p>The following endpoints should be routed directly to the worker configured as
+the stream writer for the <code>account_data</code> stream:</p>
 <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/.*/tags
 ^/_matrix/client/(api/v1|r0|v3|unstable)/.*/account_data
 </code></pre>
 <h5 id="the-receipts-stream"><a class="header" href="#the-receipts-stream">The <code>receipts</code> stream</a></h5>
-<p>The following endpoints should be routed directly to the workers configured as
-stream writers for the <code>receipts</code> stream:</p>
+<p>The following endpoints should be routed directly to the worker configured as
+the stream writer for the <code>receipts</code> stream:</p>
 <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/receipt
 ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/read_markers
 </code></pre>
 <h5 id="the-presence-stream"><a class="header" href="#the-presence-stream">The <code>presence</code> stream</a></h5>
-<p>The following endpoints should be routed directly to the workers configured as
-stream writers for the <code>presence</code> stream:</p>
+<p>The following endpoints should be routed directly to the worker configured as
+the stream writer for the <code>presence</code> stream:</p>
 <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/presence/
 </code></pre>
 <h4 id="background-tasks"><a class="header" href="#background-tasks">Background tasks</a></h4>
@@ -9369,7 +9478,7 @@ server admin. (Note that a server admin is distinct from a room admin.)</p>
 <pre><code class="language-sql">UPDATE users SET admin = 1 WHERE name = '@foo:bar.com';
 </code></pre>
 <p>A new server admin user can also be created using the <code>register_new_matrix_user</code>
-command. This is a script that is located in the <code>scripts/</code> directory, or possibly
+command. This is a script that is distributed as part of synapse. It is possibly
 already on your <code>$PATH</code> depending on how Synapse was installed.</p>
 <p>Finding your user's <code>access_token</code> is client-dependent, but will usually be shown in the client's settings.</p>
 <h2 id="making-an-admin-api-request"><a class="header" href="#making-an-admin-api-request">Making an Admin API request</a></h2>
@@ -13251,6 +13360,15 @@ accept anonymous contributions at this time.</p>
 <p>Git allows you to add this signoff automatically when using the <code>-s</code>
 flag to <code>git commit</code>, which uses the name and email set in your
 <code>user.name</code> and <code>user.email</code> git configs.</p>
+<h3 id="private-sign-off"><a class="header" href="#private-sign-off">Private Sign off</a></h3>
+<p>If you would like to provide your legal name privately to the Matrix.org
+Foundation (instead of in a public commit or comment), you can do so
+by emailing your legal name and a link to the pull request to
+<a href="mailto:dco@matrix.org?subject=Private%20sign%20off">dco@matrix.org</a>.
+It helps to include &quot;sign off&quot; or similar in the subject line. You will then
+be instructed further.</p>
+<p>Once private sign off is complete, doing so for future contributions will not
+be required.</p>
 <h1 id="10-turn-feedback-into-better-code"><a class="header" href="#10-turn-feedback-into-better-code">10. Turn feedback into better code.</a></h1>
 <p>Once the Pull Request is opened, you will see a few things:</p>
 <ol>
@@ -13461,7 +13579,7 @@ frobber:
   #distance: 100
 </code></pre>
 <p>Note that the sample configuration is generated from the synapse code
-and is maintained by a script, <code>scripts-dev/generate_sample_config</code>.
+and is maintained by a script, <code>scripts-dev/generate_sample_config.sh</code>.
 Making sure that the output from this script matches the desired format
 is left as an exercise for the reader!</p>
 <div id="chapter_begin" style="break-before: page; page-break-before: always;"></div><h1 id="synapse-release-cycle"><a class="header" href="#synapse-release-cycle">Synapse Release Cycle</a></h1>
@@ -13615,6 +13733,40 @@ most intuitive name. <a href="development/git.html#a1">^</a></p>
 <p><b id="f3">[3]</b>: Very, very occasionally (I think this has happened once in
 the history of Synapse), we've had two releases in flight at once. Obviously,
 <code>release-v1.2</code> is more-stable than <code>release-v1.3</code>. <a href="development/git.html#a3">^</a></p>
+<div id="chapter_begin" style="break-before: page; page-break-before: always;"></div><h1 id="synapse-demo-setup"><a class="header" href="#synapse-demo-setup">Synapse demo setup</a></h1>
+<p><strong>DO NOT USE THESE DEMO SERVERS IN PRODUCTION</strong></p>
+<p>Requires you to have a <a href="https://matrix-org.github.io/synapse/develop/development/contributing_guide.html#4-install-the-dependencies">Synapse development environment setup</a>.</p>
+<p>The demo setup allows running three federation Synapse servers, with server
+names <code>localhost:8080</code>, <code>localhost:8081</code>, and <code>localhost:8082</code>.</p>
+<p>You can access them via any Matrix client over HTTP at <code>localhost:8080</code>,
+<code>localhost:8081</code>, and <code>localhost:8082</code> or over HTTPS at <code>localhost:8480</code>,
+<code>localhost:8481</code>, and <code>localhost:8482</code>.</p>
+<p>To enable the servers to communicate, self-signed SSL certificates are generated
+and the servers are configured in a highly insecure way, including:</p>
+<ul>
+<li>Not checking certificates over federation.</li>
+<li>Not verifying keys.</li>
+</ul>
+<p>The servers are configured to store their data under <code>demo/8080</code>, <code>demo/8081</code>, and
+<code>demo/8082</code>. This includes configuration, logs, SQLite databases, and media.</p>
+<p>Note that when joining a public room on a different HS via &quot;#foo:bar.net&quot;, then
+you are (in the current impl) joining a room with room_id &quot;foo&quot;. This means that
+it won't work if your HS already has a room with that name.</p>
+<h2 id="using-the-demo-scripts"><a class="header" href="#using-the-demo-scripts">Using the demo scripts</a></h2>
+<p>There's three main scripts with straightforward purposes:</p>
+<ul>
+<li><code>start.sh</code> will start the Synapse servers, generating any missing configuration.
+<ul>
+<li>This accepts a single parameter <code>--no-rate-limit</code> to &quot;disable&quot; rate limits
+(they actually still exist, but are very high).</li>
+</ul>
+</li>
+<li><code>stop.sh</code> will stop the Synapse servers.</li>
+<li><code>clean.sh</code> will delete the configuration, databases, log files, etc.</li>
+</ul>
+<p>To start a completely new set of servers, run:</p>
+<pre><code class="language-sh">./demo/stop.sh; ./demo/clean.sh &amp;&amp; ./demo/start.sh
+</code></pre>
 <div id="chapter_begin" style="break-before: page; page-break-before: always;"></div><h1 id="opentracing"><a class="header" href="#opentracing">OpenTracing</a></h1>
 <h2 id="background"><a class="header" href="#background">Background</a></h2>
 <p>OpenTracing is a semi-standard being adopted by a number of distributed
@@ -13821,9 +13973,9 @@ same as integers.</p>
 <ul>
 <li>
 <p>Any new boolean column must be added to the <code>BOOLEAN_COLUMNS</code> list in
-<code>scripts/synapse_port_db</code>. This tells the port script to cast the integer
-value from SQLite to a boolean before writing the value to the postgres
-database.</p>
+<code>synapse/_scripts/synapse_port_db.py</code>. This tells the port script to cast
+the integer value from SQLite to a boolean before writing the value to the
+postgres database.</p>
 </li>
 <li>
 <p>Before SQLite 3.23, <code>TRUE</code> and <code>FALSE</code> were not recognised as constants by
@@ -14534,24 +14686,62 @@ incrementing integer, but backfilled events start with <code>stream_ordering=-1<
 rather than skipping any that arrived late; whereas if you're looking at a
 historical section of timeline (i.e. <code>/messages</code>), you want to see the best
 representation of the state of the room as others were seeing it at the time.</p>
+<h2 id="outliers"><a class="header" href="#outliers">Outliers</a></h2>
+<p>We mark an event as an <code>outlier</code> when we haven't figured out the state for the
+room at that point in the DAG yet. They are &quot;floating&quot; events that we haven't
+yet correlated to the DAG.</p>
+<p>Outliers typically arise when we fetch the auth chain or state for a given
+event. When that happens, we just grab the events in the state/auth chain,
+without calculating the state at those events, or backfilling their
+<code>prev_events</code>.</p>
+<p>So, typically, we won't have the <code>prev_events</code> of an <code>outlier</code> in the database,
+(though it's entirely possible that we <em>might</em> have them for some other
+reason). Other things that make outliers different from regular events:</p>
+<ul>
+<li>
+<p>We don't have state for them, so there should be no entry in
+<code>event_to_state_groups</code> for an outlier. (In practice this isn't always
+the case, though I'm not sure why: see https://github.com/matrix-org/synapse/issues/12201).</p>
+</li>
+<li>
+<p>We don't record entries for them in the <code>event_edges</code>,
+<code>event_forward_extremeties</code> or <code>event_backward_extremities</code> tables.</p>
+</li>
+</ul>
+<p>Since outliers are not tied into the DAG, they do not normally form part of the
+timeline sent down to clients via <code>/sync</code> or <code>/messages</code>; however there is an
+exception:</p>
+<h3 id="out-of-band-membership-events"><a class="header" href="#out-of-band-membership-events">Out-of-band membership events</a></h3>
+<p>A special case of outlier events are some membership events for federated rooms
+that we aren't full members of. For example:</p>
+<ul>
+<li>invites received over federation, before we join the room</li>
+<li><em>rejections</em> for said invites</li>
+<li>knock events for rooms that we would like to join but have not yet joined.</li>
+</ul>
+<p>In all the above cases, we don't have the state for the room, which is why they
+are treated as outliers. They are a bit special though, in that they are
+proactively sent to clients via <code>/sync</code>.</p>
 <h2 id="forward-extremity"><a class="header" href="#forward-extremity">Forward extremity</a></h2>
-<p>Most-recent-in-time events in the DAG which are not referenced by any other events' <code>prev_events</code> yet.</p>
-<p>The forward extremities of a room are used as the <code>prev_events</code> when the next event is sent.</p>
+<p>Most-recent-in-time events in the DAG which are not referenced by any other
+events' <code>prev_events</code> yet. (In this definition, outliers, rejected events, and
+soft-failed events don't count.)</p>
+<p>The forward extremities of a room (or at least, a subset of them, if there are
+more than ten) are used as the <code>prev_events</code> when the next event is sent.</p>
+<p>The &quot;current state&quot; of a room (ie: the state which would be used if we
+generated a new event) is, therefore, the resolution of the room states
+at each of the forward extremities.</p>
 <h2 id="backward-extremity"><a class="header" href="#backward-extremity">Backward extremity</a></h2>
 <p>The current marker of where we have backfilled up to and will generally be the
 <code>prev_events</code> of the oldest-in-time events we have in the DAG. This gives a starting point when
 backfilling history.</p>
-<p>When we persist a non-outlier event, we clear it as a backward extremity and set
-all of its <code>prev_events</code> as the new backward extremities if they aren't already
-persisted in the <code>events</code> table.</p>
-<h2 id="outliers"><a class="header" href="#outliers">Outliers</a></h2>
-<p>We mark an event as an <code>outlier</code> when we haven't figured out the state for the
-room at that point in the DAG yet.</p>
-<p>We won't <em>necessarily</em> have the <code>prev_events</code> of an <code>outlier</code> in the database,
-but it's entirely possible that we <em>might</em>.</p>
-<p>For example, when we fetch the event auth chain or state for a given event, we
-mark all of those claimed auth events as outliers because we haven't done the
-state calculation ourself.</p>
+<p>Note that, unlike forward extremities, we typically don't have any backward
+extremity events themselves in the database - or, if we do, they will be &quot;outliers&quot; (see
+above). Either way, we don't expect to have the room state at a backward extremity.</p>
+<p>When we persist a non-outlier event, if it was previously a backward extremity,
+we clear it as a backward extremity and set all of its <code>prev_events</code> as the new
+backward extremities if they aren't already persisted as non-outliers. This
+therefore keeps the backward extremities up-to-date.</p>
 <h2 id="state-groups"><a class="header" href="#state-groups">State groups</a></h2>
 <p>For every non-outlier event we need to know the state at that event. Instead of
 storing the full state for each event in the DB (i.e. a <code>event_id -&gt; state</code>
@@ -14768,28 +14958,29 @@ to constantly update their platform dependencies to the latest versions.</p>
 <p>Anything that requires modifying the device list <a href="https://github.com/matrix-org/synapse/issues/7721">#7721</a> will take a while to propagate, again taking the client &quot;Offline&quot; until it's complete. This includes signing in and out, editing the public name and verifying e2ee. The main mitigation I recommend is to keep long-running sessions open e.g. by using Firefox SSB &quot;Use this site in App mode&quot; or Chromium PWA &quot;Install Element&quot;.</p>
 <h3 id="recommended-configuration"><a class="header" href="#recommended-configuration">Recommended configuration</a></h3>
 <p>Put the below in a new file at /etc/matrix-synapse/conf.d/sbc.yaml to override the defaults in homeserver.yaml.</p>
-<pre><code># Set to false to disable presence tracking on this homeserver.
+<pre><code># Disable presence tracking, which is currently fairly resource intensive
+# More info: https://github.com/matrix-org/synapse/issues/9478
 use_presence: false
 
-# When this is enabled, the room &quot;complexity&quot; will be checked before a user
-# joins a new remote room. If it is above the complexity limit, the server will
-# disallow joining, or will instantly leave.
+# Set a small complexity limit, preventing users from joining large rooms
+# which may be resource-intensive to remain a part of.
+#
+# Note that this will not prevent users from joining smaller rooms that
+# eventually become complex.
 limit_remote_rooms:
-  # Uncomment to enable room complexity checking.
-  #enabled: true
+  enabled: true
   complexity: 3.0
 
 # Database configuration
 database:
+  # Use postgres for the best performance
   name: psycopg2
   args:
     user: matrix-synapse
-    # Generate a long, secure one with a password manager
+    # Generate a long, secure password using a password manager
     password: hunter2
     database: matrix-synapse
     host: localhost
-    cp_min: 5
-    cp_max: 10
 </code></pre>
 <p>Currently the complexity is measured by <a href="https://github.com/matrix-org/synapse/blob/v1.20.1/synapse/storage/databases/main/events_worker.py#L986">current_state_events / 500</a>. You can find join times and your most complex rooms like this:</p>
 <pre><code>admin@homeserver:~$ zgrep '/client/r0/join/' /var/log/matrix-synapse/homeserver.log* | awk '{print $18, $25}' | sort --human-numeric-sort