diff --git a/changelog.d/18172.misc b/changelog.d/18172.misc
new file mode 100644
index 0000000000000000000000000000000000000000..49b6be263b8459150437058e383dd7c9381e2562
--- /dev/null
+++ b/changelog.d/18172.misc
@@ -0,0 +1 @@
+Reduce database load of user search when using large search terms.
diff --git a/synapse/storage/databases/main/user_directory.py b/synapse/storage/databases/main/user_directory.py
index a51182de55ab4366919445ece45b5d42f689d948..d6cd0774a8c27ebd95a1b1f9de2ca6b8f635e1eb 100644
--- a/synapse/storage/databases/main/user_directory.py
+++ b/synapse/storage/databases/main/user_directory.py
@@ -1237,7 +1237,13 @@ def _parse_query_postgres(search_term: str) -> Tuple[str, str, str]:
     search_term = _filter_text_for_index(search_term)
 
     escaped_words = []
-    for word in _parse_words(search_term):
+    for index, word in enumerate(_parse_words(search_term)):
+        if index >= 10:
+            # We limit how many terms we include, as otherwise it can use
+            # excessive database time if people accidentally search for large
+            # strings.
+            break
+
         # Postgres tsvector and tsquery quoting rules:
         # words potentially containing punctuation should be quoted
         # and then existing quotes and backslashes should be doubled