diff --git a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml
index 41da31e93a963155ec011a950a8c773f7703ce30..a7362bf88a3898f687667ea110153ece4a8ade08 100644
--- a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml
+++ b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml
@@ -57,7 +57,8 @@ FOF:
   min_group_size:                  256         # The minimum no. of particles required for a group.
   linking_length_ratio:            0.2         # Linking length in units of the main inter-particle separation.
   black_hole_seed_halo_mass_Msun:  1.5e10      # Minimal halo mass in which to seed a black hole (in solar masses).
-  run_freq:                        256
+  scale_factor_first:              0.01        # Scale-factor of first FoF black hole seeding calls.
+  delta_time:                      1.005       # Scale-factor ratio between consecutive FoF black hole seeding calls.
 
 Scheduler:
   max_top_level_cells:   16
diff --git a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml
index cbdc44e8486d997ec0e45cc993565f0c9b865b15..ed1782127f7d80ba6d6802c256eeb9db9724d04f 100644
--- a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml
+++ b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml
@@ -57,7 +57,8 @@ FOF:
   min_group_size:                  256         # The minimum no. of particles required for a group.
   linking_length_ratio:            0.2         # Linking length in units of the main inter-particle separation.
   black_hole_seed_halo_mass_Msun:  1.5e10      # Minimal halo mass in which to seed a black hole (in solar masses).
-  run_freq:                        256
+  scale_factor_first:              0.01        # Scale-factor of first FoF black hole seeding calls.
+  delta_time:                      1.005       # Scale-factor ratio between consecutive FoF black hole seeding calls.
 
 Scheduler:
   max_top_level_cells:   16
diff --git a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml
index ebb2e37f048b455d4b8c4a3f08aa5943bc9ce13d..ca8eec7246bc0d3a0d6b10f8f75f0db6741f4f5b 100644
--- a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml
+++ b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml
@@ -57,7 +57,8 @@ FOF:
   min_group_size:                  256         # The minimum no. of particles required for a group.
   linking_length_ratio:            0.2         # Linking length in units of the main inter-particle separation.
   black_hole_seed_halo_mass_Msun:  1.5e10      # Minimal halo mass in which to seed a black hole (in solar masses).
-  run_freq:                        256
+  scale_factor_first:              0.01        # Scale-factor of first FoF black hole seeding calls.
+  delta_time:                      1.005       # Scale-factor ratio between consecutive FoF black hole seeding calls.
 
 Scheduler:
   max_top_level_cells:   32
diff --git a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml
index 951de51ca0df5d46f1f16aff6781918795da665e..434840636aceca6f6372cecfc5529a743a5cdc57 100644
--- a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml
+++ b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml
@@ -57,7 +57,8 @@ FOF:
   min_group_size:                  256         # The minimum no. of particles required for a group.
   linking_length_ratio:            0.2         # Linking length in units of the main inter-particle separation.
   black_hole_seed_halo_mass_Msun:  1.5e10      # Minimal halo mass in which to seed a black hole (in solar masses).
-  run_freq:                        256
+  scale_factor_first:              0.91        # Scale-factor of first FoF black hole seeding calls.
+  delta_time:                      1.005       # Scale-factor ratio between consecutive FoF black hole seeding calls.
 
 # Parameters related to the initial conditions
 InitialConditions:
diff --git a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml
index 720f344c1b761dbcbe0392216e4b789f1b6962cb..484eb885c4a47d92ebc82a978b1fe0d3973a00ff 100644
--- a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml
+++ b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml
@@ -64,7 +64,8 @@ FOF:
   min_group_size:                  256         # The minimum no. of particles required for a group.
   linking_length_ratio:            0.2         # Linking length in units of the main inter-particle separation.
   black_hole_seed_halo_mass_Msun:  1.5e10      # Minimal halo mass in which to seed a black hole (in solar masses).
-  run_freq:                        256
+  scale_factor_first:              0.91        # Scale-factor of first FoF black hole seeding calls.
+  delta_time:                      1.005       # Scale-factor ratio between consecutive FoF black hole seeding calls.
 
 # Parameters related to the initial conditions
 InitialConditions:
diff --git a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml
index bed82619414415f8e63782e09e8daed62b2da073..66df7929b9432eaad153dcd1a9b55da396f2e8be 100644
--- a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml
+++ b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml
@@ -59,7 +59,8 @@ FOF:
   min_group_size:                  256         # The minimum no. of particles required for a group.
   linking_length_ratio:            0.2         # Linking length in units of the main inter-particle separation.
   black_hole_seed_halo_mass_Msun:  1.5e10      # Minimal halo mass in which to seed a black hole (in solar masses).
-  run_freq:                        256
+  scale_factor_first:              0.91        # Scale-factor of first FoF black hole seeding calls.
+  delta_time:                      1.005       # Scale-factor ratio between consecutive FoF black hole seeding calls.
 
 # Parameters related to the initial conditions
 InitialConditions:
diff --git a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml
index 556276f326912303de1af6d13db1f4b6f19b7f95..5506ad242bff579ac4f6ec6ef23dbb8597eb65a9 100644
--- a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml
+++ b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml
@@ -68,10 +68,8 @@ FOF:
   min_group_size:                  256         # The minimum no. of particles required for a group.
   linking_length_ratio:            0.2         # Linking length in units of the main inter-particle separation.
   black_hole_seed_halo_mass_Msun:  1.5e10      # Minimal halo mass in which to seed a black hole (in solar masses).
-  absolute_linking_length:         -1.         # (Optional) Absolute linking length (in internal units)
-  run_freq:                        10          # (Optional) The no. of steps between each FOF search.
-  group_id_default:                2147483647  # (Optional) Sets the group ID of particles in groups below the minimum size. Defaults to 2^31 - 1 if unspecified. Has to be positive.
-  group_id_offset:                 1           # (Optional) Sets the offset of group ID labeling. Defaults to 1 if unspecified.
+  scale_factor_first:              0.91        # Scale-factor of first FoF black hole seeding calls.
+  delta_time:                      1.005       # Scale-factor ratio between consecutive FoF black hole seeding calls.
 
 # Parameters related to the initial conditions
 InitialConditions:
diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml
index a948ac62a5deb24cdfa73565ed067851d561bf38..176508f5c514b79515f3955679414ec99043b653 100644
--- a/examples/parameter_example.yml
+++ b/examples/parameter_example.yml
@@ -63,12 +63,14 @@ Gravity:
 
 # Parameters for the Friends-Of-Friends algorithm
 FOF:
-  basename:                        fof_output  # Filename for the FOF outputs.
+  basename:                        fof_output  # Filename for the FOF outputs (Unused when FoF is only run to seed BHs).
+  scale_factor_first:              0.91        # Scale-factor of first FoF black hole seeding calls (needed for cosmological runs).
+  time_first:                      0.2         # Time of first FoF black hole seeding calls (needed for non-cosmological runs).	
+  delta_time:                      1.005       # Time between consecutive FoF black hole seeding calls.
   min_group_size:                  256         # The minimum no. of particles required for a group.
   linking_length_ratio:            0.2         # Linking length in units of the main inter-particle separation.
   black_hole_seed_halo_mass_Msun:  1.5e10      # Minimal halo mass in which to seed a black hole (in solar masses).
-  absolute_linking_length:         -1.         # (Optional) Absolute linking length (in internal units)
-  run_freq:                        10          # (Optional) The no. of steps between each FOF search.
+  absolute_linking_length:         -1.         # (Optional) Absolute linking length (in internal units). When not set to -1, this will overwrite the linking length computed from 'linking_length_ratio'.
   group_id_default:                2147483647  # (Optional) Sets the group ID of particles in groups below the minimum size. Defaults to 2^31 - 1 if unspecified. Has to be positive.
   group_id_offset:                 1           # (Optional) Sets the offset of group ID labeling. Defaults to 1 if unspecified.
 
diff --git a/src/engine.c b/src/engine.c
index 007822474ec8d8b96d1c56d9e2ccc472794e2ec6..55b3346c3bdc30505e6bb53ef14edea7562301c8 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -3786,10 +3786,12 @@ void engine_step(struct engine *e) {
        ((double)e->total_nr_gparts) * e->gravity_properties->rebuild_frequency))
     e->forcerebuild = 1;
 
