diff --git a/Makefile.am b/Makefile.am
index f8d85f7c9a2b338353869a1b916fe93cd376b02d..fd3106402afd02080f93c11de7890d7d5f153489 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,13 +19,15 @@
 ACLOCAL_AMFLAGS = -I m4
 
 # Show the way...
-SUBDIRS = src argparse examples doc tests tools
+if HAVECSDS
+SUBDIRS = csds
+else
+SUBDIRS =
+endif
+SUBDIRS += src argparse examples doc tests tools
 if HAVEEAGLECOOLING
 SUBDIRS += examples/Cooling/CoolingRates
 endif
-if HAVECSDS
-SUBDIRS += csds
-endif
 DIST_SUBDIRS = $(SUBDIRS) examples/Cooling/CoolingRates
 
 # Non-standard files that should be part of the distribution.
diff --git a/autogen.sh b/autogen.sh
index d95a7581501ba184c8aee839fad190276696ef76..77d652602a3caddaaa07140cbdc1726fbde32bad 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -3,22 +3,7 @@
 #  Update generated configuration files, i.e. do work so that a
 #  developer checkout can be configured.
 
-if [ -f csds/Makefile.am ]; then
-    fake_sub=0
-else
-    echo "Creating temporary (fake) submodule files"
-    fake_sub=1
-    mkdir csds/src csds/tests
-    touch csds/Makefile.am csds/src/Makefile.am csds/tests/Makefile.am
-fi
-
 autoreconf --install --symlink
 
-if [ $fake_sub -eq 1 ]; then
-    echo "Removing fake submodule files"
-    rm -rf csds/src csds/tests
-    rm csds/Makefile.am csds/Makefile.in
-fi
-
 exit
 
diff --git a/configure.ac b/configure.ac
index 825b5b8f74bd37120e7376da241002cf8d1d20db..3cfa0558192433cecf3efa479da7d3f23b46fcba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -105,11 +105,12 @@ if test "$with_csds" = "yes"; then
    # Ensure that everything is alright for the CSDS
    if test ! -f csds/Makefile.in; then
       AC_MSG_ERROR([It seems that the submodule "CSDS" was not initialized, please rerun autogen.sh and reconfigure.])
-   fi
+
+   AC_CONFIG_SUBDIRS([csds])
+fi
 
 fi
 AM_CONDITIONAL([HAVECSDS],[test $with_csds = "yes"])
-AM_COND_IF([HAVECSDS], [AC_CONFIG_FILES([csds/Makefile csds/src/Makefile csds/tests/Makefile])])
 
 
 
@@ -1176,45 +1177,6 @@ AC_ARG_WITH([random-seed],
 )
 AC_DEFINE_UNQUOTED([SWIFT_RANDOM_SEED_XOR], [$with_random_seed],[Value of the random seed.])
 
-# Check for python.
-have_python="no"
-AC_ARG_WITH([python],
-    [AS_HELP_STRING([--with-python=PATH],
-       [root directory where python is installed @<:@yes/no@:>@]
-    )],
-    [with_python="$withval"],
-    [with_python="no"]
-)
-if test "x$with_python" != "xno"; then
-   if test "$with_python" == ""; then
-      # use linux default python
-      with_python="/usr/"
-   fi
-   AM_PATH_PYTHON([3], [], [AC_MSG_ERROR(python not found)])   
-   AC_ARG_VAR([PYTHON_LIBS], [Linking flags for python, bypassing python-config])
-   AC_ARG_VAR([PYTHON_INCS], [Include flags for python, bypassing python-config])
-   AC_ARG_VAR([PYTHON_CONFIG], [Path to python-config])
-   AS_IF([test -z "$PYTHON_INCS"], [
-      AS_IF([test -z "$PYTHON_CONFIG"], [
-      	AC_PATH_PROGS([PYTHON_CONFIG],
-	          [python$PYTHON_VERSION-config python-config],
-                  [no],
-                  [`dirname $PYTHON`])
-    	AS_IF([test "$PYTHON_CONFIG" = no], [AC_MSG_ERROR([cannot find python-config for $PYTHON.])])
-      ])
-      AC_MSG_CHECKING([python include flags])
-      PYTHON_INCS=`$PYTHON_CONFIG --includes`
-      PYTHON_LIBS=`$PYTHON_CONFIG --ldflags`
-      AC_MSG_RESULT([$PYTHON_INCS])
-      AC_MSG_RESULT([$PYTHON_LIBS])
-  ])
-  have_python="yes"
-  AC_DEFINE([HAVE_PYTHON],1,[Python appears to be present.])
-fi
-AC_SUBST([PYTHON_INCS])
-AC_SUBST([PYTHON_LIBS])
-AM_CONDITIONAL([HAVEPYTHON],[test -n "$PYTHON_INCS"])
-
 
 # Check for HDF5. This is required.
 AX_LIB_HDF5
@@ -2641,6 +2603,5 @@ AC_MSG_RESULT([
    Planetary fixed entropy     : $planetary_fixed_entropy
 
    Continuous Sim. Data Stream : $with_csds
-   Python enabled              : $have_python
 
  ------------------------])
diff --git a/csds b/csds
index 3a717e3f2ba0ea8b4ffde81a16280048a71d39c0..4a890f127e6b15e863f04a5f7408ffdcd50a59f2 160000
--- a/csds
+++ b/csds
@@ -1 +1 @@
-Subproject commit 3a717e3f2ba0ea8b4ffde81a16280048a71d39c0
+Subproject commit 4a890f127e6b15e863f04a5f7408ffdcd50a59f2
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 64735be2e177d2839c69d718303edb8192b3e72f..465e9335aebf96e73e4b9f010bb1515cafe071ff 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -16,7 +16,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Common flags
-MYFLAGS = 
+MYFLAGS =
 
 # Add the source directory and the non-standard paths to the included library headers to CFLAGS
 AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/argparse $(HDF5_CPPFLAGS) \
@@ -41,6 +41,13 @@ if HAVESTANDALONEFOF
 bin_PROGRAMS += fof
 endif
 
+# Do we have the CSDS?
+if HAVECSDS
+LD_CSDS = ../csds/src/.libs/libcsds_writer.a
+else
+LD_CSDS =
+endif
+
 # Build MPI versions as well?
 if HAVEMPI
 bin_PROGRAMS += swift_mpi
@@ -59,22 +66,22 @@ endif
 # Sources for swift
 swift_SOURCES = main.c
 swift_CFLAGS = $(MYFLAGS) $(AM_CFLAGS) -DENGINE_POLICY="engine_policy_keep $(ENGINE_POLICY_SETAFFINITY)"
-swift_LDADD =  ../src/.libs/libswiftsim.a ../argparse/.libs/libargparse.a $(EXTRA_LIBS)
+swift_LDADD =  ../src/.libs/libswiftsim.a ../argparse/.libs/libargparse.a $(EXTRA_LIBS) $(LD_CSDS)
 
 # Sources for swift_mpi, do we need an affinity policy for MPI?
 swift_mpi_SOURCES = main.c
 swift_mpi_CFLAGS = $(MYFLAGS) $(AM_CFLAGS) $(MPI_FLAGS) -DENGINE_POLICY="engine_policy_keep $(ENGINE_POLICY_SETAFFINITY)"
-swift_mpi_LDADD =  ../src/.libs/libswiftsim_mpi.a ../argparse/.libs/libargparse.a $(MPI_LIBS) $(EXTRA_LIBS)
+swift_mpi_LDADD =  ../src/.libs/libswiftsim_mpi.a ../argparse/.libs/libargparse.a $(MPI_LIBS) $(EXTRA_LIBS) $(LD_CSDS)
 
 # Sources for fof
 fof_SOURCES = main_fof.c
 fof_CFLAGS = $(MYFLAGS) $(AM_CFLAGS) -DENGINE_POLICY="engine_policy_keep $(ENGINE_POLICY_SETAFFINITY)"
