diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/DesktopModule.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/DesktopModule.kt
index 8256634c1bda95b34816c0a59b2a1a1f09e81b96..bb0b796eb3f5c54b64770ee5db7b5af86e2bb9b4 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/DesktopModule.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/DesktopModule.kt
@@ -57,6 +57,9 @@ import org.briarproject.briar.desktop.notification.StubNotificationProvider
 import org.briarproject.briar.desktop.notification.linux.LibnotifyNotificationProvider
 import org.briarproject.briar.desktop.settings.Configuration
 import org.briarproject.briar.desktop.settings.ConfigurationImpl
+import org.briarproject.briar.desktop.settings.EncryptedSettings
+import org.briarproject.briar.desktop.settings.EncryptedSettingsImpl
+import org.briarproject.briar.desktop.settings.EncryptedSettingsReadOnly
 import org.briarproject.briar.desktop.settings.UnencryptedSettings
 import org.briarproject.briar.desktop.settings.UnencryptedSettingsImpl
 import org.briarproject.briar.desktop.settings.UnencryptedSettingsReadOnly
@@ -117,6 +120,15 @@ internal class DesktopModule(
     // provide [UnencryptedSettings] singleton itself as provided above to use same object
     fun provideUnencryptedSettingsReadOnly(settings: UnencryptedSettings): UnencryptedSettingsReadOnly = settings
 
+    @Provides
+    @Singleton
+    fun provideEncryptedSettings(settings: EncryptedSettingsImpl): EncryptedSettings = settings
+
+    @Provides
+    @Singleton
+    // provide [EncryptedSettings] singleton itself as provided above to use same object
+    fun provideEncryptedSettingsReadOnly(settings: EncryptedSettings): EncryptedSettingsReadOnly = settings
+
     @Provides
     @Singleton
     @EventExecutor
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/Configuration.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/Configuration.kt
index aa042a5aa487757435932848e0a9db245c9525cb..c784324c0faf35b6a5d0adae8e7c7e741ae55e0e 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/Configuration.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/Configuration.kt
@@ -21,4 +21,4 @@ package org.briarproject.briar.desktop.settings
 import org.briarproject.bramble.api.FeatureFlags
 import org.briarproject.briar.desktop.DesktopFeatureFlags
 
-interface Configuration : UnencryptedSettingsReadOnly, FeatureFlags, DesktopFeatureFlags
+interface Configuration : UnencryptedSettingsReadOnly, EncryptedSettingsReadOnly, FeatureFlags, DesktopFeatureFlags
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/ConfigurationImpl.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/ConfigurationImpl.kt
index db7eabe9d80537dfa2efa114c5105d4aad78e913..bd5b019c4dc38b9adea65e285961cff3564f2e68 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/ConfigurationImpl.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/ConfigurationImpl.kt
@@ -25,9 +25,11 @@ import javax.inject.Inject
 class ConfigurationImpl
 @Inject internal constructor(
     unencryptedSettings: UnencryptedSettingsReadOnly,
+    encryptedSettings: EncryptedSettingsReadOnly,
     featureFlags: FeatureFlags,
     desktopFeatureFlags: DesktopFeatureFlags,
 ) : Configuration,
     UnencryptedSettingsReadOnly by unencryptedSettings,
+    EncryptedSettingsReadOnly by encryptedSettings,
     FeatureFlags by featureFlags,
     DesktopFeatureFlags by desktopFeatureFlags
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/EncryptedSettings.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/EncryptedSettings.kt
new file mode 100644
index 0000000000000000000000000000000000000000..441e1afd87937e3238e665dd122d9f96074b678e
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/EncryptedSettings.kt
@@ -0,0 +1,27 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2021-2022 The Briar Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.briarproject.briar.desktop.settings
+
+interface EncryptedSettingsReadOnly {
+    val showNotifications: Boolean
+}
+
+interface EncryptedSettings : EncryptedSettingsReadOnly {
+    override var showNotifications: Boolean
+}
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/EncryptedSettingsImpl.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/EncryptedSettingsImpl.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2645061fa19f01c0c16df44fe30f85213d162332
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/EncryptedSettingsImpl.kt
@@ -0,0 +1,52 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2021-2022 The Briar Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.briarproject.briar.desktop.settings
+
+import org.briarproject.bramble.api.lifecycle.IoExecutor
+import org.briarproject.bramble.api.lifecycle.LifecycleManager
+import org.briarproject.bramble.api.settings.Settings
+import org.briarproject.bramble.api.settings.SettingsManager
+import javax.inject.Inject
+
+const val SETTINGS_NAMESPACE = "desktop-ui" // NON-NLS
+
+const val PREF_NOTIFY = "notify" // NON-NLS
+
+class EncryptedSettingsImpl
+@Inject internal constructor(
+    private val settingsManager: SettingsManager,
+    lifecycleManager: LifecycleManager,
+) : EncryptedSettings {
+
+    init {
+        lifecycleManager.registerOpenDatabaseHook { txn ->
+            settings = settingsManager.getSettings(txn, SETTINGS_NAMESPACE)
+        }
+    }
+
+    private lateinit var settings: Settings
+
+    override var showNotifications: Boolean
+        get() = settings.getBoolean(PREF_NOTIFY, true)
+        @IoExecutor
+        set(value) {
+            settings.putBoolean(PREF_NOTIFY, value)
+            settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE)
+        }
+}
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingDetails.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingDetails.kt
index a4672d9cf77667716b85e01ba1fcbeaa1b3cdddf..46a4d3039bb4a0f65b4ae375e8724542eefb2a6a 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingDetails.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingDetails.kt
@@ -31,6 +31,7 @@ import androidx.compose.foundation.layout.widthIn
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.OutlinedButton
 import androidx.compose.material.OutlinedExposedDropDownMenu
