diff --git a/app/admin/views.py b/app/admin/views.py
index 6358167fb0393b696784a44651822cc219f388fe..6879fc955fb6483b5c42f1e1b65605b3dba7cf58 100644
--- a/app/admin/views.py
+++ b/app/admin/views.py
@@ -2,13 +2,13 @@ from flask import (abort, current_app, flash, redirect, request,
                    render_template, url_for, send_from_directory)
 from flask_login import current_user, login_required
 from .forms import EditProfileAdminForm
-from ..models import Corpus, User, Role
+from ..models import Corpus, User, Role, Job
 from ..tables import AdminUserTable, AdminUserItem
 from . import admin
 from ..decorators import admin_required
 from .. import db
-import os
-import datetime
+import threading
+from app.utils import background_delete_user
 
 
 @admin.route('/overview', methods=['GET', 'POST'])
@@ -40,9 +40,10 @@ def admin_user_page(user_id):
 @login_required
 @admin_required
 def admin_delete_user(user_id):
-    selected_user = User.query.filter_by(id=user_id).first()
-    db.session.delete(selected_user)
-    db.session.commit()
+    delete_thread = threading.Thread(target=background_delete_user,
+                                     args=(current_app._get_current_object(),
+                                           user_id))
+    delete_thread.start()
     flash('User {} has been deleted!'.format(user_id))
     return redirect(url_for('admin.for_admins_only'))
 
diff --git a/app/auth/views.py b/app/auth/views.py
index dd327cfb3bebb07a94357262fd16d9e624e2047b..ade9435702b363e20c45f37eefec61d8956b69dd 100644
--- a/app/auth/views.py
+++ b/app/auth/views.py
@@ -6,9 +6,9 @@ from .. import db
 from .forms import (ChangePasswordForm, LoginForm, PasswordResetForm,
                     PasswordResetRequestForm, RegistrationForm, EditProfileForm)
 from ..email import send_email
-from ..models import User, Job
-import logging
+from ..models import User
 import threading
+from app.utils import background_delete_user
 
 
 @auth.route('/login', methods=['GET', 'POST'])
@@ -169,30 +169,10 @@ def settings():
 @auth.route('/settings/delete_self', methods=['GET', 'POST'])
 @login_required
 def delete_self():
