diff --git a/SAS/TMSS/backend/services/scheduling/lib/constraints.py b/SAS/TMSS/backend/services/scheduling/lib/constraints.py
index 147ea15970ca20adfece81da41e275e58c651df1..26c2813a3ea76002cd58ae2822ad4e8eb1610ed1 100644
--- a/SAS/TMSS/backend/services/scheduling/lib/constraints.py
+++ b/SAS/TMSS/backend/services/scheduling/lib/constraints.py
@@ -407,7 +407,10 @@ def filter_scheduling_units_which_can_only_run_in_this_window(scheduling_units:
             logger.exception(e)
 
     _method_elapsed = datetime.utcnow() - _method_start_timestamp
-    logger.info("filter_scheduling_units_which_can_only_run_in_this_window: filtered %d units of which %s are runnable exclusively in window ['%s', '%s'] (took %.1f[s])", len(scheduling_units), len(runnable_exclusive_in_this_window_scheduling_units), lower_bound, upper_bound, _method_elapsed.total_seconds())
+    if runnable_exclusive_in_this_window_scheduling_units:
+        logger.info("filter_scheduling_units_which_can_only_run_in_this_window: filtered %d units of which %s are runnable exclusively in window ['%s', '%s'] (took %.1f[s])", len(scheduling_units), len(runnable_exclusive_in_this_window_scheduling_units), lower_bound, upper_bound, _method_elapsed.total_seconds())
+    else:
+        logger.info("filter_scheduling_units_which_can_only_run_in_this_window: all %d units can run outside of window ['%s', '%s'] (took %.1f[s])", len(scheduling_units), lower_bound, upper_bound, _method_elapsed.total_seconds())
 
     return runnable_exclusive_in_this_window_scheduling_units
 
@@ -1862,7 +1865,7 @@ def get_weighted_start_time(scheduling_unit: models.SchedulingUnitBlueprint, low
             weighted_start_time = round_to_second_precision(weighted_start_time)
 
             if can_run_at(scheduling_unit, weighted_start_time, gridder):
-                logger.info("get_weighted_start_time: SUB id=%s  weighted='%s'  -  weight=%.3f earliest='%s' optimal='%s' latest='%s'  -  window=['%s', '%s']", scheduling_unit.id, weighted_start_time, density_vs_optimal.weight, earliest_possible_start_time, optimal_start_time, latest_possible_start_time, lower_bound, upper_bound)
+                logger.debug("get_weighted_start_time: SUB id=%s  weighted='%s'  -  weight=%.3f earliest='%s' optimal='%s' latest='%s'  -  window=['%s', '%s']", scheduling_unit.id, weighted_start_time, density_vs_optimal.weight, earliest_possible_start_time, optimal_start_time, latest_possible_start_time, lower_bound, upper_bound)
                 return weighted_start_time
 
         logger.info("get_weighted_start_time: SUB id=%s returning earliest='%s'  -  window=['%s', '%s']", scheduling_unit.id, earliest_possible_start_time, lower_bound, upper_bound)
diff --git a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
index 87c3ffc97acd4ed89ea51caeb5e20cc8543bec9c..e43768f0fe9f0b97f0be030a552f7a0133e3e011 100644
--- a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
+++ b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
@@ -56,7 +56,7 @@ from datetime import datetime, timedelta, time
 
 from lofar.sas.tmss.tmss.tmssapp import models
 from lofar.sas.tmss.tmss.tmssapp.tasks import schedule_independent_subtasks_in_scheduling_unit_blueprint, unschedule_subtasks_in_scheduling_unit_blueprint, mark_independent_subtasks_in_scheduling_unit_blueprint_as_unschedulable, mark_independent_subtasks_in_scheduling_unit_blueprint_as_schedulable, mark_independent_subtasks_in_scheduling_unit_blueprint_as_schedulable, set_scheduling_unit_blueprint_start_times, reschedule_subtasks_in_scheduling_unit_blueprint, get_gaps_to_previous_and_next_observations_in_scheduling_unit
-from lofar.sas.tmss.tmss.tmssapp.subtasks import update_subtasks_start_times_for_scheduling_unit, cancel_subtask, mark_subtasks_and_successors_as_defined, get_gaps_between_scheduled_units_in_window
+from lofar.sas.tmss.tmss.tmssapp.subtasks import update_subtasks_start_times_for_scheduling_unit, cancel_subtask, mark_subtasks_and_successors_as_defined, get_gaps_between_scheduled_units_in_window, get_used_stations_in_timewindow
 from lofar.sas.tmss.client.tmssbuslistener import *
 from lofar.common.datetimeutils import round_to_second_precision
 from threading import Thread, Event
@@ -367,10 +367,19 @@ class Scheduler:
             # check gap size: minimal obs duration of 1 minute, plus an inter_observation_gap at both sides
             if (_upper_bound - _lower_bound) <= 2 * DEFAULT_INTER_OBSERVATION_GAP + timedelta(minutes=1):
                 # gap is too small
-                logger.debug("find_best_next_schedulable_unit: skipping too small window where nothing fits ['%s', '%s']",_lower_bound, _upper_bound)
+                logger.debug("find_best_next_schedulable_unit: skipping too small %dmin window where nothing fits ['%s', '%s']",
+                             (_upper_bound - _lower_bound).total_seconds() / 60.0,
+                             _lower_bound, _upper_bound)
                 return None
 
-            logger.info("find_best_next_schedulable_unit: evaluating constraints for units in window ['%s', '%s']: %s",
+            if len(_units)==0:
+                logger.debug("find_best_next_schedulable_unit: no units to evaluate in window ['%s', '%s']",_lower_bound, _upper_bound)
+                return None
+
+            logger.info("find_best_next_schedulable_unit: evaluating constraints for %d %s-queue units in %dmin window ['%s', '%s']: %s",
+                        len(_units),
+                        _units[0].priority_queue.value,
+                        (_upper_bound-_lower_bound).total_seconds()/60.0,
                         _lower_bound, _upper_bound,
                         ','.join([str(su.id) for su in sorted(_units, key=lambda x: x.id)]) or 'None')
 
@@ -381,7 +390,9 @@ class Scheduler:
                                                                                   self._raise_if_triggered,
                                                                                   self.search_gridder)
 
-            logger.info("find_best_next_schedulable_unit: units meeting constraints in window ['%s', '%s']: %s",
+            logger.info("find_best_next_schedulable_unit: %d units meeting constraints in %dmin window ['%s', '%s']: %s",
+                        len(filtered_scheduling_units),
+                        (_upper_bound-_lower_bound).total_seconds()/60.0,
                         _lower_bound,
                         _upper_bound,
                         ','.join([str(su.id) for su in sorted(filtered_scheduling_units, key=lambda x: x.id)]) or 'None')
@@ -408,7 +419,9 @@ class Scheduler:
             # then consider only those. Else, just use all.
             units_to_score = exclusive_in_this_window_scheduling_units if exclusive_in_this_window_scheduling_units else filtered_scheduling_units
 
-            logger.info("find_best_next_schedulable_unit: units to score in window ['%s', '%s']: %s",
+            logger.info("find_best_next_schedulable_unit: %d units to score in %dmin window ['%s', '%s']: %s",
+                        len(units_to_score),
+                        (_upper_bound-_lower_bound).total_seconds()/60.0,
                         _lower_bound,
                         _upper_bound,
                         ','.join([str(su.id) for su in sorted(units_to_score, key=lambda x: x.id)]) or 'None')
@@ -426,19 +439,20 @@ class Scheduler:
         # split the list of units in B-prio and non_B-prio
         # try to find the best unit in the non_B first
         scheduling_units_non_B = sorted([su for su in scheduling_units if su.priority_queue.value != models.PriorityQueueType.Choices.B.value], key=attrgetter('id'))
-
-        best_scored_scheduling_unit = _do_find_best_next_schedulable_unit(scheduling_units_non_B, lower_bound_start_time, upper_bound_stop_time)
-
-        if best_scored_scheduling_unit:
-            _elapsed = datetime.utcnow() - _start_search_timestamp
-            logger.info("find_best_next_schedulable_unit: best_scored_scheduling_unit id=%s name='%s' start='%s' in window ['%s', '%s'] (took %.2fs)",
-                        best_scored_scheduling_unit.scheduling_unit.id,
-                        best_scored_scheduling_unit.scheduling_unit.name,
-                        best_scored_scheduling_unit.start_time,
-                        lower_bound_start_time,
-                        upper_bound_stop_time,
-                        _elapsed.total_seconds())
-            return best_scored_scheduling_unit
+        if scheduling_units_non_B:
+            best_scored_scheduling_unit = _do_find_best_next_schedulable_unit(scheduling_units_non_B, lower_bound_start_time, upper_bound_stop_time)
+
+            if best_scored_scheduling_unit:
+                _elapsed = datetime.utcnow() - _start_search_timestamp
+                logger.info("find_best_next_schedulable_unit: best_scored_scheduling_unit id=%s name='%s' start='%s' in %dmin window ['%s', '%s'] (took %.2fs)",
+                            best_scored_scheduling_unit.scheduling_unit.id,
+                            best_scored_scheduling_unit.scheduling_unit.name,
+                            best_scored_scheduling_unit.start_time,
+                            (upper_bound_stop_time-lower_bound_start_time).total_seconds()/60.0,
+                            lower_bound_start_time,
+                            upper_bound_stop_time,
+                            _elapsed.total_seconds())
+                return best_scored_scheduling_unit
 
         # ok, no best non-B unit was found. Try the B-units now.
         scheduling_units_B = sorted([su for su in scheduling_units if su.priority_queue.value == models.PriorityQueueType.Choices.B.value], key=attrgetter('id'))
@@ -446,9 +460,10 @@ class Scheduler:
         # because B-prio units cannot unschedule overlapping/blocking A/triggered units, we need to search for gaps between already scheduled units.
         # and determine the scheduling search windows, taking into account the gaps between A/triggered units for B, or just the full window for A/triggered
         # group the B-units by stations, because the (non-)overlapping stations determine to gap to existing scheduled units.
+        used_stations = set(get_used_stations_in_timewindow(lower_bound_start_time, upper_bound_stop_time))
         grouped_by_stations_scheduling_units_B = {}
         for unit_B in scheduling_units_B:
-            stations = tuple(unit_B.main_observation_specified_stations)
+            stations = tuple(sorted(list(set(unit_B.main_observation_specified_stations)-used_stations)))
             if stations not in grouped_by_stations_scheduling_units_B:
                 grouped_by_stations_scheduling_units_B[stations] = [unit_B]
             else:
@@ -459,6 +474,10 @@ class Scheduler:
                                                                                   upper_bound_stop_time,
                                                                                   DEFAULT_INTER_OBSERVATION_GAP,
                                                                                   stations)
+            logger.info("find_best_next_schedulable_unit: gaps for %d units-with-stations=%s in window ['%s', '%s']: %s",
+                        len(scheduling_units_B_group),
+                        ','.join(stations), lower_bound_start_time, upper_bound_stop_time,
+                        ', '.join("['%s', '%s']"%(gap[0],gap[1]) for gap in scheduling_windows_for_B))
 
             for window in scheduling_windows_for_B:
                 best_scored_scheduling_unit = _do_find_best_next_schedulable_unit(scheduling_units_B_group,
@@ -479,7 +498,11 @@ class Scheduler:
                     return best_scored_scheduling_unit
 
         _elapsed = datetime.utcnow() - _start_search_timestamp
-        logger.info("find_best_next_schedulable_unit: could NOT find a best_scored_scheduling_unit in window ['%s', '%s']  (took %.2fs)", lower_bound_start_time, upper_bound_stop_time, _elapsed.total_seconds())
+        logger.info("find_best_next_schedulable_unit: could NOT find a best_scored_scheduling_unit in %dmin window ['%s', '%s']  (took %.2fs)",
+                    (upper_bound_stop_time-lower_bound_start_time).total_seconds()/60.0,
+                    lower_bound_start_time,
+                    upper_bound_stop_time,
+                    _elapsed.total_seconds())
         return None
 
 
@@ -710,8 +733,12 @@ class Scheduler:
                 except RecursionError as e:
                     logger.error("Max recursion depth reached. Skipping further scheduling of B-queue units in %d[min]-wide gap( ['%s', '%s')", (upper_bound_stop_time-lower_bound_start_time).total_seconds()/60, lower_bound_start_time, upper_bound_stop_time)
             else:
-                logger.info("place_B_priority_units_in_gaps: could not find any B-queue unit out of the %d candidates which fits in gap ['%s', '%s') next to unit id=%s",
-                            schedulable_units_queue_B.count(), lower_bound_start_time, upper_bound_stop_time, scheduling_unit.id)
+                logger.info("place_B_priority_units_in_gaps: could not find any B-queue unit out of the %d candidates which fits in %dmin gap ['%s', '%s') next to unit id=%s",
+                            schedulable_units_queue_B.count(),
+                            (upper_bound_stop_time-lower_bound_start_time).total_seconds()/60.0,
+                            lower_bound_start_time,
+                            upper_bound_stop_time,
+                            scheduling_unit.id)
 
         return placed_units
 
@@ -813,7 +840,7 @@ class Scheduler:
                         task_center_time, transit_time, offset_to_transit, lowest_elevation, elevation_at_center, elevation_at_transit = get_timestamps_elevations_and_offset_to_transit(unit, unit.scheduled_start_time)
 
                         logger.log(log_level,
-                            "  id=% 4d project=%s  q=%s  gap=%5d[min]  start_time='%s'[UTC]  duration=%4d[min]  status=%s name=%s centralLST='%s'  transit_offset=% 5d[min]  elv@transit=% 3.1f[deg]  elv@center=% 3.1f[deg]  elv_lowest=% 3.1f[deg] C/R/I=%s",
+                            "  id=% 4d %s %s gap=%5d[min]  start_time='%s'[UTC]  dur=%4d[min]  %s name=%s midLST='%s'  transit_offset=% 5d[min]  elv@tr=% 3.1f[deg]  elv@mid=% 3.1f[deg]  elv_min=% 3.1f[deg] C/R/I=%s",
                             unit.id,
                             ("'%s'" % (unit.project.name[:8],)).ljust(10),
                             unit.priority_queue.value,
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py
index b26ef30c1d3f87a53a92c37d628d58f6e4c86126..6dca3e5eb55ad5544642d336fb9a2c4e88831b4e 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py
@@ -2590,9 +2590,7 @@ def get_gaps_to_previous_and_next_observations(subtask: Subtask, exclude_subtask
         return ((datetime.min, datetime.max), (datetime.min, datetime.max))
 
     # prepare query for non-obsolete non-cancelled/error observations
-    qs = Subtask.objects.filter(specifications_template__type__value=SubtaskType.Choices.OBSERVATION.value)
-    qs = qs.filter(obsolete_since__isnull=True)
-    qs = qs.exclude(state__value__in=(SubtaskState.Choices.CANCELLED.value, SubtaskState.Choices.ERROR.value))
+    qs = Subtask.objects.filter(specifications_template__type__value=SubtaskType.Choices.OBSERVATION.value).filter(obsolete_since__isnull=True).exclude(state__value__in=(SubtaskState.Choices.CANCELLED.value, SubtaskState.Choices.ERROR.value))
 
     # non-placed units do not have a relevant start/stoptime.
     qs = qs.exclude(Q(placed=False) and Q(state__value=SubtaskState.Choices.DEFINED.value))
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py b/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py
index da9cef47b8926847ecd95be9f95a9ecf6cf0930e..8cef397022682b5a6fdca54e105131b0b896ffa9 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py
@@ -949,11 +949,11 @@ def get_gaps_to_previous_and_next_observations_in_scheduling_unit(scheduling_uni
     own_observation_subtasks = scheduling_unit.subtasks.filter(specifications_template__type__value='observation').filter(obsolete_since__isnull=True).all()
 
     # get all gaps, exclude observations in this unit.
-    results = [get_gaps_to_previous_and_next_observations(s,
+    results = [get_gaps_to_previous_and_next_observations(obs_subtask,
                                                           exclude_subtasks=own_observation_subtasks,
                                                           include_defined_unschedulable=include_schedulable_unschedulable,
-                                                          stations=scheduling_unit.main_observation_specified_stations)
-               for s in own_observation_subtasks]
+                                                          stations=obs_subtask.stations)
+               for obs_subtask in own_observation_subtasks]
 
     # gather overall gaps.
     overall_result = [[results[0][0][0], results[0][0][1]], [results[0][1][0], results[0][1][1]]]