diff --git a/src/Makefile.am b/src/Makefile.am
index 7556089b828cb901f0ba2b1e576cf4793e3e1e8e..0d3be275a2fa224f9f3e591c702a07ce00897f9f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,7 +52,7 @@ include_HEADERS = space.h runner.h queue.h task.h lock.h cell.h part.h const.h \
     logger_io.h tracers_io.h tracers.h tracers_struct.h star_formation_io.h fof.h \
     star_formation_struct.h star_formation.h star_formation_iact.h \
     star_formation_logger.h star_formation_logger_struct.h \
-    velociraptor_struct.h velociraptor_io.h random.h memuse.h black_holes.h black_holes_io.h \
+    velociraptor_struct.h velociraptor_io.h random.h memuse.h memuse_rnodes.h black_holes.h black_holes_io.h \
     black_holes_properties.h black_holes_struct.h feedback.h feedback_struct.h feedback_properties.h
 
 # source files for EAGLE cooling
@@ -78,7 +78,7 @@ AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c engine_maketasks.c
     part_type.c xmf.c gravity_properties.c gravity.c \
     collectgroup.c hydro_space.c equation_of_state.c \
     chemistry.c cosmology.c restart.c mesh_gravity.c velociraptor_interface.c \
-    outputlist.c velociraptor_dummy.c logger_io.c memuse.c fof.c \
+    outputlist.c velociraptor_dummy.c logger_io.c memuse.c memuse_rnodes.c fof.c \
     hashmap.c \
     $(EAGLE_COOLING_SOURCES) $(EAGLE_FEEDBACK_SOURCES)
 
diff --git a/src/memuse.c b/src/memuse.c
index 77344cc6cec56544a6e19cc6a71ca2375aa1916c..f3470f6c4569067d4f352cfb970c57d8562745b4 100644
--- a/src/memuse.c
+++ b/src/memuse.c
@@ -20,6 +20,7 @@
 /**
  *  @file memuse.c
  *  @brief file of routines to report about memory use in SWIFT.
+ *  Includes MPI exchanges made by the tasks.
  *  Note reports are in KB.
  */
 
@@ -29,6 +30,8 @@
 /* Standard includes. */
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -39,6 +42,8 @@
 #include "atomic.h"
 #include "clocks.h"
 #include "engine.h"
+#include "error.h"
+#include "memuse_rnodes.h"
 
 #ifdef SWIFT_MEMUSE_REPORTS
 
@@ -101,254 +106,10 @@ struct memuse_labelled_item {
   size_t count;
 };
 
-/* A radix node, this has a single byte key and a pointer to some related
- * resource. It also holds a sorted list of children, if any. */
-struct memuse_rnode {
-
-  /* Byte key of this node. */
-  uint8_t keypart;
-
-  /* Value of this node, if set. */
-  void *ptr;
-
-  /* Sorted pointers to children of this node. */
-  struct memuse_rnode **children;
-  unsigned int count;
-};
-
 /* Persistent radix trie root node. Holds active logs between dumps. */
 static struct memuse_rnode *memuse_rnode_root;
 static int memuse_rnode_root_init = 1;
 
