diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml
index a5791306752c92bbe63985d029594178faae7213..978986fdc57827f46ea25aa6d81b6c2e5ba06c2c 100644
--- a/examples/parameter_example.yml
+++ b/examples/parameter_example.yml
@@ -79,8 +79,8 @@ DomainDecomposition:
   initial_grid_x:   10      # (Optional) Grid size if the "grid" strategy is chosen.
   initial_grid_y:   10      # ""
   initial_grid_z:   10      # ""
-  repartition_type: task_weights # (Optional) The re-decomposition strategy: "none", "task_weights", "particle_weights",
-                                 #            "edge_task_weights" or "hybrid_weights".
+  repartition_type: task_costs # (Optional) The re-decomposition strategy: "none", "task_costs", "particle_weights",
+                               #            "edge_task_costs", "hybrid_weights" or "bin_weights"
   trigger:          0.05    # (Optional) Fractional (<1) CPU time difference between MPI ranks required to trigger a
                             # new decomposition, or number of steps (>1) between decompositions
   minfrac:          0.9     # (Optional) Fractional of all particles that should be updated in previous step when
diff --git a/src/debug.c b/src/debug.c
index fa0cd14a8c15f188c8ebc0c2ed9e29a79b73cb77..368c5cbb08003b2f1a45d276c3942bbd35a02012 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -316,7 +316,7 @@ static void dumpCells_map(struct cell *c, void *data) {
  * for all cells to a simple text file.
  *
  * @param prefix base output filename, result is written to
- *               <prefix>_<rank>_<step>.dat
+ *               %prefix%_%rank%_%step%.dat
  * @param s the space holding the cells to dump.
  * @param rank node ID of MPI rank, or 0 if not relevant.
  * @param step the current engine step, or some unique integer.
diff --git a/src/partition.c b/src/partition.c
index 5ac70205a77998aff59b24df2aaafc9406b5aa99..7fabc3cdfda185f5bb813aba0924178913c6e839 100644
--- a/src/partition.c
+++ b/src/partition.c
@@ -63,10 +63,13 @@ const char *initial_partition_name[] = {
 
 /* Simple descriptions of repartition types for reports. */
 const char *repartition_name[] = {
-    "no", "METIS edge and vertex time weighted cells",
-    "METIS particle count vertex weighted cells",
-    "METIS time edge weighted cells",
-    "METIS particle count vertex and time edge cells"};
+    "none",
+    "METIS edge and vertex cost weights",
+    "METIS particle count vertex weights",
+    "METIS cost edge weights",
+    "METIS particle count vertex and cost edge weights",
+    "METIS vertex costs and edge delta timebin weights",
+};
 
 /* Local functions, if needed. */
 static int check_complete(struct space *s, int verbose, int nregions);
@@ -476,15 +479,16 @@ static void pick_metis(struct space *s, int nregions, int *vertexw, int *edgew,
  * @param partweights whether particle counts will be used as vertex weights.
  * @param bothweights whether vertex and edge weights will be used, otherwise
  *                    only edge weights will be used.
+ * @param timebins use timebins as edge weights.
  * @param nodeID our nodeID.
  * @param nr_nodes the number of nodes.
  * @param s the space of cells holding our local particles.
  * @param tasks the completed tasks from the last engine step for our node.
  * @param nr_tasks the number of tasks.
  */
-static void repart_edge_metis(int partweights, int bothweights, int nodeID,
-                              int nr_nodes, struct space *s, struct task *tasks,
-                              int nr_tasks) {
+static void repart_edge_metis(int partweights, int bothweights, int timebins,
+                              int nodeID, int nr_nodes, struct space *s,
+                              struct task *tasks, int nr_tasks) {
 
   /* Create weight arrays using task ticks for vertices and edges (edges
    * assume the same graph structure as used in the part_ calls). Note that
@@ -599,42 +603,39 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID,
           if (cj->nodeID == nodeID) weights_v[cjd] += 0.5 * w;
         }
 
-        /* Add weights to edge for all cells based on the expected interaction
-         * time. We want to avoid having active cells on the edges, so we cut
-         * for that. */
-        int dti = num_time_bins - get_time_bin(ci->ti_end_min);
-        int dtj = num_time_bins - get_time_bin(cj->ti_end_min);
-
-        int kk;
-        for (kk = 26 * cid; inds[kk] != cjd; kk++)
-          ;
-
-        /* If a foreign cell we repeat the interaction remotely, so these get
-         * 1/2 of the local time bin weight. */
-        int dt;
-        if (ci->nodeID == nodeID)
-          dt = dti + dtj/2;
-        else
-          dt = dtj/2;
-        dt = dti + dtj;
-        dt = (1<<dt);
-
-        wtot[1] += dt;
-        weights_e[kk] += dt;
-
-        /* cj */
-        for (kk = 26 * cjd; inds[kk] != cid; kk++)
-          ;
-        if (cj->nodeID == nodeID)
-          dt = dtj + dti/2;
-        else
-          dt = dti/2;
-
-        dt = dti + dtj;
-        dt = (1<<dt);
-
-        wtot[1] += dt;
-        weights_e[kk] += dt;
+        if (timebins) {
+          /* Add weights to edge for all cells based on the expected
+           * interaction time (calculated as the time to the last expected
+           * time) as we want to avoid having active cells on the edges, so we
+           * cut for that. Note that weight is added to the local and remote
+           * cells, as we want to keep both away from any cuts. */
+          int dti = num_time_bins - get_time_bin(ci->ti_end_min);
+          int dtj = num_time_bins - get_time_bin(cj->ti_end_min);
+          int dt = (1<<(dti + dtj));
+
+          /* ci */
+          int kk;
+          for (kk = 26 * cid; inds[kk] != cjd; kk++);
+          wtot[1] += dt;
+          weights_e[kk] += dt;
+
+          /* cj */
+          for (kk = 26 * cjd; inds[kk] != cid; kk++);
+          wtot[1] += dt;
+          weights_e[kk] += dt;
+        } else {
+
+          /* Add weights from task costs to the edge. */
+
+          /* ci */
+          int kk;
+          for (kk = 26 * cid; inds[kk] != cjd; kk++);
+          weights_e[kk] += w;
+
+          /* cj */
+          for (kk = 26 * cjd; inds[kk] != cid; kk++);
+          weights_e[kk] += w;
+        }
       }
     }
   }
@@ -705,7 +706,8 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID,
       }
     }
 