+import androidx.compose.material.Switch
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
@@ -48,6 +49,7 @@ fun SettingDetails(viewModel: SettingsViewModel) {
         SettingCategory.GENERAL -> {
             SettingDetail(i18n("settings.general.title")) {}
         }
+
         SettingCategory.DISPLAY -> {
             // TODO: Change this to `settings.display.title` once more categories are implemented
             SettingDetail(i18n("settings.title")) {
@@ -97,17 +99,34 @@ fun SettingDetails(viewModel: SettingsViewModel) {
                         Text(i18n("settings.security.password.change"))
                     }
                 }
+
+                DetailItem(
+                    label = i18n("settings.notifications.title"),
+                    description = (
+                        if (viewModel.showNotifications.value) i18n("access.settings.currently_enabled")
+                        else i18n("access.settings.currently_disabled")
+                        ) + ". " + i18n("access.settings.click_to_toggle_notifications")
+                ) {
+                    Switch(
+                        checked = viewModel.showNotifications.value,
+                        onCheckedChange = { viewModel.toggleShowNotifications() }
+                    )
+                }
             }
         }
+
         SettingCategory.CONNECTIONS -> {
             SettingDetail(i18n("settings.connections.title")) {}
         }
+
         SettingCategory.SECURITY -> {
             SettingDetail(i18n("settings.security.title")) {}
         }
+
         SettingCategory.NOTIFICATIONS -> {
             SettingDetail(i18n("settings.notifications.title")) {}
         }
+
         SettingCategory.ACTIONS -> {
             SettingDetail(i18n("settings.actions.title")) {}
         }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingsViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingsViewModel.kt
index 982cb5e3218f218aa6ca57ee90377b00a5eb7ee2..fd81555f638a153c623755e32210aba155301c1d 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingsViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingsViewModel.kt
@@ -21,8 +21,10 @@ package org.briarproject.briar.desktop.settings
 import androidx.compose.runtime.mutableStateOf
 import org.briarproject.bramble.api.account.AccountManager
 import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator
+import org.briarproject.bramble.api.db.TransactionManager
+import org.briarproject.bramble.api.lifecycle.LifecycleManager
 import org.briarproject.briar.desktop.threading.BriarExecutors
-import org.briarproject.briar.desktop.viewmodel.ViewModel
+import org.briarproject.briar.desktop.viewmodel.DbViewModel
 import org.briarproject.briar.desktop.viewmodel.asState
 import javax.inject.Inject
 
