diff --git a/atdb/atdb/settings/base.py b/atdb/atdb/settings/base.py
index 79d03f49dd38ad97a54c444e99d91a0098e04ea4..52dcb06fd829093025ad6f689324e43f02ceaa72 100644
--- a/atdb/atdb/settings/base.py
+++ b/atdb/atdb/settings/base.py
@@ -198,4 +198,6 @@ ACTIVE_STATUSSES = ['staging','staged','processing','processed','validated','sto
 STATUSSES_WITH_DATA = ['staged','fetching','fetched','processing','processed','validated','storing','stored','scrubbing','scrubbed','archiving','archived']
 AGGREGATES = ['failed','active','total']
 
-QUERY_LIMIT_MULTI_CHANGE = 1000
\ No newline at end of file
+QUERY_LIMIT_MULTI_CHANGE = 1000
+MAX_MONITORING_HISTORY_HOURS = 7 * 24
+SERVICES_LATE_WARNING_SECONDS = 1800
\ No newline at end of file
diff --git a/atdb/atdb/static/taskdatabase/style.css b/atdb/atdb/static/taskdatabase/style.css
index abaa979356a70d6a40c5ffac12ca958ef50d26c4..86e9ac908dc232210c22807bcabfd36f7bd2efe7 100644
--- a/atdb/atdb/static/taskdatabase/style.css
+++ b/atdb/atdb/static/taskdatabase/style.css
@@ -34,7 +34,7 @@ TD {
 }
 
 
-.error,.failed,.staging_failed,.staged_failed,.processed_failed,.scrubbed_failed,.stored_failed,.archived_failed {
+.error,.failed,.staging_failed,.staged_failed,.processed_failed,.scrubbed_failed,.stored_failed,.archived_failed,.on_hold {
   color: red;
   font-weight: bold;
 }
diff --git a/atdb/taskdatabase/models.py b/atdb/taskdatabase/models.py
index 3a770aa02f4adf7425479d30d119969050e06e71..60ede446eadfeb294007b3cdbd8f417fcb457fc1 100644
--- a/atdb/taskdatabase/models.py
+++ b/atdb/taskdatabase/models.py
@@ -1,6 +1,8 @@
 from django.db import models
 from django.urls import reverse
-from django.utils.timezone import datetime
+from django.utils import timezone
+from django.utils.timezone import datetime, timedelta
+from django.conf import settings
 
 # constants
 datetime_format_string = '%Y-%m-%dT%H:%M:%SZ'
@@ -226,11 +228,31 @@ class LatestMonitor(models.Model):
     status = models.CharField(max_length=50, default="ok", null=True)
     metadata = models.JSONField(null=True, blank=True)
 
+    @property
+    def enabled(self):
+        try:
+            enabled = self.metadata['enabled']
+            return enabled
+        except:
+            # only when metadata['enabled']=False' this will be register as false.
+            # to make sure that services are enabled by default
+            return "True"
+
     # the representation of the value in the REST API
     def __str__(self):
         return str(self.name) + ' - ('+ self.hostname+') - '+str(self.timestamp) + ' - ' + self.status
 
 
+def purge_old_records():
+    current_time = timezone.now()  # change this
+    try:
+        time_threshold = current_time - timedelta(hours=settings.MAX_MONITORING_HISTORY_HOURS)
+        records_to_delete = Monitor.objects.filter(timestamp__lt=time_threshold).delete()
+    except Exception as e:
+        # if MAX_MONITORING_HISTORY_HOURS is not set, then do nothing and continue
+        pass
+
+
 class Monitor(models.Model):
     name = models.CharField(max_length=50, default="unknown")
     type = models.CharField(max_length=20, default="ldv-service", null=True, blank=True)
@@ -246,11 +268,20 @@ class Monitor(models.Model):
         # in the LatestMonitor, and update if it is newer.
         try:
             latestMonitor = LatestMonitor.objects.get(name=self.name,hostname=self.hostname)
+            # carry over the metadata, if possible
+            latest_metadata = latestMonitor.metadata
             latestMonitor.delete()
         except:
             pass
 
         # this combination of name and hostname didn't yet exist, create it.
+        metadata = self.metadata
+        try:
+            if latest_metadata:
+                metadata = latest_metadata
+        except:
+            pass
+
         latestMonitor = LatestMonitor(
             name=self.name,
             type=self.type,
@@ -259,13 +290,16 @@ class Monitor(models.Model):
             process_id = self.process_id,
             description = self.description,
             status = self.status,
-            metadata = self.metadata
+            metadata = metadata
         )
         latestMonitor.save()
 
         # finally save the Monitor info itself also
         super(Monitor, self).save(*args, **kwargs)
 
+        # and purge the monitoring table to its max
+        purge_old_records()
+
     # the representation of the value in the REST API
     def __str__(self):
         return str(self.name) + ' - ('+ self.hostname+') - '+str(self.timestamp) + ' - ' + self.status
diff --git a/atdb/taskdatabase/services/algorithms.py b/atdb/taskdatabase/services/algorithms.py
index 0fa1fce7ed1fe033353a16efb482646959a2845c..62fe1b7ba12196b4e00d31f296496ebbf1805db9 100644
--- a/atdb/taskdatabase/services/algorithms.py
+++ b/atdb/taskdatabase/services/algorithms.py
@@ -9,10 +9,6 @@ from django.db.models import Q, Sum
 import logging
 from .common import timeit
 
-from urllib.request import urlopen
-from django.core.files import File
-from django.core.files.temp import NamedTemporaryFile
-
 from ..models import Task, LogEntry, Workflow, Configuration
 from django.conf import settings
 
@@ -288,19 +284,31 @@ def convert_monitor_to_html(request, monitor_data):
             line += "<td><b>" + link_to_service_history + "</b></td>"
             line += "<td>" + str(record.hostname) + "</td>"
 
+            # only provide the hold/resume buttons for superusers, otherwise just show the state
+            if request.user.is_superuser:
+                if record.enabled=="True":
+                    service_enabled = str(record.enabled) + '&nbsp;&nbsp; <a href="service_hold_resume/' + str(record.pk) + '/False"' + 'class="btn btn-warning btn-sm" role="button"><i class="fas fa-pause"></i> Hold</a>'
+                else:
+                    service_enabled = str(record.enabled) + '&nbsp;&nbsp; <a href="service_hold_resume/' + str(record.pk) + '/True"' + 'class="btn btn-success btn-sm" role="button"><i class="fas fa-play"></i> Resume</a>'
+            else:
+                service_enabled = str(record.enabled)
+
             # if the heartbeat is 30 minutes late, show '(late)' in red
-            if delta.seconds > 1800:
+            if delta.seconds > settings.SERVICES_LATE_WARNING_SECONDS:
+                line += "<td>" + service_enabled + "</td>"
                 line += "<td><i>unknown</i></td>"
                 line += '<td class="error">' + str(record.timestamp.strftime(TIME_FORMAT)) + " - (late)</td>"
             else:
+                line += "<td>" + service_enabled + "</td>"
                 line += '<td class="' + record.status + '" >' + str(record.status) + "</td>"
                 line += '<td>' + str(record.timestamp.strftime(TIME_FORMAT)) + "</td>"
+
             line += "<td>" + str(record.process_id) + "</td>"
             line += "<td>" + str(record.description) + "</td>"
             line += "</tr>"
 
             results = results + line
-    except:
+    except Exception as e:
         results = "<tr><td>no data</td></tr>"
 
     return results
diff --git a/atdb/taskdatabase/static/taskdatabase/style.css b/atdb/taskdatabase/static/taskdatabase/style.css
index abaa979356a70d6a40c5ffac12ca958ef50d26c4..86e9ac908dc232210c22807bcabfd36f7bd2efe7 100644
--- a/atdb/taskdatabase/static/taskdatabase/style.css
+++ b/atdb/taskdatabase/static/taskdatabase/style.css
@@ -34,7 +34,7 @@ TD {
 }
 
 
-.error,.failed,.staging_failed,.staged_failed,.processed_failed,.scrubbed_failed,.stored_failed,.archived_failed {
+.error,.failed,.staging_failed,.staged_failed,.processed_failed,.scrubbed_failed,.stored_failed,.archived_failed,.on_hold {
   color: red;
   font-weight: bold;
 }
diff --git a/atdb/taskdatabase/templates/taskdatabase/index.html b/atdb/taskdatabase/templates/taskdatabase/index.html
index 36cbd2dd4c658906d7831f7b8a455375c496df71..ea9b66c7a793f2c60bdadef8bacaf840acc6383d 100644
--- a/atdb/taskdatabase/templates/taskdatabase/index.html
+++ b/atdb/taskdatabase/templates/taskdatabase/index.html
@@ -34,7 +34,7 @@
         {% include 'taskdatabase/pagination.html' %}
        </div>
     </div>
-    <p class="footer"> Version 1.0.0 (14 apr 2021 - 13:00)
+    <p class="footer"> Version 1.0.0 (21 apr 2021 - 13:00)
 
 </div>
 
diff --git a/atdb/taskdatabase/templates/taskdatabase/monitoring_page.html b/atdb/taskdatabase/templates/taskdatabase/monitoring_page.html
index 6b85c675e86ef472209e1402525f456b39e13d76..0679ca228746b005a9a786f5c9139dcf07052ba3 100644
--- a/atdb/taskdatabase/templates/taskdatabase/monitoring_page.html
+++ b/atdb/taskdatabase/templates/taskdatabase/monitoring_page.html
@@ -22,7 +22,7 @@
               </p>
               {% endif %}
                <table class="table table-striped">
-                   <th>LDV-Service</th><th>Host</th><th>Status</th><th>Timestamp</th><th>Process id</th><th>Description</th>
+                   <th>LDV-Service</th><th>Host</th><th>Enabled</th><th>Last Status</th><th>Timestamp</th><th>Process id</th><th>Description</th>
                    <tbody>
                       {{ monitor_results | safe }}
                     </tbody>
diff --git a/atdb/taskdatabase/urls.py b/atdb/taskdatabase/urls.py
index d950d86cf0e76e08b1188b68f26d42bc2d5bd722..e55c0c0335c99b9232cddff67cd81f3287ef90ad 100644
--- a/atdb/taskdatabase/urls.py
+++ b/atdb/taskdatabase/urls.py
@@ -72,7 +72,7 @@ urlpatterns = [
     path('monitor/<int:pk>/', views.MonitorDetailsViewAPI.as_view(),name='monitor-detail-view-api'),
     path('latest_monitor/', views.LatestMonitorListViewAPI.as_view(),name='latest-monitor-detail-view-api'),
     path('monitor/clear_inactive_services/', views.ClearInactiveServices, name='clear-inactive-services'),
-
+    path('monitoring/service_hold_resume/<int:pk>/<enabled>', views.ServiceHoldResume, name='service-hold-resume'),
 
     # --- custom requests ---
     # /atdb/get_size?status__in=defined,staged
@@ -108,5 +108,7 @@ urlpatterns = [
     path('tasks/<int:pk>/hold/<hold_it>', views.Hold, name='task-hold-resume'),
     path('tasks/<int:pk>/query-hold/<hold_it>/<query_params>', views.HoldQuery, name='query-hold-resume'),
 
+    path('tasks/<int:pk>/hold/<hold_it>/<page>', views.Hold, name='service-hold-resume'),
+
     path('hello/', views.HelloView.as_view(), name='hello'),
 ]
diff --git a/atdb/taskdatabase/views.py b/atdb/taskdatabase/views.py
index 654b8cd028f96c4d344d4015ddba8e2e1a01f3b0..f6775feb55ce896ef2825ff784c385ea40897c7e 100644
--- a/atdb/taskdatabase/views.py
+++ b/atdb/taskdatabase/views.py
@@ -6,7 +6,6 @@ from django.contrib.auth.decorators import login_required
 
 from django.views.generic import ListView
 from django.contrib import messages
-from django.http import QueryDict
 
 from rest_framework import generics, pagination
 from rest_framework.response import Response
@@ -41,7 +40,6 @@ from .serializers import \
     PostProcessingRuleSerializer, \
     MonitorSerializer, LatestMonitorSerializer
 
-
 from .services import algorithms
 
 logger = logging.getLogger(__name__)
@@ -156,6 +154,15 @@ class MonitorFilter(filters.FilterSet):
             'timestamp': ['icontains'],
         }
 
+class LatestMonitorFilter(filters.FilterSet):
+    class Meta:
+        model = LatestMonitor
+
+        fields = {
+            'name': ['exact', 'icontains', 'in'],
+            'hostname': ['exact', 'icontains', 'in'],
+        }
+
 # ---------- Tables2 Views (experimental) -----------
 class QueryView(SingleTableMixin, FilterView):
     table_class = TaskTable
@@ -903,7 +910,7 @@ class LatestMonitorListViewAPI(generics.ListCreateAPIView):
     serializer_class = LatestMonitorSerializer
 
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_class = MonitorFilter
+    filter_class = LatestMonitorFilter
 
 
 @login_required
@@ -945,6 +952,19 @@ def HoldQuery(request, pk, hold_it, query_params):
     current_query_params = convert_query_params_to_url(query_params)
     return redirect('/atdb/query/?' + current_query_params)
 
+@login_required
+def ServiceHoldResume(request, pk, enabled):
+    model = LatestMonitor
+    service = LatestMonitor.objects.get(pk=pk)
+    metadata = service.metadata
+    if not metadata:
+        metadata = {}
+
+    metadata['enabled'] = enabled
+    service.metadata = metadata
+    service.save()
+    return redirect('/atdb/monitoring')
+
 
 @login_required
 def TaskSetStatus(request, pk, new_status, page=0):