-fof_LDADD =  ../src/.libs/libswiftsim.a ../argparse/.libs/libargparse.a $(EXTRA_LIBS)
+fof_LDADD =  ../src/.libs/libswiftsim.a ../argparse/.libs/libargparse.a $(EXTRA_LIBS) $(LD_CSDS)
 
 # Sources for fof_mpi, do we need an affinity policy for MPI?
 fof_mpi_SOURCES = main_fof.c
 fof_mpi_CFLAGS = $(MYFLAGS) $(AM_CFLAGS) $(MPI_FLAGS) -DENGINE_POLICY="engine_policy_keep $(ENGINE_POLICY_SETAFFINITY)"
-fof_mpi_LDADD =  ../src/.libs/libswiftsim_mpi.a ../argparse/.libs/libargparse.a $(MPI_LIBS) $(EXTRA_LIBS)
+fof_mpi_LDADD =  ../src/.libs/libswiftsim_mpi.a ../argparse/.libs/libargparse.a $(MPI_LIBS) $(EXTRA_LIBS) $(LD_CSDS)
 
 # Scripts to generate ICs
 EXTRA_DIST = Cooling/CoolingBox/coolingBox.yml Cooling/CoolingBox/plotEnergy.py Cooling/CoolingBox/makeIC.py Cooling/CoolingBox/run.sh Cooling/CoolingBox/getGlass.sh \
diff --git a/src/Makefile.am b/src/Makefile.am
index 2cf1d890beccfc24a8cff9d5a772543cc1fd2274..369786e94ae65e69b37d55e2c36e011de99a5f1e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -48,7 +48,7 @@ include_HEADERS += common_io.h single_io.h distributed_io.h map.h tools.h  parti
 include_HEADERS += partition.h clocks.h parser.h physical_constants.h physical_constants_cgs.h potential.h version.h 
 include_HEADERS += hydro_properties.h riemann.h threadpool.h cooling_io.h cooling.h cooling_struct.h cooling_properties.h 
 include_HEADERS += statistics.h memswap.h cache.h runner_doiact_hydro_vec.h profiler.h entropy_floor.h 
-include_HEADERS += dump.h csds.h active.h timeline.h xmf.h gravity_properties.h gravity_derivatives.h 
+include_HEADERS += csds.h active.h timeline.h xmf.h gravity_properties.h gravity_derivatives.h 
 include_HEADERS += gravity_softened_derivatives.h vector_power.h collectgroup.h hydro_space.h sort_part.h 
 include_HEADERS += chemistry.h chemistry_io.h chemistry_struct.h cosmology.h restart.h space_getsid.h utilities.h 
 include_HEADERS += mesh_gravity.h cbrt.h exp10.h velociraptor_interface.h swift_velociraptor_part.h output_list.h 
@@ -129,7 +129,7 @@ AM_SOURCES += kernel_hydro.c tools.c map.c part.c partition.c clocks.c
 AM_SOURCES += physical_constants.c units.c potential.c hydro_properties.c 
 AM_SOURCES += threadpool.c cooling.c star_formation.c 
 AM_SOURCES += hydro.c stars.c
-AM_SOURCES += statistics.c profiler.c dump.c csds.c part_type.c 
+AM_SOURCES += statistics.c profiler.c csds.c part_type.c 
 AM_SOURCES += gravity_properties.c gravity.c multipole.c 
 AM_SOURCES += collectgroup.c hydro_space.c equation_of_state.c io_compression.c 
 AM_SOURCES += chemistry.c cosmology.c mesh_gravity.c velociraptor_interface.c 
diff --git a/src/csds.c b/src/csds.c
index 2ea5f62a67c856f903e502508f8d5552a29376f2..9d2d2964489370cf6034c57f11a705a411299562 100644
--- a/src/csds.c
+++ b/src/csds.c
@@ -41,7 +41,6 @@
 #include "active.h"
 #include "atomic.h"
 #include "chemistry_csds.h"
-#include "dump.h"
 #include "engine.h"
 #include "error.h"
 #include "gravity_csds.h"
@@ -50,91 +49,6 @@
 #include "stars_csds.h"
 #include "units.h"
 
-/*
- * Thoses are definitions from the format and therefore should not be changed!
- */
-/* Number of bytes for a mask. */
-// TODO change this to number of bits
-#define csds_mask_size 2
-
-/* Number of bits for record header. */
-#define csds_header_bytes 8
-
-/* Number bytes for an offset. */
-#define csds_offset_size csds_header_bytes - csds_mask_size
-
-/* Number of bytes for the file format information. */
-#define csds_format_size 20
-
-char csds_file_format[csds_format_size] = "SWIFT_CSDS";
-
-/*
- * The two following defines need to correspond to the list's order
- * in csds_init_masks.
- */
-/* Index of the special flags in the list of masks */
-#define csds_index_special_flags 0
-/* Index of the timestamp in the list of masks */
-#define csds_index_timestamp 1
-
-/**
- * @brief Print the current size used by the logger in GB (not the allocated
- * one).
- *
- * @param log The #csds_writer.
- * @param e The #engine.
- */
-float csds_get_current_filesize_used_gb(const struct csds_writer *log,
-                                        const struct engine *e) {
-  return log->dump.count / (1024.f * 1024.f * 1024.f);
-}
-
-/**
- * @brief Write the header of a record (offset + mask).
- *
- * This is maybe broken for big(?) endian.
- *
- * @param buff The buffer where to write the mask and offset.
- * @param mask The mask to write inside the buffer.
- * @param offset The offset of the previous record.
- * @param offset_new The offset of the current record.
- *
- * @return updated buff
- */
-char *csds_write_record_header(char *buff, const unsigned int *mask,
-                               const size_t *offset, const size_t offset_new) {
-  /* write mask. */
-  memcpy(buff, mask, csds_mask_size);
-  buff += csds_mask_size;
-
-  /* write offset. */
-  uint64_t diff_offset = offset_new - *offset;
-  memcpy(buff, &diff_offset, csds_offset_size);
-  buff += csds_offset_size;
-
-  return buff;
-}
-
-/**
- * @brief Write to the dump.
- *
- * @param d #dump file
- * @param offset (return) offset of the data
- * @param size number of bytes to write
- * @param p pointer to the data
- */
-void csds_write_data(struct dump *d, size_t *offset, size_t size,
-                     const void *p) {
-  /* get buffer. */
-  char *buff = dump_get(d, size, offset);
-
-  /* write data to the buffer. */
-  memcpy(buff, p, size);
-
-  /* Update offset to end of record. */
-  *offset += size;
-}
-
 /**
  * @brief log all particles in the engine.
  *
@@ -229,11 +143,11 @@ void csds_copy_part_fields(const struct csds_writer *log, const struct part *p,
   buff = csds_write_record_header(buff, &mask, offset, offset_new);
 
   /* Special flags */
-  if (mask & log->list_fields[csds_index_special_flags].mask) {
+  if (mask & log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask) {
     memcpy(buff, &special_flags,
-           log->list_fields[csds_index_special_flags].size);
-    buff += log->list_fields[csds_index_special_flags].size;
-    mask &= ~log->list_fields[csds_index_special_flags].mask;
+           log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size);
+    buff += log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size;
+    mask &= ~log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask;
   }
 
   /* Write the hydro fields */
