diff --git a/reviewboard/attachments/apps.py b/reviewboard/attachments/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..9ae7d5360366032c469afe580ba32fafc0791fad
--- /dev/null
+++ b/reviewboard/attachments/apps.py
@@ -0,0 +1,29 @@
+"""The app definition for reviewboard.attachments.
+
+Version Added:
+    6.0
+"""
+
+from __future__ import annotations
+
+from django.apps import AppConfig
+
+
+class AttachmentsAppConfig(AppConfig):
+    """App configuration for reviewboard.attachments.
+
+    Version Added:
+        6.0
+    """
+
+    name = 'reviewboard.attachments'
+
+    def ready(self) -> None:
+        """Configure the app once it's ready.
+
+        This will connect signal handlers for the app.
+        """
+        from reviewboard.attachments.signal_handlers import \
+            connect_signal_handlers
+
+        connect_signal_handlers()
diff --git a/reviewboard/attachments/signal_handlers.py b/reviewboard/attachments/signal_handlers.py
new file mode 100644
index 0000000000000000000000000000000000000000..751d498f79e42b2440c5168441f7c3785643f222
--- /dev/null
+++ b/reviewboard/attachments/signal_handlers.py
@@ -0,0 +1,54 @@
+"""Signal handlers for file attachments.
+
+Version Added:
+    6.0
+"""
+
+from __future__ import annotations
+
+from typing import Type
+
+from django.db.models.signals import pre_delete
+
+from reviewboard.attachments.models import FileAttachment
+
+
+def _on_file_attachment_deleted(
+    sender: Type[FileAttachment],
+    instance: FileAttachment,
+    using: str,
+    **kwargs,
+) -> None:
+    """Handle any extra cleanup when a file attachment is deleted.
+
+    This will ensure that any files associated with the file attachment
+    are removed from the filesystem.
+
+    Version Added:
+        6.0
+
+    Args:
+        sender (type, unused):
+            The sender of the signal.
+
+        instance (reviewboard.attachments.models.FileAttachment):
+            The file attachment being deleted.
+
+        using (str, unused):
+            The database alias being used.
+
+        **kwargs (dict, unused):
+            Unused additional keyword arguments.
+    """
+    instance.mimetype_handler.delete_associated_files()
+    instance.file.delete(save=False)
+
+
+def connect_signal_handlers() -> None:
+    """Connect file attachment related signal handlers.
+
+    Version Added:
+        6.0
+    """
+    pre_delete.connect(_on_file_attachment_deleted,
+                       sender=FileAttachment)
