diff --git a/reviewboard/accounts/forms/pages.py b/reviewboard/accounts/forms/pages.py
index 5e21b417a23f5372a4fb672b103e8f800418995a..c89674dcc3873d7295e2dd978e95b6cea6820ff2 100644
--- a/reviewboard/accounts/forms/pages.py
+++ b/reviewboard/accounts/forms/pages.py
@@ -105,6 +105,11 @@ class AccountSettingsForm(AccountPageForm):
         label=_('Show desktop notifications'),
         required=False)
 
+    publish_and_archive = forms.BooleanField(
+        label=_('Archive review requests after publishing reviews'),
+        required=False,
+        initial=False)
+
     #: Mapping of Profile attribute names to form field names.
     #:
     #: This is not necessarily comprehensive. Settings that require further
@@ -115,6 +120,7 @@ class AccountSettingsForm(AccountPageForm):
     _PROFILE_ATTRS_MAP: Mapping[str, str] = {
         'default_use_rich_text': 'default_use_rich_text',
         'open_an_issue': 'open_an_issue',
+        'publish_and_archive': 'publish_and_archive',
         'should_confirm_ship_it': 'confirm_ship_it',
         'should_enable_desktop_notifications': 'enable_desktop_notifications',
         'should_send_email': 'should_send_email',
@@ -179,7 +185,7 @@ class AccountSettingsForm(AccountPageForm):
                     'open_an_issue',
                     'default_use_rich_text',
                     'syntax_highlighting',
-                ),
+                    'publish_and_archive',),
             }),
             (_('Notifications'), {
                 'fields': ('should_send_email',
diff --git a/reviewboard/accounts/models.py b/reviewboard/accounts/models.py
index 19c5d04e761cf627747916e68f1f3f67bee85f8b..ef7cd99f6835bc8ef153f6ba4c10bded13a6f475 100644
--- a/reviewboard/accounts/models.py
+++ b/reviewboard/accounts/models.py
@@ -733,6 +733,39 @@ class Profile(models.Model):
         self.settings.setdefault('avatars', {})['avatar_service_id'] = \
             service.avatar_service_id
 
+    @property
+    def publish_and_archive(self) -> bool:
+        """Whether to always archive review requests after publishing.
+
+        Version Added:
+            8.0
+
+        Type:
+            bool
+        """
+        settings = self.settings or {}
+
+        return settings.get('publish_and_archive', False)
+
+    @publish_and_archive.setter
+    def publish_and_archive(
+        self,
+        archive: bool,
+    ) -> None:
+        """Set whether to always archive review requests after publishing.
+
+        The ``settings`` field will need to be saved after this is
+        modified.
+
+        Version Added:
+            8.0
+
+        Args:
+            archive (bool):
+                Whether or not to archive when publishing a review request.
+        """
+        self.settings['publish_and_archive'] = archive
+
     def get_display_name(self, viewing_user):
         """Return the name to display to the given user.
 
diff --git a/reviewboard/accounts/templatetags/accounts.py b/reviewboard/accounts/templatetags/accounts.py
index 62146bc21b4e056b37f3942815853c1e76d904fe..394ef31e410624c34fa7832f1328f94f8ad68ca5 100644
--- a/reviewboard/accounts/templatetags/accounts.py
+++ b/reviewboard/accounts/templatetags/accounts.py
@@ -124,6 +124,7 @@ def js_user_session_info(context):
                 'confirmShipIt': profile.should_confirm_ship_it,
                 'enableDesktopNotifications':
                     profile.should_enable_desktop_notifications,
+                'publishAndArchive': profile.publish_and_archive,
                 'quickAccessActionIDs': profile.quick_access_actions,
             })
         else:
diff --git a/reviewboard/accounts/tests/test_account_settings_form.py b/reviewboard/accounts/tests/test_account_settings_form.py
index 7d3d8b41c16069012d58d28065ae5c501f1e00de..92f6e26be674ff87dea0042de32657a7b9f61511 100644
--- a/reviewboard/accounts/tests/test_account_settings_form.py
+++ b/reviewboard/accounts/tests/test_account_settings_form.py
@@ -1,6 +1,9 @@
 """Unit tests for reviewboard.accounts.forms.pages.AccountSettingsForm."""
 
+from __future__ import annotations
+
 from django.contrib.auth.models import User
+from django.http import HttpRequest
 from django.views.generic.base import View
 from djblets.testing.decorators import add_fixtures
 
@@ -13,6 +16,26 @@ from reviewboard.testing import TestCase
 class AccountSettingsFormTests(TestCase):
     """Unit tests for reviewboard.accounts.forms.pages.AccountSettingsForm."""
 
+    ######################
+    # Instance variables #
+    ######################
+
+    #: The HTTP request.
+    request: HttpRequest
+
+    #: The user profile.
+    profile: Profile
+
+    #: The user to test with.
+    user: User
+
+    def setUp(self) -> None:
+        """Setup for a unit test."""
+        super().setUp()
+        self.request = self.create_http_request()
+        self.user = self.create_user()
+        self.profile = self.user.get_profile()
+
     @add_fixtures(['test_users'])
     def test_save_syntax_highlighting_disabled(self):
         """Testing AccountSettingsForm.save() with
@@ -41,3 +64,117 @@ class AccountSettingsFormTests(TestCase):
 
         profile = Profile.objects.get(pk=profile.pk)
         self.assertTrue(profile.syntax_highlighting)
+
+    def test_load_initial_data(self) -> None:
+        """Testing initial data loading into the form"""
+        form = AccountSettingsForm(page=None,
+                                   request=self.request,
+                                   user=self.user)
+        form.load()
+
+        self.assertEqual(form['timezone'].initial, self.profile.timezone)
+        self.assertEqual(form['open_an_issue'].initial,
+                         self.profile.open_an_issue)
+        self.assertEqual(form['syntax_highlighting'].initial,
+                         self.profile.syntax_highlighting)
+        self.assertEqual(form['default_use_rich_text'].initial, True)
+        self.assertEqual(form['should_send_email'].initial,
+                         self.profile.should_send_email)
+        self.assertEqual(form['should_send_own_updates'].initial,
+                         self.profile.should_send_own_updates)
+        self.assertEqual(form['enable_desktop_notifications'].initial,
+                         self.profile.settings.get(
+                             'enable_desktop_notifications', True))
+        self.assertEqual(form['publish_and_archive'].initial,
+                         self.profile.publish_and_archive)
+
+    def test_load_with_new_profile_defaults(self) -> None:
+        """Testing AccountSettingsForm.load with profile defaults"""
+        self.profile.timezone = 'US/Pacific'
+        self.profile.syntax_highlighting = False
+
+        form = AccountSettingsForm(page=None,
+                                   request=self.request,
+                                   user=self.user)
+
+        form.load()
+
+        self.assertEqual(form['timezone'].initial, 'US/Pacific')
+        self.assertEqual(form['syntax_highlighting'].initial, False)
+
+    def test_save_data(self) -> None:
+        """Testing saving form data to profile"""
+        form_data = {
+            'default_use_rich_text': False,
+            'enable_desktop_notifications': False,
+            'open_an_issue': True,
+            'publish_and_archive': True,
+            'should_send_email': True,
+            'should_send_own_updates': False,
+            'syntax_highlighting': True,
+            'timezone': 'US/Pacific',
+        }
+        form = AccountSettingsForm(page=None,
+                                   request=self.request,
+                                   user=self.user,
+                                   data=form_data)
+
+        self.assertTrue(form.is_valid())
+        form.save()
+
+        profile = self.user.get_profile()
+        self.assertEqual(profile.timezone, 'US/Pacific')
+        self.assertEqual(profile.open_an_issue, True)
+        self.assertEqual(profile.syntax_highlighting, True)
+        self.assertEqual(profile.default_use_rich_text, False)
+        self.assertEqual(profile.should_send_email, True)
+        self.assertEqual(profile.should_send_own_updates, False)
+        self.assertEqual(profile.settings.get('enable_desktop_notifications'),
+                         False)
+        self.assertEqual(profile.publish_and_archive, True)
+
+    def test_invalid_data(self) -> None:
+        """Testing form validation with invalid data"""
+        form_data = {
+            'default_use_rich_text': 'not_a_boolean',  # Invalid boolean
+            'enable_desktop_notifications': False,
+            'open_an_issue': True,
+            'publish_and_archive': True,
+            'should_send_email': True,
+            'should_send_own_updates': False,
+            'syntax_highlighting': 'not_a_boolean',  # Invalid boolean
+
+            # Assuming 'Invalid Timezone' is invalid
+            'timezone': 'Invalid Timezone',
+        }
+        form = AccountSettingsForm(page=None,
+                                   request=self.request,
+                                   user=self.user,
+                                   data=form_data)
+
+        self.assertFalse(form.is_valid())
+        self.assertIn('timezone', form.errors)
+
+        # BooleanField interprets any value that is not True, False, 'true',
+        # 'false', 1, 0, '1', '0' as False, so they don't cause errors.
+        self.assertNotIn('syntax_highlighting', form.errors)
+        self.assertNotIn('default_use_rich_text', form.errors)
+
+    def test_missing_required_data(self) -> None:
+        """Testing form validation with missing required data"""
+        form_data = {
+            # 'timezone' Missing required field
+            'open_an_issue': True,
+            'syntax_highlighting': True,
+            'default_use_rich_text': True,
+            'should_send_email': True,
+            'should_send_own_updates': False,
+            'enable_desktop_notifications': False,
+            'publish_and_archive': True,
+        }
+        form = AccountSettingsForm(data=form_data, page=None,
+                                   request=self.request,
+                                   user=self.user)
+
+        self.assertFalse(form.is_valid())
+        self.assertIn('timezone', form.errors)
diff --git a/reviewboard/accounts/tests/test_template_tags.py b/reviewboard/accounts/tests/test_template_tags.py
index 2c513f24522e445e8dc70fe619f2e479fca7ed5f..729dad339af68caa4939bdef309f2353d08f8317 100644
--- a/reviewboard/accounts/tests/test_template_tags.py
+++ b/reviewboard/accounts/tests/test_template_tags.py
@@ -86,6 +86,7 @@ class JSUserSessionInfoTests(TestCase):
                 'fullName': 'Test User',
                 'mutedReviewRequestsURL':
                     '/api/users/test/muted-review-requests/',
+                'publishAndArchive': False,
                 'quickAccessActionIDs': [],
                 'readOnly': False,
                 'sessionURL': '/api/session/',
@@ -154,6 +155,7 @@ class JSUserSessionInfoTests(TestCase):
                 'fullName': 'Test User',
                 'mutedReviewRequestsURL':
                     '/s/local-site-1/api/users/test/muted-review-requests/',
+                'publishAndArchive': False,
                 'quickAccessActionIDs': [],
                 'readOnly': False,
                 'sessionURL': '/s/local-site-1/api/session/',
@@ -215,6 +217,7 @@ class JSUserSessionInfoTests(TestCase):
                     'fullName': 'Test User',
                     'mutedReviewRequestsURL':
                         '/api/users/test/muted-review-requests/',
+                    'publishAndArchive': False,
                     'quickAccessActionIDs': [],
                     'readOnly': False,
                     'sessionURL': '/api/session/',
@@ -254,6 +257,7 @@ class JSUserSessionInfoTests(TestCase):
                     'fullName': 'Test User',
                     'mutedReviewRequestsURL':
                         '/api/users/test/muted-review-requests/',
+                    'publishAndArchive': False,
                     'quickAccessActionIDs': [],
                     'readOnly': False,
                     'sessionURL': '/api/session/',