-  /* Trigger a FOF search every N steps. */
-  if (e->policy & engine_policy_fof &&
-      (e->step % e->fof_properties->run_freq == 1))
-    e->run_fof = 1;
+  /* Trigger a FOF black hole seeding? */
+  if (e->policy & engine_policy_fof) {
+    if (e->ti_end_min > e->ti_next_fof && e->ti_next_fof > 0) {
+      e->run_fof = 1;
+    }
+  }
 
 #ifdef WITH_LOGGER
   /* Mark the current time step in the particle logger file. */
@@ -4971,6 +4973,8 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params,
   e->delta_time_statistics =
       parser_get_param_double(params, "Statistics:delta_time");
   e->ti_next_stats = 0;
+  e->ti_next_stf = 0;
+  e->ti_next_fof = 0;
   e->verbose = verbose;
   e->wallclock_time = 0.f;
   e->physical_constants = physical_constants;
@@ -5051,6 +5055,17 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params,
         parser_get_opt_param_double(params, "StructureFinding:delta_time", -1.);
   }
 
+  /* Initialise FoF calls frequency. */
+  if (e->policy & engine_policy_fof) {
+
+    e->time_first_fof_call =
+        parser_get_opt_param_double(params, "FOF:time_first", 0.);
+    e->a_first_fof_call =
+        parser_get_opt_param_double(params, "FOF:scale_factor_first", 0.1);
+    e->delta_time_fof =
+        parser_get_opt_param_double(params, "FOF:delta_time", -1.);
+  }
+
   engine_init_output_lists(e, params);
 }
 
@@ -5420,6 +5435,18 @@ void engine_config(int restart, struct engine *e, struct swift_params *params,
             "simulation start a=%e.",
             e->a_first_stf_output, e->cosmology->a_begin);
     }
+
+    if (e->policy & engine_policy_fof) {
+
+      if (e->delta_time_fof <= 1.)
+        error("Time between FOF (%e) must be > 1.", e->delta_time_fof);
+
+      if (e->a_first_fof_call < e->cosmology->a_begin)
+        error(
+            "Scale-factor of first fof call (%e) must be after the "
+            "simulation start a=%e.",
+            e->a_first_fof_call, e->cosmology->a_begin);
+    }
   } else {
 
     if (e->delta_time_snapshot <= 0.)
@@ -5455,6 +5482,16 @@ void engine_config(int restart, struct engine *e, struct swift_params *params,
         error("Time of first STF (%e) must be after the simulation start t=%e.",
               e->time_first_stf_output, e->time_begin);
     }
+
+    if (e->policy & engine_policy_structure_finding) {
+
+      if (e->delta_time_fof <= 0.)
+        error("Time between FOF (%e) must be positive.", e->delta_time_fof);
+
+      if (e->time_first_fof_call < e->time_begin)
+        error("Time of first FOF (%e) must be after the simulation start t=%e.",
+              e->time_first_fof_call, e->time_begin);
+    }
   }
 
   /* Get the total mass */
@@ -5486,6 +5523,11 @@ void engine_config(int restart, struct engine *e, struct swift_params *params,
     engine_compute_next_stf_time(e);
   }
 
+  /* Find the time of the first stf output */
+  if (e->policy & engine_policy_fof) {
+    engine_compute_next_fof_time(e);
+  }
+
   /* Check that we are invoking VELOCIraptor only if we have it */
   if (e->snapshot_invoke_stf &&
       !(e->policy & engine_policy_structure_finding)) {
@@ -5896,6 +5938,67 @@ void engine_compute_next_stf_time(struct engine *e) {
   }
 }
 
