diff --git a/beat/web/backend/schedule.py b/beat/web/backend/schedule.py
index 5c01231366cf60f211fce3aec34d5e7fe195e849..72d88b2c280c18b19a435f090249b4b2c2ca4deb 100644
--- a/beat/web/backend/schedule.py
+++ b/beat/web/backend/schedule.py
@@ -90,17 +90,6 @@ def _select_splits_for_queue(queue):
     return splits_to_consider[:queue.availability()]
 
 
-@transaction.atomic
-def send_experiment_emails():
-    '''Sends experiment e-mails for experiments that just finished'''
-
-    from ..experiments.models import Experiment
-
-    qs = Experiment.objects.select_for_update().filter(email_dispatch=True)
-    for k in qs: k.email()
-    qs.update(email_dispatch=False)
-
-
 def schedule():
     '''Schedules job splits that can run now, respecting user/queue usage
 
diff --git a/beat/web/backend/views.py b/beat/web/backend/views.py
index c3bac6c255044f1eb283e18c8714e413dcddb5e9..c846b0791180e3a846447e6c56f7ebede98b02bf 100644
--- a/beat/web/backend/views.py
+++ b/beat/web/backend/views.py
@@ -131,7 +131,6 @@ def scheduler(request):
         activity = request.GET['activity']
 
         if activity in ('both', 'schedule'):
-            schedule.send_experiment_emails()
             splits = schedule.schedule()
             if splits:
                 logger.info("Scheduler assigned %d splits", len(splits))
diff --git a/beat/web/experiments/migrations/0002_scheduler_addons.py b/beat/web/experiments/migrations/0002_scheduler_addons.py
index 76ea88b379d5bc957f68295bb3ee4910581dfb30..5e3cd961acd49497645a37a41b6ed91d0c1cbe5c 100644
--- a/beat/web/experiments/migrations/0002_scheduler_addons.py
+++ b/beat/web/experiments/migrations/0002_scheduler_addons.py
@@ -234,11 +234,6 @@ class Migration(migrations.Migration):
     ]
 
     operations = [
-        migrations.AddField(
-            model_name='experiment',
-            name='email_dispatch',
-            field=models.BooleanField(default=False),
-        ),
         migrations.AddField(
             model_name='result',
             name='cache',
diff --git a/beat/web/experiments/models.py b/beat/web/experiments/models.py
index 8001c7122dc9056d4947087cc55f321622f6a4e8..6114d2944d25fe6a86c1f888d74bb04e2b831fad 100644
--- a/beat/web/experiments/models.py
+++ b/beat/web/experiments/models.py
@@ -232,7 +232,6 @@ class Experiment(Shareable):
     creation_date     = models.DateTimeField(null=True, blank=True, auto_now_add=True)
     start_date        = models.DateTimeField(null=True, blank=True)
     end_date          = models.DateTimeField(null=True, blank=True)
-    email_dispatch    = models.BooleanField(default=False)
 
     declaration_file = models.FileField(
                                 storage=DeclarationStorage(),
@@ -410,7 +409,7 @@ class Experiment(Shareable):
 
         if not is_adding and self._loaded_status != self.status:
             if self.status in [Experiment.DONE, Experiment.FAILED]:
-                self.email_dispatch = True
+                self.email()
 
         # Invoke the base implementation
         super(Experiment, self).save(*args, **kwargs)
diff --git a/beat/web/scripts/scheduler.py b/beat/web/scripts/scheduler.py
index d85e6e8b3c27a0979a365d989db18d68049d208b..fdf56ffb37ea0c547b4a3ca6ca37002123f8caa7 100644
--- a/beat/web/scripts/scheduler.py
+++ b/beat/web/scripts/scheduler.py
@@ -111,7 +111,6 @@ def main(user_input=None):
 
         start = time.time()
         logger.debug("Starting scheduler cycle...")
-        schedule.send_experiment_emails()
         schedule.schedule()
         duration = time.time() - start
         if duration < timing:
diff --git a/doc/admin/installation.rst b/doc/admin/installation.rst
index e7f1dc56581f3742dfaa7fafbef192c4c8b8b9f8..c540013da0b2f31654e6c5c1a0cb1d0f74de4be3 100644
--- a/doc/admin/installation.rst
+++ b/doc/admin/installation.rst
@@ -379,14 +379,10 @@ concerning these. We provide only some tips which we consider important:
 
     * E-mail privileges: e-mailing maybe configured as part of the Django_
       standard logging facilities or used to report experiment completion and
-      other platform activity. Not all node types require access to an e-mail
-      server:
-
-      - The web server may send e-mails and needs access to a server
-
-      - The scheduler process may send e-mails and needs access to a server
-
-      - The worker may send e-mails and needs access to a server
+      other platform activity. While, by default, all node types have access to
+      Django the configuration and can potentially send e-mails, it is wiser to
+      use a Django extension such as Post-office_ to centralize e-mail sending
+      to one node, avoiding potential spam.
 
     * User processes: user code is run in isolated processes launched by the
       children of worker processes. Because the user code process does not
@@ -581,3 +577,4 @@ page`_.
 .. _our gitlab page: https://gitlab.idiap.ch/beat/beat.web/issues
 .. _bower: http://bower.io
 .. _support: https://www.beat-eu.org/platform/contact/
+.. _post-office: https://pypi.python.org/pypi/django-post_office
diff --git a/todo.rst b/todo.rst
index 8602654cc27cde2af0c0c6a8b01a11a5dcfae3a5..edef05144ccdadc4c49325046b14ec00d0618a8e 100644
--- a/todo.rst
+++ b/todo.rst
@@ -64,5 +64,4 @@ Experiments
 Backend
 -------
 
-* Add proper e-mail queueing support
 * Support for launching user process under a different user name