-    /* Now edge weights. Unlikely these will ever need scaling. */
+    /* Now edge weights. XXX need to balance weights if very different in
+     * range. */
     wmin[1] = wmax[1];
     wmax[1] = 0;
     for (int k = 0; k < nr_cells; k++) {
@@ -838,35 +840,26 @@ void partition_repartition(struct repartition *reparttype, int nodeID,
 
 #if defined(WITH_MPI) && defined(HAVE_METIS)
 
-  if (reparttype->type == REPART_METIS_BOTH ||
-      reparttype->type == REPART_METIS_EDGE ||
-      reparttype->type == REPART_METIS_VERTEX_EDGE) {
+  if (reparttype->type == REPART_METIS_VERTEX_COSTS_EDGE_COSTS) {
+    repart_edge_metis(1, 1, 0, nodeID, nr_nodes, s, tasks, nr_tasks);
 
-    int partweights;
-    int bothweights;
-    if (reparttype->type == REPART_METIS_VERTEX_EDGE)
-      partweights = 1;
-    else
-      partweights = 0;
+  } else if (reparttype->type == REPART_METIS_EDGE_COSTS) {
+    repart_edge_metis(0, 0, 0, nodeID, nr_nodes, s, tasks, nr_tasks);
 
-    if (reparttype->type == REPART_METIS_BOTH)
-      bothweights = 1;
-    else
-      bothweights = 0;
+  } else if (reparttype->type == REPART_METIS_VERTEX_COUNTS_EDGE_COSTS) {
+    repart_edge_metis(1, 0, 0, nodeID, nr_nodes, s, tasks, nr_tasks);
 
-    repart_edge_metis(partweights, bothweights, nodeID, nr_nodes, s, tasks,
-                      nr_tasks);
-
-  } else if (reparttype->type == REPART_METIS_VERTEX) {
+  } else if (reparttype->type == REPART_METIS_VERTEX_COSTS_EDGE_TIMEBINS) {
+    repart_edge_metis(1, 1, 1, nodeID, nr_nodes, s, tasks, nr_tasks);
 
+  } else if (reparttype->type == REPART_METIS_VERTEX_COUNTS) {
     repart_vertex_metis(s, nodeID, nr_nodes);
 
   } else if (reparttype->type == REPART_NONE) {
-
     /* Doing nothing. */
 
   } else {
-    error("Unknown repartition type");
+    error("Impossible repartition type");
   }
 #else
   error("SWIFT was not compiled with METIS support.");
@@ -1020,7 +1013,7 @@ void partition_init(struct partition *partition,
 
 /* Defaults make use of METIS if available */
 #ifdef HAVE_METIS
-  const char *default_repart = "task_weights";
+  const char *default_repart = "task_costs";
   const char *default_part = "simple_metis";
 #else
   const char *default_repart = "none";
@@ -1086,22 +1079,25 @@ void partition_init(struct partition *partition,
       break;
 #ifdef HAVE_METIS
     case 't':
-      repartition->type = REPART_METIS_BOTH;
+      repartition->type = REPART_METIS_VERTEX_COSTS_EDGE_COSTS;
       break;
     case 'e':
-      repartition->type = REPART_METIS_EDGE;
+      repartition->type = REPART_METIS_EDGE_COSTS;
       break;
     case 'p':
-      repartition->type = REPART_METIS_VERTEX;
+      repartition->type = REPART_METIS_VERTEX_COUNTS;
       break;
     case 'h':
-      repartition->type = REPART_METIS_VERTEX_EDGE;
+      repartition->type = REPART_METIS_VERTEX_COUNTS_EDGE_COSTS;
+      break;
+    case 'b':
+      repartition->type = REPART_METIS_VERTEX_COSTS_EDGE_TIMEBINS;
       break;
     default:
       message("Invalid choice of re-partition type '%s'.", part_type);
       error(
-          "Permitted values are: 'none', 'task_weights', 'particle_weights',"
-          "'edge_task_weights' or 'hybrid_weights'");
+          "Permitted values are: 'none', 'task_costs', 'particle_weights',"
+          "'edge_task_costs', 'hybrid_weights' or 'bin_weights'");
 #else
     default:
       message("Invalid choice of re-partition type '%s'.", part_type);
diff --git a/src/partition.h b/src/partition.h
index 03523b165a930b085224e458ac0dd8c8232a578d..e7668f56fd8a1b1bb16ce41f3ba61be58df5371c 100644
--- a/src/partition.h
+++ b/src/partition.h
@@ -43,10 +43,11 @@ struct partition {
 /* Repartition type to use. */
 enum repartition_type {
   REPART_NONE = 0,
-  REPART_METIS_BOTH,
-  REPART_METIS_VERTEX,
-  REPART_METIS_EDGE,
-  REPART_METIS_VERTEX_EDGE
+  REPART_METIS_VERTEX_COSTS_EDGE_COSTS,
+  REPART_METIS_VERTEX_COUNTS,
+  REPART_METIS_EDGE_COSTS,
+  REPART_METIS_VERTEX_COUNTS_EDGE_COSTS,
+  REPART_METIS_VERTEX_COSTS_EDGE_TIMEBINS,
 };
 
 /* Repartition preferences. */