@@ -333,7 +247,7 @@ void csds_log_parts(struct csds_writer *log, const struct part *p,
                     const enum csds_special_flags flag, const int flag_data) {
 
   /* Build the special flag */
-  const int size_special_flag = log->list_fields[csds_index_special_flags].size;
+  const int size_special_flag = log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size;
   const uint32_t special_flags =
       csds_pack_flags_and_data(flag, flag_data, swift_type_gas);
 
@@ -346,14 +260,15 @@ void csds_log_parts(struct csds_writer *log, const struct part *p,
   /* Add the flag */
   if (flag != csds_flag_none) {
     size += size_special_flag;
-    mask |= log->list_fields[csds_index_special_flags].mask;
+    mask |= log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask;
   }
-  size += csds_header_bytes;
+  size += CSDS_HEADER_SIZE;
   size_t size_total = count * size;
 
-  /* Allocate a chunk of memory in the dump of the right size. */
+  /* Allocate a chunk of memory in the logfile of the right size. */
   size_t offset_new;
-  char *buff = (char *)dump_get(&log->dump, size_total, &offset_new);
+  char *buff =
+      (char *)csds_logfile_writer_get(&log->logfile, size_total, &offset_new);
 
 #ifdef SWIFT_DEBUG_CHECKS
   /* Save the buffer position in order to test if the requested buffer was
@@ -418,11 +333,11 @@ void csds_copy_spart_fields(const struct csds_writer *log,
   buff = csds_write_record_header(buff, &mask, offset, offset_new);
 
   /* Special flags */
-  if (mask & log->list_fields[csds_index_special_flags].mask) {
+  if (mask & log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask) {
     memcpy(buff, &special_flags,
-           log->list_fields[csds_index_special_flags].size);
-    buff += log->list_fields[csds_index_special_flags].size;
-    mask &= ~log->list_fields[csds_index_special_flags].mask;
+           log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size);
+    buff += log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size;
+    mask &= ~log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask;
   }
 
   /* Write the stellar fields */
@@ -488,7 +403,7 @@ void csds_log_sparts(struct csds_writer *log, struct spart *sp, int count,
                      const struct engine *e, const int log_all_fields,
                      const enum csds_special_flags flag, const int flag_data) {
   /* Build the special flag */
-  const int size_special_flag = log->list_fields[csds_index_special_flags].size;
+  const int size_special_flag = log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size;
   const uint32_t special_flags =
       csds_pack_flags_and_data(flag, flag_data, swift_type_stars);
 
@@ -502,15 +417,16 @@ void csds_log_sparts(struct csds_writer *log, struct spart *sp, int count,
 
   /* Add the flag */
   if (flag != csds_flag_none) {
-    mask |= log->list_fields[csds_index_special_flags].mask;
+    mask |= log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask;
     size += size_special_flag;
   }
-  size += csds_header_bytes;
+  size += CSDS_HEADER_SIZE;
   size_t size_total = count * size;
 
-  /* Allocate a chunk of memory in the dump of the right size. */
+  /* Allocate a chunk of memory in the logfile of the right size. */
   size_t offset_new;
-  char *buff = (char *)dump_get(&log->dump, size_total, &offset_new);
+  char *buff =
+      (char *)csds_logfile_writer_get(&log->logfile, size_total, &offset_new);
 #ifdef SWIFT_DEBUG_CHECKS
   /* Save the buffer position in order to test if the requested buffer was
    * really used */
@@ -571,11 +487,11 @@ void csds_copy_gpart_fields(const struct csds_writer *log,
   buff = csds_write_record_header(buff, &mask, offset, offset_new);
 
   /* Special flags */
-  if (mask & log->list_fields[csds_index_special_flags].mask) {
+  if (mask & log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask) {
     memcpy(buff, &special_flags,
-           log->list_fields[csds_index_special_flags].size);
-    buff += log->list_fields[csds_index_special_flags].size;
-    mask &= ~log->list_fields[csds_index_special_flags].mask;
+           log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size);
+    buff += log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size;
+    mask &= ~log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask;
   }
 
   /* Write the gravity fields */
@@ -641,7 +557,7 @@ void csds_log_gparts(struct csds_writer *log, struct gpart *p, int count,
                      const struct engine *e, const int log_all_fields,
                      const enum csds_special_flags flag, const int flag_data) {
   /* Build the special flag */
-  const int size_special_flag = log->list_fields[csds_index_special_flags].size;
+  const int size_special_flag = log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].size;
   const uint32_t special_flags =
       csds_pack_flags_and_data(flag, flag_data, swift_type_dark_matter);
 
@@ -665,15 +581,16 @@ void csds_log_gparts(struct csds_writer *log, struct gpart *p, int count,
 
   /* Add the flag */
   if (flag != csds_flag_none) {
-    mask |= log->list_fields[csds_index_special_flags].mask;
+    mask |= log->list_fields[CSDS_SPECIAL_FLAGS_INDEX].mask;
     size += size_special_flag;
   }
-  size += csds_header_bytes;
+  size += CSDS_HEADER_SIZE;
   size_t size_total = size * count_dm;
 
-  /* Allocate a chunk of memory in the dump of the right size. */
+  /* Allocate a chunk of memory in the logfile of the right size. */
   size_t offset_new;
-  char *buff = (char *)dump_get(&log->dump, size_total, &offset_new);
+  char *buff =
+      (char *)csds_logfile_writer_get(&log->logfile, size_total, &offset_new);
 #ifdef SWIFT_DEBUG_CHECKS
   /* Save the buffer position in order to test if the requested buffer was
    * really used */
@@ -722,17 +639,17 @@ void csds_log_gparts(struct csds_writer *log, struct gpart *p, int count,
  */
 void csds_log_timestamp(struct csds_writer *log, integertime_t timestamp,
                         double time, size_t *offset) {
-  struct dump *dump = &log->dump;
+  struct csds_logfile_writer *logfile = &log->logfile;
   /* Start by computing the size of the message. */
   const int size =
-      log->list_fields[csds_index_timestamp].size + csds_header_bytes;
+      log->list_fields[CSDS_TIMESTAMP_INDEX].size + CSDS_HEADER_SIZE;
 
-  /* Allocate a chunk of memory in the dump of the right size. */
+  /* Allocate a chunk of memory in the logfile of the right size. */
   size_t offset_new;
-  char *buff = (char *)dump_get(dump, size, &offset_new);
+  char *buff = (char *)csds_logfile_writer_get(logfile, size, &offset_new);
 
   /* Write the header. */
-  unsigned int mask = log->list_fields[csds_index_timestamp].mask;
+  unsigned int mask = log->list_fields[CSDS_TIMESTAMP_INDEX].mask;
   buff = csds_write_record_header(buff, &mask, offset, offset_new);
 
   /* Store the timestamp. */
@@ -774,20 +691,20 @@ void csds_ensure_size(struct csds_writer *log, const struct engine *e) {
   // TODO improve estimate with the size of each particle
   limit *= log->max_record_size;
 
-  /* ensure enough space in dump */
-  dump_ensure(&log->dump, limit, log->buffer_scale * limit);
+  /* ensure enough space in logfile */
+  csds_logfile_writer_ensure(&log->logfile, limit, log->buffer_scale * limit);
 
   if (e->verbose)
     message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
             clocks_getunit());
 }
 
-/** @brief Generate the name of the dump files
+/** @brief Generate the name of the logfile files
  *
  * @param log The #csds_writer.
- * @param filename The filename of the dump file.
+ * @param filename The filename of the logfile file.
  */
-void csds_get_dump_name(struct csds_writer *log, char *filename) {
+void csds_get_logfile_name(struct csds_writer *log, char *filename) {
   sprintf(filename, "%s_%04i.dump", log->base_name, engine_rank);
 }
 
@@ -809,27 +726,27 @@ void csds_init_masks(struct csds_writer *log, const struct engine *e) {
 
   /* The next fields must be the two first ones. */
   /* Add the special flags (written manually => no need of offset) */
-  if (csds_index_special_flags != 0) {
+  if (CSDS_SPECIAL_FLAGS_INDEX != 0) {
     error("Expecting the special flags to be the first element.");
   }
-  csds_define_common_field(list[csds_index_special_flags], "SpecialFlags",
+  csds_define_common_field(list[CSDS_SPECIAL_FLAGS_INDEX], "SpecialFlags",
                            sizeof(uint32_t));
   num_fields += 1;
 
   /* Add the timestamp */
-  if (csds_index_timestamp != 1) {
+  if (CSDS_TIMESTAMP_INDEX != 1) {
     error("Expecting the timestamp to be the first element.");
   }
-  csds_define_common_field(list[csds_index_timestamp], "Timestamp",
+  csds_define_common_field(list[CSDS_TIMESTAMP_INDEX], "Timestamp",
                            sizeof(integertime_t) + sizeof(double));
-  list[num_fields].type = mask_type_timestep;  // flag it as timestamp
+  list[num_fields].type = mask_for_timestep;  // flag it as timestamp
   num_fields += 1;
 
   /* Initialize all the particles types */
   for (int i = 0; i < swift_type_count; i++) {
     int tmp_num_fields = 0;
     struct csds_field *current = &list[num_fields];
-    enum mask_type mask_type;
+    enum mask_for_type mask_for_type;
 
     /* Set the pointer */
     log->field_pointers[i] = current;
@@ -838,7 +755,7 @@ void csds_init_masks(struct csds_writer *log, const struct engine *e) {
       /* Hydro */
       case swift_type_gas:
         /* Set the mask type */
-        mask_type = mask_type_gas;
+        mask_for_type = mask_for_gas;
 
         /* Set the masks */
         tmp_num_fields = csds_hydro_define_fields(current);
@@ -850,7 +767,7 @@ void csds_init_masks(struct csds_writer *log, const struct engine *e) {
       /* Stars */
       case swift_type_stars:
         /* Set the mask type */
-        mask_type = mask_type_stars;
+        mask_for_type = mask_for_stars;
 
         /* Set the masks */
         tmp_num_fields = csds_stars_define_fields(current);
@@ -862,7 +779,7 @@ void csds_init_masks(struct csds_writer *log, const struct engine *e) {
 
       case swift_type_dark_matter:
         /* Set the mask type */
-        mask_type = mask_type_dark_matter;
+        mask_for_type = mask_for_dark_matter;
 
         /* Set the masks */
         tmp_num_fields = csds_gravity_define_fields(current);
@@ -875,7 +792,7 @@ void csds_init_masks(struct csds_writer *log, const struct engine *e) {
 
     /* Set the particle type */
     for (int j = 0; j < tmp_num_fields; j++) {
-      current[j].type = mask_type;
+      current[j].type = mask_for_type;
     }
 
     /* Update the number of fields */
@@ -924,7 +841,7 @@ void csds_init_masks(struct csds_writer *log, const struct engine *e) {
   }
 
   /* Check that we have enough available flags. */
-  if (mask >= 8 * csds_mask_size) {
+  if (mask >= 8 * CSDS_MASK_SIZE) {
     error(
         "Not enough available flags for all the fields. "
         "Please reduce the number of output fields.");
@@ -988,24 +905,24 @@ void csds_init(struct csds_writer *log, const struct engine *e,
   /* set initial value of parameters. */
   log->timestamp_offset = 0;
 
-  /* generate dump filename. */
+  /* generate logfile filename. */
   char csds_name_file[PARSER_MAX_LINE_SIZE];
-  csds_get_dump_name(log, csds_name_file);
+  csds_get_logfile_name(log, csds_name_file);
 
   /* Compute max size for a particle record. */
-  int max_size = csds_offset_size + csds_mask_size;
+  int max_size = CSDS_OFFSET_SIZE + CSDS_MASK_SIZE;
 
   /* Loop over all fields except timestamp. */
   for (int i = 0; i < log->total_number_fields; i++) {
     /* Skip the timestamp */
-    if (i == csds_index_timestamp) continue;
+    if (i == CSDS_TIMESTAMP_INDEX) continue;
 
     max_size += log->list_fields[i].size;
   }
   log->max_record_size = max_size;
 
-  /* init dump. */
-  dump_init(&log->dump, csds_name_file, buffer_size);
+  /* init logfile. */
+  csds_logfile_writer_init(&log->logfile, csds_name_file, buffer_size);
 
   if (e->verbose)
     message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
@@ -1013,12 +930,12 @@ void csds_init(struct csds_writer *log, const struct engine *e,
 }
 
 /**
- * @brief Close dump file and desallocate memory
+ * @brief Close logfile file and desallocate memory
  *
  * @param log The #csds_writer
  */
 void csds_free(struct csds_writer *log) {
-  dump_close(&log->dump);
+  csds_logfile_writer_close(&log->logfile);
 
   free(log->list_fields);
   log->list_fields = NULL;
@@ -1034,39 +951,16 @@ void csds_free(struct csds_writer *log) {
 void csds_write_file_header(struct csds_writer *log) {
 
   /* get required variables. */
-  struct dump *dump = &log->dump;
-
-  uint64_t file_offset = dump->file_offset;
-
-  if (file_offset != 0)
-    error(
-        "The CSDS is not empty."
-        "This function should be called before writing anything in the CSDS");
-
-  /* Write format information. */
-  csds_write_data(dump, &file_offset, csds_format_size, &csds_file_format);
-
-  /* Write the major version number. */
-  int major = csds_major_version;
-  csds_write_data(dump, &file_offset, sizeof(int), &major);
-
-  /* Write the minor version number. */
-  int minor = csds_minor_version;
-  csds_write_data(dump, &file_offset, sizeof(int), &minor);
-
-  /* write offset direction. */
-  const int reversed = 0;
-  csds_write_data(dump, &file_offset, sizeof(int), &reversed);
-
-  /* placeholder to write the offset of the first log here. */
-  char *skip_header = dump_get(dump, csds_offset_size, &file_offset);
+  struct csds_logfile_writer *logfile = &log->logfile;
 
-  /* write number of bytes used for names. */
-  const unsigned int label_size = csds_string_length;
-  csds_write_data(dump, &file_offset, sizeof(unsigned int), &label_size);
+  /* Write the beginning of the header */
+  char *offset_first_record =
+      csds_logfile_writer_write_begining_header(logfile);
 
   /* placeholder to write the number of unique masks. */
-  char *skip_unique_masks = dump_get(dump, sizeof(unsigned int), &file_offset);
+  size_t file_offset = 0;
+  char *skip_unique_masks =
+      csds_logfile_writer_get(logfile, sizeof(unsigned int), &file_offset);
 
   /* write masks. */
   // loop over all mask type.
@@ -1088,17 +982,17 @@ void csds_write_file_header(struct csds_writer *log) {
     unique_mask += 1;
 
     // mask name.
-    csds_write_data(dump, &file_offset, csds_string_length,
+    csds_write_data(logfile, &file_offset, CSDS_STRING_SIZE,
                     &log->list_fields[i].name);
 
     // mask size.
-    csds_write_data(dump, &file_offset, sizeof(unsigned int),
+    csds_write_data(logfile, &file_offset, sizeof(unsigned int),
                     &log->list_fields[i].size);
   }
   memcpy(skip_unique_masks, &unique_mask, sizeof(unsigned int));
 
   /* Write the number of fields per particle */
-  csds_write_data(dump, &file_offset, sizeof(log->number_fields),
+  csds_write_data(logfile, &file_offset, sizeof(log->number_fields),
                   log->number_fields);
 
   /* Now write the order for each particle type */
@@ -1115,15 +1009,15 @@ void csds_write_file_header(struct csds_writer *log) {
       /* Find the index among all the fields. */
       for (int m = 0; m < log->total_number_fields; m++) {
         if (log->list_fields[m].mask == current_mask) {
-          csds_write_data(dump, &file_offset, sizeof(int), &m);
+          csds_write_data(logfile, &file_offset, sizeof(int), &m);
           break;
         }
       }
     }
   }
 
-  /* last step: write first offset. */
-  memcpy(skip_header, &file_offset, csds_offset_size);
+  /* Write the end of the header. */
+  csds_logfile_writer_write_end_header(logfile, offset_first_record);
 }
 
 /**
@@ -1138,14 +1032,14 @@ void csds_write_file_header(struct csds_writer *log) {
  */
 __attribute__((always_inline)) INLINE static int csds_read_record_header(
     const char *buff, unsigned int *mask, size_t *offset, size_t cur_offset) {
-  memcpy(mask, buff, csds_mask_size);
-  buff += csds_mask_size;
+  memcpy(mask, buff, CSDS_MASK_SIZE);
+  buff += CSDS_MASK_SIZE;
 
   *offset = 0;
-  memcpy(offset, buff, csds_offset_size);
+  memcpy(offset, buff, CSDS_OFFSET_SIZE);
   *offset = cur_offset - *offset;
 
-  return csds_mask_size + csds_offset_size;
+  return CSDS_MASK_SIZE + CSDS_OFFSET_SIZE;
 }
 
 /**
@@ -1171,7 +1065,7 @@ int csds_read_part(const struct csds_writer *log, struct part *p,
 
   for (int i = 0; i < log->total_number_fields; i++) {
     if ((mask & log->list_fields[i].mask) &&
-        (log->list_fields[i].type == mask_type_gas)) {
+        (log->list_fields[i].type == mask_for_gas)) {
 
       const char *name = log->list_fields[i].name;
       if (strcmp("Coordinates", name) == 0) {
@@ -1234,7 +1128,7 @@ int csds_read_gpart(const struct csds_writer *log, struct gpart *p,
 
   for (int i = 0; i < log->total_number_fields; i++) {
     if ((mask & log->list_fields[i].mask) &&
-        (log->list_fields[i].type == mask_type_dark_matter)) {
+        (log->list_fields[i].type == mask_for_dark_matter)) {
 
       const char *name = log->list_fields[i].name;
       if (strcmp("Coordinates", name) == 0) {
@@ -1286,11 +1180,11 @@ int csds_read_timestamp(const struct csds_writer *log, integertime_t *t,
   buff += csds_read_record_header(buff, &mask, offset, cur_offset);
 
   /* We are only interested in timestamps. */
-  if (!(mask & log->list_fields[csds_index_timestamp].mask))
+  if (!(mask & log->list_fields[CSDS_TIMESTAMP_INDEX].mask))
     error("Trying to read timestamp from a particle.");
 
   /* Make sure we don't have extra fields. */
-  if (mask != log->list_fields[csds_index_timestamp].mask)
+  if (mask != log->list_fields[CSDS_TIMESTAMP_INDEX].mask)
     error("Timestamp message contains extra fields.");
 
   /* Copy the timestamp value from the buffer. */
@@ -1348,11 +1242,11 @@ void csds_struct_restore(struct csds_writer *log, FILE *stream) {
         log->list_fields + (log->field_pointers[i] - old_list_fields);
   }
 
-  /* Restart the dump file. */
+  /* Restart the logfile. */
   char csds_name_file[PARSER_MAX_LINE_SIZE];
-  csds_get_dump_name(log, csds_name_file);
+  csds_get_logfile_name(log, csds_name_file);
 
-  dump_restart(&log->dump, csds_name_file);
+  csds_logfile_writer_restart(&log->logfile, csds_name_file);
 }
 
 #endif /* WITH_CSDS */
diff --git a/src/csds.h b/src/csds.h
index 2ecfd64d8fcc24a539947d0ef1e291caf2ce7b60..c327ff39f7b53f0d1cebed2cb810b81600fef140 100644
--- a/src/csds.h
+++ b/src/csds.h
@@ -27,32 +27,19 @@
 /* Includes. */
 #include "align.h"
 #include "common_io.h"
-#include "dump.h"
 #include "error.h"
 #include "inline.h"
 #include "timeline.h"
 #include "units.h"
 
+/* Include the CSDS */
+#include "csds/src/csds_logfile_writer.h"
+
 /* Forward declaration. */
-struct dump;
 struct gpart;
 struct part;
 struct engine;
 
-#define csds_major_version 1
-#define csds_minor_version 4
-/* Size of the strings. */
-#define csds_string_length 200
-
-/*
- * The two following defines need to correspond to the list's order
- * in csds_init_masks.
- */
-/* Index of the special flags in the list of masks */
-#define csds_index_special_flags 0
-/* Index of the timestamp in the list of masks */
-#define csds_index_timestamp 1
-
 /**
  * Csds entries contain messages representing the particle data at a given
  * point in time during the simulation.
@@ -60,47 +47,22 @@ struct engine;
  * The csds messages always start with an 8-byte header structured as
  * follows:
  *
- *   data: [ mask |                     offset                     ]
+ *   data: [ mask        |              offset                     ]
  *   byte: [  01  |  02  |  03  |  04  |  05  |  06  |  07  |  08  ]
  *
- * I.e. a first "mask" byte followed by 7 "offset" bytes. The mask contains
+ * I.e. a first "mask" byte followed by 6 "offset" bytes. The mask contains
  * information on what kind of data is packed after the header. The mask
  * bits correspond to the following data:
  *
- *   bit | name   | size | comment
- *   -------------------------------------------------------------------------
- *   0   | x      | 24   | The particle position, in absolute coordinates,
- *       |        |      | stored as three doubles.
- *   1   | v      | 12   | Particle velocity, stored as three floats.
- *   2   | a      | 12   | Particle acceleration, stored as three floats.
- *   3   | u      | 4    | Particle internal energy (or entropy, if Gadget-SPH
- *       |        |      | is used), stored as a single float.
- *   4   | h      | 4    | Particle smoothing length (or epsilon, if a gpart),
- *       |        |      | stored as a single float.
- *   5   | rho    | 4    | Particle density, stored as a single float.
- *   6   | consts | 12   | Particle constants, i.e. mass and ID.
- *   7   | time   | 8    | Timestamp, not associated with a particle, just
- *       |        |      | marks the transitions from one timestep to another.
- *
  * There is no distinction between gravity and SPH particles.
  *
  * The offset refers to the relative location of the previous message for the
- * same particle or for the previous timestamp (if mask bit 7 is set). I.e.
+ * same particle or for the previous timestamp. I.e.
  * the previous log entry will be at the address of the current mask byte minus
  * the unsigned value stored in the offset. An offset equal to the record offset
  * indicated that this is the first message for the given particle/timestamp.
  */
 
-enum csds_special_flags {
-  csds_flag_none = 0,        /* No flag */
-  csds_flag_change_type = 1, /* Flag for a change of particle type */
-  csds_flag_mpi_enter, /* Flag for a particle received from another  MPI rank
-                        */
-  csds_flag_mpi_exit,  /* Flag for a particle sent to another MPI rank */
-  csds_flag_delete,    /* Flag for a deleted particle */
-  csds_flag_create,    /* Flag for a created particle */
-} __attribute__((packed));
-
 /**
  * @brief structure containing global data for the particle csds.
  */
@@ -109,11 +71,10 @@ struct csds_writer {
   short int delta_step;
 
   /* Csds basename. */
-  char base_name[csds_string_length];
+  char base_name[CSDS_STRING_SIZE];
 
-  /*  Dump file (In the reader, the dump is cleaned, therefore it is renamed
-   * logfile). */
-  struct dump dump;
+  /*  The logfile writer. */
+  struct csds_logfile_writer logfile;
 
   /* timestamp offset for csds. */
   size_t timestamp_offset;
@@ -148,8 +109,6 @@ struct csds_part_data {
 };
 
 /* Function prototypes. */
-float csds_get_current_filesize_used_gb(const struct csds_writer *log,
-                                        const struct engine *e);
 void csds_log_all_particles(struct csds_writer *log, const struct engine *e,
                             int first_log);
 void csds_log_part(struct csds_writer *log, const struct part *p,
@@ -189,32 +148,6 @@ int csds_read_timestamp(const struct csds_writer *log, integertime_t *t,
 void csds_struct_dump(const struct csds_writer *log, FILE *stream);
 void csds_struct_restore(struct csds_writer *log, FILE *stream);
 
-/**
- * @brief Generate the data for the special flags.
- *
- * @param flag The special flag to use.
- * @param flag_data The data to write in the record.
- * @param type The type of the particle.
- */
-INLINE static uint32_t csds_pack_flags_and_data(enum csds_special_flags flag,
-                                                int flag_data,
-                                                enum part_type type) {
-#ifdef SWIFT_DEBUG_CHECKS
-  if (flag & 0xFFFFFF00) {
-    error(
-        "The special flag in the particle CSDS cannot be larger than 1 "
-        "byte.");
-  }
-  if (flag_data & ~0xFFFF) {
-    error(
-        "The data for the special flag in the particle CSDS cannot be larger "
-        "than 2 bytes.");
-  }
-#endif
-  return ((uint32_t)flag << (3 * 8)) | ((flag_data & 0xFFFF) << 8) |
-         (type & 0xFF);
-}
-
 /**
  * @brief Initialize the csds data for a particle.
  *
diff --git a/src/csds_io.c b/src/csds_io.c
index 1c0145a9e5672af4b86d31b5d55712a4a66a2bd6..0400e783eb8b28e0828900419af66a57baf525f7 100644
--- a/src/csds_io.c
+++ b/src/csds_io.c
@@ -40,28 +40,7 @@
 #include "csds_io.h"
 
 /* Local includes. */
-#include "chemistry_io.h"
-#include "common_io.h"
-#include "cooling_io.h"
-#include "dimension.h"
-#include "engine.h"
-#include "error.h"
-#include "gravity_io.h"
-#include "gravity_properties.h"
-#include "hydro_io.h"
-#include "hydro_properties.h"
-#include "io_properties.h"
-#include "kernel_hydro.h"
-#include "parallel_io.h"
-#include "part.h"
-#include "serial_io.h"
-#include "single_io.h"
-#include "stars_io.h"
-#include "threadpool.h"
-#include "tracers_io.h"
-#include "units.h"
 #include "version.h"
-#include "xmf.h"
 
 /**
  * @brief Write the parameters into a yaml file.
diff --git a/src/csds_io.h b/src/csds_io.h
index beac33a6a72e9804fc3393ef2208e3447a57c678..4f86e1dadd0f63ce03d2f6c714f402d0bc812e88 100644
--- a/src/csds_io.h
+++ b/src/csds_io.h
@@ -33,24 +33,24 @@
 /* This enum defines the type of particle to use
    with a given mask.
    The values should be the same than in part_type.h. */
-enum mask_type {
-  mask_type_gas = 0,
-  mask_type_dark_matter = 1,
+enum mask_for_type {
+  mask_for_gas = 0,
+  mask_for_dark_matter = 1,
   /* Only need a single type of dm. */
-  mask_type_stars = 4,
-  mask_type_black_hole = 5,
-  mask_type_timestep = -1,
+  mask_for_stars = 4,
+  mask_for_black_hole = 5,
+  mask_for_timestep = -1,
 } __attribute__((packed));
 
 struct csds_field {
   /* Name of the field */
-  char name[csds_string_length];
+  char name[CSDS_STRING_SIZE];
 
   /* Mask value. */
   unsigned int mask;
 
   /* Type of particle (follow part_type.h and -1 for timestamp). */
-  enum mask_type type;
+  enum mask_for_type type;
 
   /* The offset of the field within the particle */
   size_t offset;
@@ -82,7 +82,7 @@ struct csds_field {
   {                                                                  \
     csds_field.offset = 0;                                           \
     csds_field.size = size_field;                                    \
-    if (strlen(field_name) >= csds_string_length)                    \
+    if (strlen(field_name) >= CSDS_STRING_SIZE)                      \
       error("Name %s too long", field_name);                         \
     strcpy(csds_field.name, field_name);                             \
     csds_field.mask = 0;                                             \
@@ -105,7 +105,7 @@ struct csds_field {
     csds_field.offset = offsetof(part, field);                          \
     part *tmp;                                                          \
     csds_field.size = sizeof(tmp->field);                               \
-    if (strlen(field_name) >= csds_string_length)                       \
+    if (strlen(field_name) >= CSDS_STRING_SIZE)                         \
       error("Name %s too long", field_name);                            \
     strcpy(csds_field.name, field_name);                                \
     csds_field.mask = 0;                                                \
@@ -145,7 +145,7 @@ struct csds_field {
 #define csds_define_field_from_function_general(                    \
     csds_field, field_name, conversion_func, field_size, part_type) \
   {                                                                 \
-    if (strlen(field_name) >= csds_string_length)                   \
+    if (strlen(field_name) >= CSDS_STRING_SIZE)                     \
       error("Name %s too long", field_name);                        \
     strcpy(csds_field.name, field_name);                            \
     csds_field.size = field_size;                                   \
diff --git a/src/dump.c b/src/dump.c
deleted file mode 100644
index 5d2c1ae69194f76e5ebd70e873f7064f0d6e5b33..0000000000000000000000000000000000000000
--- a/src/dump.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*******************************************************************************
- * This file is part of SWIFT.
- * Copyright (c) 2016 Pedro Gonnet (pedro.gonnet@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/>.
- *
- ******************************************************************************/
-
-/* Config parameters. */
-#include "../config.h"
-
-#ifdef HAVE_POSIX_FALLOCATE
-
-/* This object's header. */
-#include "dump.h"
-
-/* Local headers. */
-#include "atomic.h"
-#include "error.h"
-
-/* Some standard headers. */
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-/**
- * @brief Obtain a chunk of memory from a dump.
- *
- * @param d The #dump.
- * @param count The number of bytes requested.
- * @param offset The offset of the returned memory address within the dump file.
- * @return A pointer to the memory-mapped chunk of data.
- */
-void *dump_get(struct dump *d, size_t count, size_t *offset) {
-  size_t local_offset = atomic_add(&d->count, count);
-#ifdef SWIFT_DEBUG_CHECKS
-  if (d->count > d->size) error("Dump file is too small.");
-#endif
-  *offset = local_offset + d->file_offset;
-  return (char *)d->data + local_offset;
-}
-
-/**
- * @brief Ensure that at least size bytes are available in the #dump.
- *
- * @param d The #dump.
- * @param required_size The required size for the #dump
- * @param increase_size If not enough size, increase by this amount
- */
-void dump_ensure(struct dump *d, size_t required_size, size_t increase_size) {
-
-  /* If we have enough space already, just bail. */
-  if (d->size - d->count > required_size) return;
-
-  /* Unmap the current data. */
-  if (munmap(d->data, d->size) != 0) {
-    error("Failed to unmap %zi bytes of dump data (%s).", d->size,
-          strerror(errno));
-  }
-
-  /* Update the size and count. */
-  const size_t trunc_count = d->count & d->page_mask;
-  d->file_offset += trunc_count;
-  d->count -= trunc_count;
-  d->size = (d->count + increase_size + ~d->page_mask) & d->page_mask;
-
-  /* Re-allocate the file size. */
-  if (posix_fallocate(d->fd, d->file_offset, d->size) != 0) {
-    error("Failed to pre-allocate the dump file.");
-  }
-
-  /* Re-map starting at the end of the file. */
-  if ((d->data = mmap(NULL, d->size, PROT_WRITE, MAP_SHARED, d->fd,
-                      d->file_offset)) == MAP_FAILED) {
-    error("Failed to allocate map of size %zi bytes (%s).", d->size,
-          strerror(errno));
-  }
-}
-
-/**
- * @brief Flush the #dump to disk.
- */
-void dump_sync(struct dump *d) {
-  if (msync(d->data, d->count, MS_SYNC) != 0)
-    error("Failed to sync memory-mapped data.");
-}
-
-/**
- * @brief Finalize the #dump.
- */
-void dump_close(struct dump *d) {
-  /* Unmap the data in memory. */
-  if (munmap(d->data, d->count) != 0) {
-    error("Failed to unmap dump data (%s).", strerror(errno));
-  }
-
-  /* Truncate the file to the correct length. */
-  if (ftruncate(d->fd, d->file_offset + d->count) != 0) {
-    error("Failed to truncate dump file (%s).", strerror(errno));
-  }
-
-  /* Close the memory-mapped file. */
-  if (close(d->fd) != 0) error("Failed to close memory-mapped file.");
-}
-
-/**
- * @brief Initialize a file dump.
- *
- * @param d The #dump to initialize.
- * @param filename The fully qualified name of the file in which to dump,
- *                 note that it will be overwritten.
- * @param size The initial buffer size for this #dump.
- */
-void dump_init(struct dump *d, const char *filename, size_t size) {
-
-  /* Create the output file.
-     The option O_RDWR seems to be required by mmap.
-  */
-  if ((d->fd = open(filename, O_CREAT | O_RDWR, 0660)) == -1) {
-    error("Failed to create dump file '%s' (%s).", filename, strerror(errno));
-  }
-
-  /* Adjust the size to be at least the page size. */
-  const size_t page_mask = ~(sysconf(_SC_PAGE_SIZE) - 1);
-  size = (size + ~page_mask) & page_mask;
-
-  /* Pre-allocate the file size. */
-  if (posix_fallocate(d->fd, 0, size) != 0) {
-    error("Failed to pre-allocate the dump file.");
-  }
-
-  /* Map memory to the created file. */
-  if ((d->data = mmap(NULL, size, PROT_WRITE, MAP_SHARED, d->fd, 0)) ==
-      MAP_FAILED) {
-    error("Failed to allocate map of size %zi bytes (%s).", size,
-          strerror(errno));
-  }
-
-  /* Init some counters. */
-  d->size = size;
-  d->count = 0;
-  d->file_offset = 0;
-  d->page_mask = page_mask;
-}
-
-/**
- * @brief Restart a file dump.
- *
- * @param d The #dump to restart.
- * @param filename The fully qualified name of the file in which to dump,
- *                 note that it will be overwritten.
- */
-void dump_restart(struct dump *d, const char *filename) {
-  /* Create the output file.
-     The option O_RDWR seems to be required by mmap.
-  */
-  if ((d->fd = open(filename, O_RDWR, 0660)) == -1) {
-    error("Failed to open dump file '%s' (%s).", filename, strerror(errno));
-  }
-
-  /* Adjust the size to be at least the page size. */
-  const size_t page_mask = ~(sysconf(_SC_PAGE_SIZE) - 1);
-  size_t size = (d->size + ~page_mask) & page_mask;
-
-  /* Pre-allocate the file size. */
-  if (posix_fallocate(d->fd, 0, size) != 0) {
-    error("Failed to pre-allocate the dump file.");
-  }
-
-  /* Map memory to the created file. */
-  if ((d->data = mmap(NULL, size, PROT_WRITE, MAP_SHARED, d->fd,
-                      d->file_offset)) == MAP_FAILED) {
-    error("Failed to allocate map of size %zi bytes (%s).", d->size,
-          strerror(errno));
-  }
-}
-
-#endif
diff --git a/src/dump.h b/src/dump.h
deleted file mode 100644
index e92684c6f7c60e414365b06278c9afedc8e74c50..0000000000000000000000000000000000000000
--- a/src/dump.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
- * This file is part of SWIFT.
- * Copyright (c) 2016 Pedro Gonnet (pedro.gonnet@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_DUMP_H
-#define SWIFT_DUMP_H
-
-/* Config parameters. */
-#include "../config.h"
-
-#ifdef HAVE_POSIX_FALLOCATE /* Are we on a sensible platform? */
-
-/* Standard headers */
-#include <stdlib.h>
-
-/** The dump struct. */
-struct dump {
-
-  /* The memory-mapped data of this dump. */
-  void *data;
-
-  /* The size of the memory-mapped data, in bytes. */
-  size_t size;
-
-  /* The number of bytes that have been dumped. */
-  size_t count;
-
-  /* The offset of the data within the current file. */
-  size_t file_offset;
-
-  /* The file with which this memory is associated. */
-  int fd;
-
-  /* Mask containing the significant bits for page addresses. */
-  size_t page_mask;
-};
-
-/* Function prototypes. */
-void dump_init(struct dump *d, const char *filename, size_t size);
-void dump_restart(struct dump *d, const char *filename);
-void dump_ensure(struct dump *d, size_t required_size, size_t increase_size);
-void dump_sync(struct dump *d);
-void dump_close(struct dump *d);
-void *dump_get(struct dump *d, size_t count, size_t *offset);
-
-#endif /* HAVE_POSIX_FALLOCATE */
-
-#endif /* SWIFT_DUMP_H */
diff --git a/src/engine.h b/src/engine.h
index 1ef13fa954678875f69d4987e41cdd0366caa213..3c7306219257e0c2842378e3227d4c34ab3c7f4f 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -36,7 +36,6 @@
 #include "barrier.h"
 #include "clocks.h"
 #include "collectgroup.h"
-#include "dump.h"
 #include "mesh_gravity.h"
 #include "output_options.h"
 #include "parser.h"
diff --git a/src/engine_collect_end_of_step.c b/src/engine_collect_end_of_step.c
index 4364c328bf2d410468e4a68aa25b149369ef741b..f842f7c6d7eb7a8276ad30b105d6a624c61c8068 100644
--- a/src/engine_collect_end_of_step.c
+++ b/src/engine_collect_end_of_step.c
@@ -501,7 +501,8 @@ void engine_collect_end_of_step(struct engine *e, int apply) {
 #ifdef WITH_CSDS
   /* Get the file size from the CSDS. */
   if (e->policy & engine_policy_csds)
-    data.csds_file_size_gb = csds_get_current_filesize_used_gb(e->csds, e);
+    data.csds_file_size_gb =
+        csds_logfile_writer_get_current_filesize_used_gb(&e->csds->logfile);
 #endif
 
   /* Need to use a consistent check of the hours since we started. */
diff --git a/src/swift.h b/src/swift.h
index 07aabf5d35d38ba0ae62a94b2191ae365381542c..2365cc175dabcd5adbf0b492401975766426919c 100644
--- a/src/swift.h
+++ b/src/swift.h
@@ -39,7 +39,6 @@
 #include "csds_io.h"
 #include "cycle.h"
 #include "debug.h"
-#include "dump.h"
 #include "engine.h"
 #include "entropy_floor.h"
 #include "error.h"
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5049239b05b257c2939a356047acc6f6600bd520..aa6d956b8d12bab3f3117e0eac6bc88e57f48f71 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -19,6 +19,10 @@ AM_CFLAGS = -I$(top_srcdir)/src $(HDF5_CPPFLAGS) $(GSL_INCS) $(FFTW_INCS) $(NUMA
 
 AM_LDFLAGS = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS) $(FFTW_LIBS) $(NUMA_LIBS) $(TCMALLOC_LIBS) $(JEMALLOC_LIBS) $(TBBMALLOC_LIBS) $(GRACKLE_LIBS) $(GSL_LIBS) $(PROFILER_LIBS)
 
+if HAVECSDS
+AM_LDFLAGS += ../csds/src/.libs/libcsds_writer.a
+endif
+
 # List of programs and scripts to run in the test suite
 TESTS = testGreetings testMaths testReading.sh testKernel testKernelLongGrav \
         testActivePair.sh test27cells.sh test27cellsPerturbed.sh testExp \
diff --git a/tests/testCSDS.c b/tests/testCSDS.c
index 317685c36cbbd0b14b7575b04dd3b2b017eb785d..452237ffd3c7d5c23f767688d9e5976571cebc59 100644
--- a/tests/testCSDS.c
+++ b/tests/testCSDS.c
@@ -30,13 +30,18 @@
 #include <unistd.h>
 
 /* Local headers. */
+#include "csds/src/csds_logfile_writer.h"
 #include "swift.h"
 
 void test_log_parts(struct csds_writer *log) {
-  struct dump *d = &log->dump;
+  struct csds_logfile_writer *d = &log->logfile;
   struct engine e;
+  struct cosmology cosmo;
+  e.cosmology = &cosmo;
+  cosmo.a_factor_hydro_accel = 1;
+  cosmo.a_factor_grav_accel = 1;
 
-  /* Write several copies of a part to the dump. */
+  /* Write several copies of a part to the logfile. */
   struct part p;
   struct xpart xp;
   bzero(&p, sizeof(struct part));
@@ -64,7 +69,7 @@ void test_log_parts(struct csds_writer *log) {
                 /* flag_data */ 0);
   printf("Wrote part at offset %#016zx.\n", xp.csds_data.last_offset);
 
-  /* Recover the last part from the dump. */
+  /* Recover the last part from the logfile. */
   bzero(&p, sizeof(struct part));
   size_t offset = xp.csds_data.last_offset;
   size_t offset_old = offset;
@@ -78,7 +83,7 @@ void test_log_parts(struct csds_writer *log) {
     abort();
   }
 
-  /* Recover the second part from the dump (only position). */
+  /* Recover the second part from the logfile (only position). */
   bzero(&p, sizeof(struct part));
   offset_old = offset;
   mask = csds_read_part(log, &p, &offset, (const char *)d->data);
@@ -91,7 +96,7 @@ void test_log_parts(struct csds_writer *log) {
     abort();
   }
 
-  /* Recover the first part from the dump. */
+  /* Recover the first part from the logfile. */
   bzero(&p, sizeof(struct part));
   offset_old = offset;
   mask = csds_read_part(log, &p, &offset, (const char *)d->data);
@@ -106,10 +111,10 @@ void test_log_parts(struct csds_writer *log) {
 }
 
 void test_log_gparts(struct csds_writer *log) {
-  struct dump *d = &log->dump;
+  struct csds_logfile_writer *d = &log->logfile;
   struct engine e;
 
-  /* Write several copies of a part to the dump. */
+  /* Write several copies of a part to the logfile. */
   struct gpart p;
   bzero(&p, sizeof(struct gpart));
   p.x[0] = 1.0;
@@ -136,7 +141,7 @@ void test_log_gparts(struct csds_writer *log) {
                  /* flag_data */ 0);
   printf("Wrote gpart at offset %#016zx.\n", p.csds_data.last_offset);
 
-  /* Recover the last part from the dump. */
+  /* Recover the last part from the logfile. */
   size_t offset = p.csds_data.last_offset;
   bzero(&p, sizeof(struct gpart));
   size_t offset_old = offset;
@@ -150,7 +155,7 @@ void test_log_gparts(struct csds_writer *log) {
     abort();
   }
 
-  /* Recover the second part from the dump. */
+  /* Recover the second part from the logfile. */
   bzero(&p, sizeof(struct gpart));
   offset_old = offset;
   mask = csds_read_gpart(log, &p, &offset, (const char *)d->data);
@@ -163,7 +168,7 @@ void test_log_gparts(struct csds_writer *log) {
     abort();
   }
 
-  /* Recover the first part from the dump. */
+  /* Recover the first part from the logfile. */
   bzero(&p, sizeof(struct gpart));
   offset_old = offset;
   mask = csds_read_gpart(log, &p, &offset, (const char *)d->data);
@@ -178,13 +183,13 @@ void test_log_gparts(struct csds_writer *log) {
 }
 
 void test_log_timestamps(struct csds_writer *log) {
-  struct dump *d = &log->dump;
+  struct csds_logfile_writer *d = &log->logfile;
 
   /* The timestamp to log. */
   integertime_t t = 10;
   double time = 0.1;
 
-  /* Start with an offset at the end of the dump. */
+  /* Start with an offset at the end of the logfile. */
   size_t offset = d->count;
 
   /* Log three consecutive timestamps. */
diff --git a/tests/testDump.c b/tests/testDump.c
index 878daae9cc0deddd6f9fb02857041f705110743c..92cd4882715f2211702871f30c50e3d95216e247 100644
--- a/tests/testDump.c
+++ b/tests/testDump.c
@@ -35,10 +35,10 @@
 /* Local headers. */
 #include "swift.h"
 
-void dump_mapper(void *map_data, int num_elements, void *extra_data) {
-  struct dump *d = (struct dump *)extra_data;
+void logfile_mapper(void *map_data, int num_elements, void *extra_data) {
+  struct csds_logfile_writer *d = (struct csds_logfile_writer *)extra_data;
   size_t offset;
-  char *out_string = (char *)dump_get(d, 7, &offset);
+  char *out_string = (char *)csds_logfile_writer_get(d, 7, &offset);
   char out_buff[8];
   /* modulo due to bug in gcc, should be removed */
   snprintf(out_buff, 8, "%06zi\n", (offset / 7) % 1000000);
@@ -62,8 +62,8 @@ int main(int argc, char *argv[]) {
   threadpool_init(&t, num_threads);
 
   /* Prepare a dump. */
-  struct dump d;
-  dump_init(&d, filename, 1024);
+  struct csds_logfile_writer d;
+  csds_logfile_writer_init(&d, filename, 1024);
 
   /* Print the page size for reference. */
   printf("Will dump %i bytes, page size is %zi bytes.\n",
@@ -73,19 +73,19 @@ int main(int argc, char *argv[]) {
   for (int run = 0; run < num_runs; run++) {
 
     /* Ensure capacity. */
-    dump_ensure(&d, 7 * chunk_size, 7 * chunk_size);
+    csds_logfile_writer_ensure(&d, 7 * chunk_size, 7 * chunk_size);
 
     /* Dump a few numbers. */
     printf("dumping %i chunks...\n", chunk_size);
     fflush(stdout);
-    threadpool_map(&t, dump_mapper, NULL, chunk_size, 0, 1, &d);
+    threadpool_map(&t, logfile_mapper, NULL, chunk_size, 0, 1, &d);
   }
 
   /* Sync the file, not necessary before dump_close, but just to test this. */
-  dump_sync(&d);
+  csds_logfile_writer_sync(&d);
 
   /* Finalize the dump. */
-  dump_close(&d);
+  csds_logfile_writer_close(&d);
 
   /* Clean the threads */
   threadpool_clean(&t);