-#ifdef MEMUSE_RNODE_DUMP
-/**
- * @brief Dump a representation of the radix tree rooted at a node to stdout.
- *
- * @param depth the depth of the node in the tree, root is 0.
- * @param node the node at which to start dumping.
- * @param full if not zero then nodes that are not storing a value
- *              are also reported.
- */
-static void memuse_rnode_dump(int depth, struct memuse_rnode *node, int full) {
-
-  /* Value of the full key, to this depth. Assumes full key is a pointer,
-   * so uncomment when using strings. */
-  static union {
-    // uint8_t key[MEMUSE_MAXLABLEN];
-    // char ptr[MEMUSE_MAXLABLEN];
-    uint8_t key[sizeof(uintptr_t)];
-    void *ptr;
-  } keyparts = {0};
-
-  /* Record keypart at this depth. Root has no keypart. */
-  if (depth != 0) keyparts.key[depth - 1] = node->keypart;
-
-  // if (node->ptr != NULL || full) {
-  //  keyparts.key[depth] = '\0';
-  //
-  //    /* Gather children's keys if full. */
-  //    char fullkey[MEMUSE_MAXLABLEN];
-  //    if (full) {
-  //      for (size_t k = 0; k < node->count; k++) {
-  //        fullkey[k] = node->children[k]->keypart;
-  //      }
-  //      fullkey[node->count] = '\0';
-  //      printf("dump @ depth: %d keypart: %d key: %s value: %p fullkey: %s\n",
-  //             depth, node->keypart, keyparts.ptr, node->ptr, fullkey);
-  //    } else {
-  //      printf("dump @ depth: %d keypart: %d key: %s value: %p\n", depth,
-  //             node->keypart, keyparts.ptr, node->ptr);
-  //    }
-  //}
-
-  if (node->ptr != NULL || full) {
-    printf("dump @ depth: %d keypart: %d key: %p value: %p\n", depth,
-           node->keypart, keyparts.ptr, node->ptr);
-  }
-
-  /* Recurse to all children. */
-  for (size_t k = 0; k < node->count; k++) {
-    memuse_rnode_dump(depth + 1, node->children[k], full);
-  }
-}
-#endif
-
-/**
- * @brief Return the position of a keypart for a list of children.
- *        If not found returns where it would be inserted.
- *
- * @param keypart the keypart to locate.
- * @param children the list of sorted children.
- * @param count the number of children
- *
- * @return the index of key or where it should be inserted.
- */
-static unsigned int memuse_rnode_bsearch(uint8_t keypart,
-                                         struct memuse_rnode **children,
-                                         unsigned int count) {
-
-  /* Search for lower bound. */
-  unsigned int lower = 0;
-  unsigned int upper = count;
-  while (lower < upper) {
-    unsigned int middle = (upper + lower) / 2;
-    if (keypart > children[middle]->keypart)
-      lower = middle + 1;
-    else
-      upper = middle;
-  }
-  return lower;
-}
-
-/**
- * @brief Insert a child, if needed, into a list of children. Assumes
- *        we have sufficient room.
- *
- * @param child the child to insert, if needed.
- * @param children the list of sorted children.
- * @param count the number of children
- */
-static void memuse_rnode_binsert_child(struct memuse_rnode *child,
-                                       struct memuse_rnode **children,
-                                       unsigned int *count) {
-  unsigned int pos = 0;
-  if (*count > 0) {
-
-    /* Find the child or insertion point. */
-    pos = memuse_rnode_bsearch(child->keypart, children, *count);
-
-    /* If not found move all children to make a space, unless we're inserting
-     * after the end. */
-    if (pos < *count && children[pos]->keypart != child->keypart) {
-      memmove(&children[pos + 1], &children[pos],
-              (*count - pos) * sizeof(struct memuse_rnode *));
-    }
-  }
-
-  /* Insert new child */
-  children[pos] = child;
-  *count += 1;
-}
-
-/**
- * @brief Add a child rnode to an rnode. Making sure we have room and keeping
- *        the sort order.
- *
- * @param node the parent node.
- * @param child the node to add to the parent,
- */
-static void memuse_rnode_add_child(struct memuse_rnode *node,
-                                   struct memuse_rnode *child) {
-
-  /* Extend the children list to include a new entry .*/
-  void *mem = realloc(node->children,
-                      (node->count + 1) * sizeof(struct memuse_rnode *));
-  if (mem == NULL) error("Failed to reallocate rnodes\n");
-  node->children = mem;
-
-  /* Insert the new child. */
-  memuse_rnode_binsert_child(child, node->children, &node->count);
-}
-
-/**
- * @brief Find a child of a node with the given key part.
- *
- * @param node the node to search.
- * @param keypart the key part of the child.
- * @return NULL if not found.
- */
-static struct memuse_rnode *memuse_rnode_lookup(const struct memuse_rnode *node,
-                                                uint8_t keypart) {
-
-  /* Locate the key, or where it would be inserted. */
-  if (node->count > 0) {
-    unsigned int index =
-        memuse_rnode_bsearch(keypart, node->children, node->count);
-    if (index < node->count && keypart == node->children[index]->keypart) {
-      return node->children[index];
-    }
-  }
-  return NULL;
-}
-
-/**
- * @brief insert a child into a node's children list and add a pointer, iff
- *        this is the destination node for the given key.
- *
- * @param node the parent node.
- * @param depth the depth of the parent node.
- * @param key the full key of the eventual leaf node.
- * @param keylen the numbers of bytes in the full key.
- * @param value pointer that will be stored as the value of the leaf node.
- */
-static void memuse_rnode_insert_child(struct memuse_rnode *node, uint8_t depth,
-                                      uint8_t *key, uint8_t keylen,
-                                      void *value) {
-
-  /* Check if keypart this already exists at this level and add new child if
-   * not. */
-  uint8_t keypart = key[depth];
-  struct memuse_rnode *child = memuse_rnode_lookup(node, keypart);
-  if (child == NULL) {
-    child = calloc(1, sizeof(struct memuse_rnode));
-    child->keypart = keypart;
-    memuse_rnode_add_child(node, child);
-  }
-
-  /* Are we at the lowest level yet? */
-  depth++;
-  if (depth == keylen) {
-  /* Our destination node. */
-
-#if SWIFT_DEBUG_CHECKS
-    if (child->ptr != NULL)
-      message("Overwriting rnode value: %p with %p", child->ptr, value);
-#endif
-    child->ptr = value;
-    return;
-  }
-
-  /* Down we go to the next level. */
-  memuse_rnode_insert_child(child, depth, key, keylen, value);
-  return;
-}
-
-/**
- * @brief Find a child node for the given full key.
- *
- * @param node the current parent node.
- * @param depth the depth of the parent node, 0 for first call.
- * @param key the full key of the expected child node.
- * @param keylen the number of bytes in the key.
- */
-static struct memuse_rnode *memuse_rnode_find_child(struct memuse_rnode *node,
-                                                    uint8_t depth, uint8_t *key,
-                                                    uint8_t keylen) {
-  uint8_t keypart = key[depth];
-  struct memuse_rnode *child = NULL;
-  if (node->count > 0) child = memuse_rnode_lookup(node, keypart);
-  if (child != NULL && (depth + 1) < keylen) {
-    return memuse_rnode_find_child(child, depth + 1, key, keylen);
-  }
-  return child;
-}
-
-/**
- * @brief Free all resources associated with a node.
- *
- * @param node the rnode.
- */
-static void memuse_rnode_cleanup(struct memuse_rnode *node) {
-
-  if (!node) return;
-
-  for (size_t k = 0; k < node->count; k++) {
-    memuse_rnode_cleanup(node->children[k]);
-    free(node->children[k]);
-  }
-  if (node->count > 0) free(node->children);
-}
-
 /**
  * @brief reallocate the entries log if space is needed.
  */