+/**
+ * @brief Computes the next time (on the time line) for FoF black holes seeding
+ *
+ * @param e The #engine.
+ */
+void engine_compute_next_fof_time(struct engine *e) {
+
+  /* Find upper-bound on last output */
+  double time_end;
+  if (e->policy & engine_policy_cosmology)
+    time_end = e->cosmology->a_end * e->delta_time_fof;
+  else
+    time_end = e->time_end + e->delta_time_fof;
+
+  /* Find next snasphot above current time */
+  double time;
+  if (e->policy & engine_policy_cosmology)
+    time = e->a_first_fof_call;
+  else
+    time = e->time_first_fof_call;
+
+  int found_fof_time = 0;
+  while (time < time_end) {
+
+    /* Output time on the integer timeline */
+    if (e->policy & engine_policy_cosmology)
+      e->ti_next_fof = log(time / e->cosmology->a_begin) / e->time_base;
+    else
+      e->ti_next_fof = (time - e->time_begin) / e->time_base;
+
+    /* Found it? */
+    if (e->ti_next_fof > e->ti_current) {
+      found_fof_time = 1;
+      break;
+    }
+
+    if (e->policy & engine_policy_cosmology)
+      time *= e->delta_time_fof;
+    else
+      time += e->delta_time_fof;
+  }
+
+  /* Deal with last snapshot */
+  if (!found_fof_time) {
+    e->ti_next_fof = -1;
+    if (e->verbose) message("No further FoF time.");
+  } else {
+
+    /* Be nice, talk... */
+    if (e->policy & engine_policy_cosmology) {
+      const float next_fof_time =
+          exp(e->ti_next_fof * e->time_base) * e->cosmology->a_begin;
+      // if (e->verbose)
+      message("Next FoF time set to a=%e.", next_fof_time);
+    } else {
+      const float next_fof_time = e->ti_next_fof * e->time_base + e->time_begin;
+      if (e->verbose) message("Next FoF time set to t=%e.", next_fof_time);
+    }
+  }
+}
+
 /**
  * @brief Initialize all the output_list required by the engine
  *
@@ -6419,6 +6522,9 @@ void engine_fof(struct engine *e) {
   /* Flag that a FOF has taken place */
   e->step_props |= engine_step_prop_fof;
 
+  /* ... and find the next FOF time */
+  engine_compute_next_fof_time(e);
+
   if (engine_rank == 0)
     message("Complete FOF search took: %.3f %s.",
             clocks_from_ticks(getticks() - tic), clocks_getunit());
diff --git a/src/engine.h b/src/engine.h
index 579adf8a8f4e02567ff83815b312267e0a144051..f6de893ca23cc995d1ff9646b79e14c2faf8761b 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -307,6 +307,14 @@ struct engine {
   char stf_base_name[PARSER_MAX_LINE_SIZE];
   int stf_output_count;
 
+  /* FoF black holes seeding information */
+  double a_first_fof_call;
+  double time_first_fof_call;
+  double delta_time_fof;
+
+  /* Integer time of the next FoF black holes seeding call */
+  integertime_t ti_next_fof;
+
   /* FOF information */
   int run_fof;
 
@@ -470,6 +478,7 @@ void engine_addlink(struct engine *e, struct link **l, struct task *t);
 void engine_barrier(struct engine *e);
 void engine_compute_next_snapshot_time(struct engine *e);
 void engine_compute_next_stf_time(struct engine *e);
+void engine_compute_next_fof_time(struct engine *e);
 void engine_compute_next_statistics_time(struct engine *e);
 void engine_recompute_displacement_constraint(struct engine *e);
 void engine_unskip(struct engine *e);
diff --git a/src/fof.c b/src/fof.c
index 048155280cacb6deabd80092e6a8c43959376876..5ed57ba6c2bc3916e3d69589963af884f1ae6815 100644
--- a/src/fof.c
+++ b/src/fof.c
@@ -42,7 +42,6 @@
 #include "proxy.h"
 #include "threadpool.h"
 
-#define fof_props_default_run_freq 2000
 #define fof_props_default_group_id 2147483647
 #define fof_props_default_group_id_offset 1
 #define fof_props_default_group_link_size 20000
@@ -100,10 +99,6 @@ void fof_init(struct fof_props *props, struct swift_params *params,
           strerror(errno));
   }
 
-  /* Read the FOF search frequency. */
-  props->run_freq = parser_get_opt_param_int(params, "FOF:run_freq",
-                                             fof_props_default_run_freq);
-
   /* Read the minimum group size. */
   props->min_group_size = parser_get_param_int(params, "FOF:min_group_size");
 
diff --git a/src/fof.h b/src/fof.h
index 93d3a0beb2ecf22adcd808fe4879a86806301e5a..160f7c0af8f7f6f7a589c6978cd107b7ffbff1fc 100644
--- a/src/fof.h
+++ b/src/fof.h
@@ -69,9 +69,6 @@ struct fof_props {
   /*! The minimum halo mass for black hole seeding. */
   double seed_halo_mass;
 
-  /*! The no. of steps between each FOF search. */
-  int run_freq;
-
   /*! Minimal number of particles in a group */
   size_t min_group_size;