-    logger = logging.getLogger(__name__)
-
-    def background_delete(app, current_user_id):
-        with app.app_context():
-            logger.warning('Called by delete_thread.')
-            logger.warning('User id is: {}.'.format(current_user_id))
-            jobs = Job.query.join(User).filter_by(id=current_user_id).all()
-            logger.warning('Jobs to delete are: {}'.format(jobs))
-            for job in jobs:
-                job.flag_for_stop()
-                logger.warning('Job status: {}'.format(job.status))
-                deleted = False
-                while deleted is False:
-                    db.session.refresh(job)
-                    if job.status == 'deleted':
-                        logger.warning('Job status is deleted.')
-                        job.delete_job()
-                        deleted = True
-
-    delete_thread = threading.Thread(target=background_delete,
+    delete_thread = threading.Thread(target=background_delete_user,
                                      args=(current_app._get_current_object(),
                                            current_user.id))
     delete_thread.start()
-    db.session.delete(current_user)
-    db.session.commit()
+    logout_user()
     flash('Your account has been deleted!')
     return redirect(url_for('main.index'))
diff --git a/app/main/views.py b/app/main/views.py
index 51ba514ecbe4689c3716a7015c62e86119e09897..13a64be3b6cab8db5fb20d92932cb0823edde1da 100644
--- a/app/main/views.py
+++ b/app/main/views.py
@@ -8,6 +8,7 @@ from ..models import Corpus, Job
 import os
 import logging
 import threading
+from app.utils import background_delete_job
 
 
 @main.route('/')
@@ -144,28 +145,9 @@ def job_download(job_id):
 @main.route('/jobs/<int:job_id>/delete')
 @login_required
 def delete_job(job_id):
-    logger = logging.getLogger(__name__)
-
-    def background_delete(job_id, app):
-        with app.app_context():
-            logger.warning('Called by delete_thread.')
-            logger.warning('Job id is: {}.'.format(job_id))
-            job = Job.query.filter_by(id=job_id).first()
-            logger.warning('Job object is: {}'.format(job))
-            logger.warning('Job status: {}'.format(job.status))
-            job.flag_for_stop()
-            logger.warning('Job status: {}'.format(job.status))
-            deleted = False
-            while deleted is False:
-                db.session.refresh(job)
-                if job.status == 'deleted':
-                    logger.warning('Job status is deleted.')
-                    job.delete_job()
-                    deleted = True
-
-    delete_thread = threading.Thread(target=background_delete,
-                                     args=(job_id,
-                                           current_app._get_current_object()))
+    delete_thread = threading.Thread(target=background_delete_job,
+                                     args=(current_app._get_current_object(),
+                                           job_id))
     delete_thread.start()
     flash('Job has been deleted!')
     return redirect(url_for('main.dashboard'))
diff --git a/app/models.py b/app/models.py
index 3d4d4f0b72b74e52efc578d67aabfe0a4162b060..8bf8481f718ed89b5e6d1dab829e6603150ef008 100644
--- a/app/models.py
+++ b/app/models.py
@@ -220,13 +220,21 @@ class User(UserMixin, db.Model):
             jobs[str(job.id)] = job.to_dict()
         return jobs
 
-    def delete_user(self, user_id):
+    def delete_user(self):
         """
         Delete user from database. Also delete all associated jobs and corpora
         files.
         """
-        user = User.query.filter_by(user_id=user_id)
-        db.session.delete(user)
+        logger = logging.getLogger(__name__)
+        delete_path = os.path.join('/mnt/opaque/', str(self.id))
+        logger.warning('Delete path for user is: {}'.format(delete_path))
+        while os.path.exists(delete_path):
+            try:
+                shutil.rmtree(delete_path, ignore_errors=True)
+                logger.warning('Path does still exist.')
+            except OSError:
+                pass
+        db.session.delete(self)
         db.session.commit()
 
 
diff --git a/app/templates/auth/settings.html.j2 b/app/templates/auth/settings.html.j2
index bb2b533d72a2bf848ec4a8fa0c6d6282a25b82af..ab4dff9a806a3095fb620d81547ed73e5213ad68 100644
--- a/app/templates/auth/settings.html.j2
+++ b/app/templates/auth/settings.html.j2
@@ -85,6 +85,7 @@
           <h4>Confirm deletion</h4>
             <p>
               Do you really want to delete your account and all associated data?
+              All associated jobs and job files will be permanently deleted!
             </p>
         </div>
         <div class="modal-footer">
diff --git a/app/utils.py b/app/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..eb2d1ea43e6c88ae86e671287409d45ebd69dc35
--- /dev/null
+++ b/app/utils.py
@@ -0,0 +1,53 @@
+from .models import Job, User
+from . import db
+import logging
+
+
+'''
+' A list of background process functions. Functions should be called using the
+  Thread class from the module threading.
+'''
+
+
+def background_delete_user(app, current_user_id):
+    with app.app_context():
+        logger = logging.getLogger(__name__)
+        logger.warning('Called by delete_thread.')
+        logger.warning('User id is: {}.'.format(current_user_id))
+        jobs = Job.query.filter_by(user_id=current_user_id).all()
+        logger.warning('Jobs to delete are: {}'.format(jobs))
+        user = User.query.get_or_404(current_user_id)
+        for job in jobs:
+            job.flag_for_stop()
+            logger.warning('Job status: {}'.format(job.status))
+            deleted = False
+            while deleted is False:
+                logger.warning('Refreshing')
+                db.session.refresh(job)
+                logger.warning('Refreshed')
+                if job.status == 'deleted':
+                    logger.warning('Job status is deleted.')
+                    job.delete_job()
+                    deleted = True
+            logger.warning('Loop has ended.')
+        user.delete_user()
+
+
+def background_delete_job(app, job_id):
+    logger = logging.getLogger(__name__)
+    with app.app_context():
+        logger.warning('Called by delete_thread.')
+        logger.warning('Job id is: {}.'.format(job_id))
+        job = Job.query.filter_by(id=job_id).first()
+        logger.warning('Job object is: {}'.format(job))
+        logger.warning('Job status: {}'.format(job.status))
+        job.flag_for_stop()
+        logger.warning('Job status: {}'.format(job.status))
+        deleted = False
+        while deleted is False:
+            db.session.refresh(job)
+            if job.status == 'deleted':
+                logger.warning('Job status is deleted.')
+                job.delete_job()
+                deleted = True
+        logger.warning('Loop has ended.')