diff --git a/src/memuse_rnodes.c b/src/memuse_rnodes.c
new file mode 100644
index 0000000000000000000000000000000000000000..daf8164fe4d39a2532287e1bfc8b2d132bf05b19
--- /dev/null
+++ b/src/memuse_rnodes.c
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2019 Peter W. Draper (p.w.draper@durham.ac.uk)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+/**
+ *  @file memuse_rnode.c
+ *  @brief file of routines used for radix nodes in memory loggers.
+ */
+
+/* Config parameters. */
+#include "../config.h"
+
+/* Standard includes. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* Local defines. */
+#include "memuse_rnodes.h"
+
+/* Local includes. */
+#include "atomic.h"
+#include "clocks.h"
+#include "error.h"
+
+/**
+ * @brief Return the position of a keypart for a list of children.
+ *        If not found returns where it would be inserted.
+ *
+ * @param keypart the keypart to locate.
+ * @param children the list of sorted children.
+ * @param count the number of children
+ *
+ * @return the index of key or where it should be inserted.
+ */
+static unsigned int memuse_rnode_bsearch(uint8_t keypart,
+                                         struct memuse_rnode **children,
+                                         unsigned int count) {
+
+  /* Search for lower bound. */
+  unsigned int lower = 0;
+  unsigned int upper = count;
+  while (lower < upper) {
+    unsigned int middle = (upper + lower) / 2;
+    if (keypart > children[middle]->keypart)
+      lower = middle + 1;
+    else
+      upper = middle;
+  }
+  return lower;
+}
+
+/**
+ * @brief Insert a child, if needed, into a list of children. Assumes
+ *        we have sufficient room.
+ *
+ * @param child the child to insert, if needed.
+ * @param children the list of sorted children.
+ * @param count the number of children
+ */
+static void memuse_rnode_binsert_child(struct memuse_rnode *child,
+                                       struct memuse_rnode **children,
+                                       unsigned int *count) {
+  unsigned int pos = 0;
+  if (*count > 0) {
+
+    /* Find the child or insertion point. */
+    pos = memuse_rnode_bsearch(child->keypart, children, *count);
+
+    /* If not found move all children to make a space, unless we're inserting
+     * after the end. */
+    if (pos < *count && children[pos]->keypart != child->keypart) {
+      memmove(&children[pos + 1], &children[pos],
+              (*count - pos) * sizeof(struct memuse_rnode *));
+    }
+  }
+
+  /* Insert new child */
+  children[pos] = child;
+  *count += 1;
+}
+
+/**
+ * @brief Add a child rnode to an rnode. Making sure we have room and keeping
+ *        the sort order.
+ *
+ * @param node the parent node.
+ * @param child the node to add to the parent,
+ */
+static void memuse_rnode_add_child(struct memuse_rnode *node,
+                                   struct memuse_rnode *child) {
+
+  /* Extend the children list to include a new entry .*/
+  void *mem = realloc(node->children,
+                      (node->count + 1) * sizeof(struct memuse_rnode *));
+  if (mem == NULL) error("Failed to reallocate rnodes\n");
+  node->children = mem;
+
+  /* Insert the new child. */
+  memuse_rnode_binsert_child(child, node->children, &node->count);
+}
+
+/**
+ * @brief Find a child of a node with the given key part.
+ *
+ * @param node the node to search.
+ * @param keypart the key part of the child.
+ * @return NULL if not found.
+ */
+static struct memuse_rnode *memuse_rnode_lookup(const struct memuse_rnode *node,
+                                                uint8_t keypart) {
+
+  /* Locate the key, or where it would be inserted. */
+  if (node->count > 0) {
+    unsigned int index =
+        memuse_rnode_bsearch(keypart, node->children, node->count);
+    if (index < node->count && keypart == node->children[index]->keypart) {
+      return node->children[index];
+    }
+  }
+  return NULL;
+}
+
+/**
+ * @brief insert a child into a node's children list and add a pointer, iff
+ *        this is the destination node for the given key.
+ *
+ * @param node the parent node.
+ * @param depth the depth of the parent node.
+ * @param key the full key of the eventual leaf node.
+ * @param keylen the numbers of bytes in the full key.
+ * @param value pointer that will be stored as the value of the leaf node.
+ */
+void memuse_rnode_insert_child(struct memuse_rnode *node, uint8_t depth,
+                               uint8_t *key, uint8_t keylen,
+                               void *value) {
+
+  /* Check if keypart this already exists at this level and add new child if
+   * not. */
+  uint8_t keypart = key[depth];
+  struct memuse_rnode *child = memuse_rnode_lookup(node, keypart);
+  if (child == NULL) {
+    child = calloc(1, sizeof(struct memuse_rnode));
+    child->keypart = keypart;
+    memuse_rnode_add_child(node, child);
+  }
+
+  /* Are we at the lowest level yet? */
+  depth++;
+  if (depth == keylen) {
+  /* Our destination node. */
+
+#if SWIFT_DEBUG_CHECKS
+    if (child->ptr != NULL)
+      message("Overwriting rnode value: %p with %p", child->ptr, value);
+#endif
+    child->ptr = value;
+    return;
+  }
+
+  /* Down we go to the next level. */
+  memuse_rnode_insert_child(child, depth, key, keylen, value);
+  return;
+}
+
+/**
+ * @brief Find a child node for the given full key.
+ *
+ * @param node the current parent node.
+ * @param depth the depth of the parent node, 0 for first call.
+ * @param key the full key of the expected child node.
+ * @param keylen the number of bytes in the key.
+ */
+struct memuse_rnode *memuse_rnode_find_child(struct memuse_rnode *node,
+                                             uint8_t depth, uint8_t *key,
+                                             uint8_t keylen) {
+  uint8_t keypart = key[depth];
+  struct memuse_rnode *child = NULL;
+  if (node->count > 0) child = memuse_rnode_lookup(node, keypart);
+  if (child != NULL && (depth + 1) < keylen) {
+    return memuse_rnode_find_child(child, depth + 1, key, keylen);
+  }
+  return child;
+}
+
+/**
+ * @brief Free all resources associated with a node.
+ *
+ * @param node the rnode.
+ */
+void memuse_rnode_cleanup(struct memuse_rnode *node) {
+
+  if (!node) return;
+
+  for (size_t k = 0; k < node->count; k++) {
+    memuse_rnode_cleanup(node->children[k]);
+    free(node->children[k]);
+  }
+  if (node->count > 0) free(node->children);
+}
+
+/**
+ * @brief Dump a representation of the radix tree rooted at a node to stdout.
+ *
+ * Debugging code.
+ *
+ * @param depth the depth of the node in the tree, root is 0.
+ * @param node the node at which to start dumping.
+ * @param full if not zero then nodes that are not storing a value
+ *              are also reported.
+ */
+void memuse_rnode_dump(int depth, struct memuse_rnode *node, int full) {
+
+  /* Value of the full key, to this depth. Assumes full key is a pointer,
+   * so uncomment when using strings. */
+  static union {
+    // uint8_t key[MEMUSE_MAXLABLEN];
+    // char ptr[MEMUSE_MAXLABLEN];
+    uint8_t key[sizeof(uintptr_t)];
+    void *ptr;
+  } keyparts = {0};
+
+  /* Record keypart at this depth. Root has no keypart. */
+  if (depth != 0) keyparts.key[depth - 1] = node->keypart;
+
+  // if (node->ptr != NULL || full) {
+  //  keyparts.key[depth] = '\0';
+  //
+  //    /* Gather children's keys if full. */
+  //    char fullkey[MEMUSE_MAXLABLEN];
+  //    if (full) {
+  //      for (size_t k = 0; k < node->count; k++) {
+  //        fullkey[k] = node->children[k]->keypart;
+  //      }
+  //      fullkey[node->count] = '\0';
+  //      printf("dump @ depth: %d keypart: %d key: %s value: %p fullkey: %s\n",
+  //             depth, node->keypart, keyparts.ptr, node->ptr, fullkey);
+  //    } else {
+  //      printf("dump @ depth: %d keypart: %d key: %s value: %p\n", depth,
+  //             node->keypart, keyparts.ptr, node->ptr);
+  //    }
+  //}
+
+  if (node->ptr != NULL || full) {
+    printf("dump @ depth: %d keypart: %d key: %p value: %p\n", depth,
+           node->keypart, keyparts.ptr, node->ptr);
+  }
+
+  /* Recurse to all children. */
+  for (size_t k = 0; k < node->count; k++) {
+    memuse_rnode_dump(depth + 1, node->children[k], full);
+  }
+}
diff --git a/src/memuse_rnodes.h b/src/memuse_rnodes.h
new file mode 100644
index 0000000000000000000000000000000000000000..e1f4b2bce4ad56d0571e8d74b1d8b705ed2be29d
--- /dev/null
+++ b/src/memuse_rnodes.h
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2018 Peter W. Draper (p.w.draper@durham.ac.uk)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+#ifndef SWIFT_MEMUSE_RNODE_H
+#define SWIFT_MEMUSE_RNODE_H
+
+/* Config parameters. */
+#include "../config.h"
+
+/* Includes. */
+#include <stdlib.h>
+
+/* A radix node, this has a single byte key and a pointer to some related
+ * resource. It also holds a sorted list of children, if any. */
+struct memuse_rnode {
+
+  /* Byte key of this node. */
+  uint8_t keypart;
+
+  /* Value of this node, if set. */
+  void *ptr;
+
+  /* Sorted pointers to children of this node. */
+  struct memuse_rnode **children;
+  unsigned int count;
+};
+
+void memuse_rnode_dump(int depth, struct memuse_rnode *node, int full);
+void memuse_rnode_insert_child(struct memuse_rnode *node, uint8_t depth,
+                               uint8_t *key, uint8_t keylen,
+                               void *value);
+struct memuse_rnode *memuse_rnode_find_child(struct memuse_rnode *node,
+                                             uint8_t depth, uint8_t *key,
+                                             uint8_t keylen);
+void memuse_rnode_cleanup(struct memuse_rnode *node);
+
+#endif /* SWIFT_MEMUSE_RNODE_H */