diff --git a/plugins/chat/app/models/chat/user_chat_thread_membership.rb b/plugins/chat/app/models/chat/user_chat_thread_membership.rb
index 0b2793e51c2..49d2bdfd181 100644
--- a/plugins/chat/app/models/chat/user_chat_thread_membership.rb
+++ b/plugins/chat/app/models/chat/user_chat_thread_membership.rb
@@ -20,7 +20,11 @@ end
 #  user_id              :bigint           not null
 #  thread_id            :bigint           not null
 #  last_read_message_id :bigint
-#  notification_level   :integer          default(2), not null
+#  notification_level   :integer          default("tracking"), not null
 #  created_at           :datetime         not null
 #  updated_at           :datetime         not null
 #
+# Indexes
+#
+#  user_chat_thread_unique_memberships  (user_id,thread_id) UNIQUE
+#
diff --git a/plugins/chat/db/migrate/20230607091233_backfill_thread_memberships.rb b/plugins/chat/db/migrate/20230607091233_backfill_thread_memberships.rb
new file mode 100644
index 00000000000..8dfedf140ab
--- /dev/null
+++ b/plugins/chat/db/migrate/20230607091233_backfill_thread_memberships.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+class BackfillThreadMemberships < ActiveRecord::Migration[7.0]
+  def up
+    thread_tracking_notification_level = 2
+
+    sql = <<~SQL
+      INSERT INTO user_chat_thread_memberships(
+        user_id,
+        thread_id,
+        notification_level,
+        last_read_message_id,
+        created_at,
+        updated_at
+      )
+      SELECT
+        thread_participant_stats.user_id,
+        thread_participant_stats.thread_id,
+        #{thread_tracking_notification_level},
+        (
+          SELECT id FROM chat_messages
+          WHERE thread_id = thread_participant_stats.thread_id
+          AND deleted_at IS NULL
+          ORDER BY created_at DESC, id DESC
+          LIMIT 1
+        ),
+        NOW(),
+        NOW()
+      FROM (
+        SELECT chat_messages.thread_id, chat_messages.user_id
+        FROM chat_messages
+        INNER JOIN chat_threads ON chat_threads.id = chat_messages.thread_id
+        WHERE chat_messages.thread_id IS NOT NULL
+        GROUP BY chat_messages.thread_id, chat_messages.user_id
+        ORDER BY chat_messages.thread_id ASC, chat_messages.user_id ASC
+      ) AS thread_participant_stats
+      INNER JOIN users ON users.id = thread_participant_stats.user_id
+      LEFT JOIN user_chat_thread_memberships ON user_chat_thread_memberships.thread_id = thread_participant_stats.thread_id
+        AND user_chat_thread_memberships.user_id = thread_participant_stats.user_id
+      WHERE user_chat_thread_memberships IS NULL
+      ORDER BY user_chat_thread_memberships.thread_id ASC
+      ON CONFLICT DO NOTHING;
+    SQL
+
+    execute(sql)
+  end
+
+  def down
+    raise ActiveRecord::IrreversibleMigration
+  end
+end