diff --git a/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py b/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
index 95118c912f9382dc2d9fd032b7d70211b5d5ec8f..f11e52baff63d43af941a5c468149974534747b9 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py
@@ -181,6 +181,12 @@ class Subtask(BasicCommon):
 class SubtaskStateLog(BasicCommon):
     """
     History of state changes on subtasks
+    This is now a very specific solution and based on what SOS communicated is what they are regularly interested in.
+    Maybe one or two additional log tables for other models are benefitial and should be added at some point.
+
+    Note that we could of course also log on the db level and there is also a variety of audit middlewares for Django
+    available to keep track of changes more generally: https://djangopackages.org/grids/g/model-audit/
+    This seems a bit overkill at the moment and we have to manage access to those logs etc., this needs tbd.
     """
     user = ForeignKey(User, null=False, editable=False, on_delete=PROTECT, help_text='The user who changed the state of the subtask.')
     user_identifier = CharField(null=False, editable=False, max_length=128, help_text='The ID of the user who changed the state of the subtask.')
diff --git a/SAS/TMSS/src/tmss/tmssapp/serializers/scheduling.py b/SAS/TMSS/src/tmss/tmssapp/serializers/scheduling.py
index 202f7f716fc4fa148df2bfd70837c1f5b0239f87..3967e8e168e5c28395f8db2b592bf001deddaa88 100644
--- a/SAS/TMSS/src/tmss/tmssapp/serializers/scheduling.py
+++ b/SAS/TMSS/src/tmss/tmssapp/serializers/scheduling.py
@@ -172,16 +172,19 @@ class SubtaskSerializerJSONeditorOnline(RelationalHyperlinkedModelSerializer):
             # todo: Shall we use one of the default templates for the init?
             logger.warning('Could not determine schema, hence no fancy JSON form. Expected for list view.')
 
+    # Intercept updates to also create a log entry
     def update(self, instance, validated_data):
-        user = self.context.get('request').user
-        log_entry = models.SubtaskStateLog(user=user,
-                                           user_identifier=user.email,
-                                           subtask=instance,
-                                           old_state=instance.state,
-                                           new_state=validated_data.get('state'))
-        log_entry.save()
-        super().update(instance, validated_data)
-        return instance
+        if instance.state is not None \
+                and validated_data.get('state') is not None \
+                and instance.state != validated_data.get('state'):
+            user = self.context.get('request').user
+            log_entry = models.SubtaskStateLog(user=user,
+                                               user_identifier=user.email,
+                                               subtask=instance,
+                                               old_state=instance.state,
+                                               new_state=validated_data.get('state'))
+            log_entry.save()
+        return super().update(instance, validated_data)
 
     class Meta:
         model = models.Subtask
diff --git a/SAS/TMSS/src/tmss/tmssapp/viewsets/scheduling.py b/SAS/TMSS/src/tmss/tmssapp/viewsets/scheduling.py
index 2277d1876454c13abd08b36e307d2591d4b657f7..8eb8e847c4e599521e5cb63cf2947ea26a05e9f9 100644
--- a/SAS/TMSS/src/tmss/tmssapp/viewsets/scheduling.py
+++ b/SAS/TMSS/src/tmss/tmssapp/viewsets/scheduling.py
@@ -43,6 +43,17 @@ class SubtaskStateViewSet(LOFARViewSet):
 
 
 class SubtaskStateLogViewSet(LOFARViewSet):
+
+    def get_queryset(self):
+        queryset = models.SubtaskStateLog.objects.all()
+
+        # query by subtask
+        subtask = self.request.query_params.get('subtask', None)
+        if subtask is not None:
+            return queryset.filter(subtask=subtask)
+
+        return queryset
+
     queryset = models.SubtaskStateLog.objects.all()
     serializer_class = serializers.SubtaskStateLogSerializer
 
diff --git a/SAS/TMSS/test/t_tmssapp_scheduling_functional.py b/SAS/TMSS/test/t_tmssapp_scheduling_functional.py
index 1c46c09ee95846377399d1b63c8f1c45e11e4bc1..480cdf15bc16690fd295667a8b259b096ceef9ae 100755
--- a/SAS/TMSS/test/t_tmssapp_scheduling_functional.py
+++ b/SAS/TMSS/test/t_tmssapp_scheduling_functional.py
@@ -378,6 +378,31 @@ class SubtaskTestCase(unittest.TestCase):
         self.assertTrue("ProtectedError" in str(response.content))
         GET_and_assert_expected_response(self, specifications_template_url, 200, stt_test_data)
 
+    def test_subtask_state_log_records(self):
+        st_test_data = test_data_creator.Subtask()
+
+        # POST new item, verify
+        r_dict = POST_and_assert_expected_response(self, BASE_URL + '/subtask/', st_test_data, 201, st_test_data)
+        url = r_dict['url']
+        GET_and_assert_expected_response(self, url, 200, st_test_data)
+
+        # Verify state log count is zero
+        segments = url.split('/')
+        identifier = ''
+        while identifier == '':
+            identifier = segments.pop()
+        GET_and_assert_expected_response(self, BASE_URL + '/subtask_state_log/?subtask=' + identifier, 200, {"count":0})
+
+        # PATCH item with something else than state and verify no log record is created
+        test_patch = {"specifications_doc": {"somespec": "somevalue"}}
+        PATCH_and_assert_expected_response(self, url, test_patch, 200, test_patch)
+        GET_and_assert_expected_response(self, BASE_URL + '/subtask_state_log/?subtask=' + identifier, 200, {"count": 0})
+
+        # PATCH item with state update and verify log record is created
+        test_patch = {"state": BASE_URL + "/subtask_state/finishing/"}
+        PATCH_and_assert_expected_response(self, url, test_patch, 200, test_patch)
+        GET_and_assert_expected_response(self, BASE_URL + '/subtask_state_log/?subtask=' + identifier, 200, {"count": 1})
+
 
 class DataproductTestCase(unittest.TestCase):
     @classmethod