@@ -39,10 +41,13 @@ class SettingsViewModel
 @Inject
 constructor(
     private val briarExecutors: BriarExecutors,
+    lifecycleManager: LifecycleManager,
+    db: TransactionManager,
     private val unencryptedSettings: UnencryptedSettings,
+    private val encryptedSettings: EncryptedSettings,
     private val accountManager: AccountManager,
     private val passwordStrengthEstimator: PasswordStrengthEstimator,
-) : ViewModel {
+) : DbViewModel(briarExecutors, lifecycleManager, db) {
     private val _selectedSetting = mutableStateOf(SettingCategory.DISPLAY)
     val selectedSetting = _selectedSetting.asState()
 
@@ -60,6 +65,9 @@ constructor(
 
     val changePasswordSubViewModel = ChangePasswordSubViewModel(accountManager, passwordStrengthEstimator)
 
+    private val _showNotifications = mutableStateOf(encryptedSettings.showNotifications)
+    val showNotifications = _showNotifications.asState()
+
     fun selectSetting(selectedOption: SettingCategory) {
         _selectedSetting.value = selectedOption
     }
@@ -81,4 +89,10 @@ constructor(
     fun dismissChangePasswordDialog() {
         _changePasswordDialogVisible.value = false
     }
+
+    fun toggleShowNotifications() {
+        val newValue = !_showNotifications.value
+        _showNotifications.value = newValue
+        runOnDbThread { encryptedSettings.showNotifications = newValue }
+    }
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
index 772973ce264e6a913d3ae780eb3a211f745a6329..7b8ca936ec15d1efa67d668f99c0aa39a4a7776d 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
@@ -147,7 +147,9 @@ constructor(
                             messageCount++
                             if (!focusState.focused) {
                                 window.iconImage = iconBadge
-                                notificationProvider.notifyPrivateMessages(messageCount)
+                                if (configuration.showNotifications) {
+                                    notificationProvider.notifyPrivateMessages(messageCount)
+                                }
                             }
                         }
 
diff --git a/briar-desktop/src/main/resources/strings/BriarDesktop.properties b/briar-desktop/src/main/resources/strings/BriarDesktop.properties
index c460e74194f8985c63e1c3d50cd42355e25118bb..8eeae493747783f22054504e90c4ce34addfc8c7 100644
--- a/briar-desktop/src/main/resources/strings/BriarDesktop.properties
+++ b/briar-desktop/src/main/resources/strings/BriarDesktop.properties
@@ -53,6 +53,10 @@ access.password.hide=Hide password
 access.settings.current_value=Current value
 access.settings.click_to_change_value=Click to change value
 access.settings.click_to_change_password=Click to change password
+access.settings.currently_enabled=Currently enabled
+access.settings.currently_disabled=Currently enabled
+access.settings.click_to_toggle_notifications=Click to toggle notifications
+
 access.return_to_previous_screen=Return to previous screen
 
 # Contacts
@@ -281,6 +285,7 @@ settings.security.password.changed=Password has been changed.
 
 # Settings Notifications
 settings.notifications.title=Notifications
+settings.notifications.show=Show Notifications
 
 # Settings Actions
 settings.actions.title=Actions
diff --git a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/DesktopTestModule.kt b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/DesktopTestModule.kt
index 84250542eccd0512a5e1bd50ac1308f8b0ffaa65..a043f8baa051d1b17dc41c42bd8eb76fe13a0ee6 100644
--- a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/DesktopTestModule.kt
+++ b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/DesktopTestModule.kt
@@ -58,6 +58,9 @@ import org.briarproject.briar.desktop.notification.StubNotificationProvider
 import org.briarproject.briar.desktop.notification.linux.LibnotifyNotificationProvider
 import org.briarproject.briar.desktop.settings.Configuration
 import org.briarproject.briar.desktop.settings.ConfigurationImpl
+import org.briarproject.briar.desktop.settings.EncryptedSettings
+import org.briarproject.briar.desktop.settings.EncryptedSettingsImpl
+import org.briarproject.briar.desktop.settings.EncryptedSettingsReadOnly
 import org.briarproject.briar.desktop.settings.UnencryptedSettings
 import org.briarproject.briar.desktop.settings.UnencryptedSettingsImpl
 import org.briarproject.briar.desktop.settings.UnencryptedSettingsReadOnly
@@ -123,6 +126,15 @@ internal class DesktopTestModule(
     @Singleton
     fun provideUnencryptedSettings(settings: UnencryptedSettingsImpl): UnencryptedSettings = settings
 
+    @Provides
+    @Singleton
+    fun provideEncryptedSettings(settings: EncryptedSettingsImpl): EncryptedSettings = settings
+
+    @Provides
+    @Singleton
+    // provide [EncryptedSettings] singleton itself as provided above to use same object
+    fun provideEncryptedSettingsReadOnly(settings: EncryptedSettings): EncryptedSettingsReadOnly = settings
+
     @Provides
     @Singleton
     @EventExecutor
diff --git a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/RunWithMultipleTemporaryAccounts.kt b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/RunWithMultipleTemporaryAccounts.kt
index d02435170631eeb81ef7709d9c1090ae8ac8a85c..6b391741d7b9522af969f6bfed950e9b703f02c9 100644
--- a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/RunWithMultipleTemporaryAccounts.kt
+++ b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/RunWithMultipleTemporaryAccounts.kt
@@ -19,9 +19,10 @@
 package org.briarproject.briar.desktop
 
 import androidx.compose.runtime.Composable
-import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.ui.window.ApplicationScope
 import androidx.compose.ui.window.application
+import kotlinx.coroutines.delay
 import mu.KotlinLogging
 import org.briarproject.bramble.BrambleCoreEagerSingletons
 import org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_CONTROL_PORT
@@ -44,7 +45,6 @@ internal class RunWithMultipleTemporaryAccounts(
 
     private val apps = mutableListOf<BriarDesktopTestApp>()
 
-    @OptIn(ExperimentalComposeUiApi::class)
     fun run() {
         LogUtils.setupLogging(ALL)
 
@@ -54,9 +54,21 @@ internal class RunWithMultipleTemporaryAccounts(
             apps.add(app)
         }
 
-        customization(apps)
-
         application {
+            LaunchedEffect(Unit) {
+                delay(500)
+
+                apps.forEach {
+                    val accountManager = it.getAccountManager()
+                    val lifecycleManager = it.getLifecycleManager()
+                    val dbKey = accountManager.databaseKey ?: throw AssertionError()
+                    lifecycleManager.startServices(dbKey)
+                    lifecycleManager.waitForStartup()
+                }
+
+                customization(apps)
+            }
+
             for (app in apps) {
                 start(app, this)
             }
@@ -82,17 +94,12 @@ internal class RunWithMultipleTemporaryAccounts(
         BrambleCoreEagerSingletons.Helper.injectEagerSingletons(app)
         BriarCoreEagerSingletons.Helper.injectEagerSingletons(app)
 
-        val lifecycleManager = app.getLifecycleManager()
         val accountManager = app.getAccountManager()
 
         @NonNls
         val password = "verySecret123!"
         accountManager.createAccount(name, password)
 
-        val dbKey = accountManager.databaseKey ?: throw AssertionError()
-        lifecycleManager.startServices(dbKey)
-        lifecycleManager.waitForStartup()
-
         return app
     }
 
diff --git a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/RunWithTemporaryAccount.kt b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/RunWithTemporaryAccount.kt
index 1b745e495e589ec0775988e4067b0b7bba9cad19..3905d354d3d4d20dff6db27ae8b5c123624f7bb7 100644
--- a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/RunWithTemporaryAccount.kt
+++ b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/RunWithTemporaryAccount.kt
@@ -18,8 +18,10 @@
 
 package org.briarproject.briar.desktop
 
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.window.application
+import kotlinx.coroutines.delay
 import mu.KotlinLogging
 import org.briarproject.bramble.BrambleCoreEagerSingletons
 import org.briarproject.briar.BriarCoreEagerSingletons
@@ -77,17 +79,21 @@ internal class RunWithTemporaryAccount(
             @NonNls
             val password = "verySecret123!"
             accountManager.createAccount("alice", password)
-
-            if (login) {
-                val dbKey = accountManager.databaseKey ?: throw AssertionError()
-                lifecycleManager.startServices(dbKey)
-                lifecycleManager.waitForStartup()
-            }
         }
 
-        customization(app)
-
         application {
+            LaunchedEffect(Unit) {
+                delay(500)
+
+                if (createAccount && login) {
+                    val dbKey = accountManager.databaseKey ?: throw AssertionError()
+                    lifecycleManager.startServices(dbKey)
+                    lifecycleManager.waitForStartup()
+
+                    customization(app)
+                }
+            }
+
             app.getBriarUi().start {
                 app.getBriarUi().stop()
                 exitApplication()