diff --git a/src/communication/export_manager.hpp b/src/communication/export_manager.hpp
index d3628a847abcdaedb93b92b99ffb5e61f0d8d320..4211b747f41308faaf07be2489d232c0305139da 100644
--- a/src/communication/export_manager.hpp
+++ b/src/communication/export_manager.hpp
@@ -23,21 +23,19 @@ class export_manager {
 public:
     using time_type = Time;
     using spike_type = spike<cell_member_type, time_type>;
-    export_manager() 
+    export_manager(bool file_per_rank) 
     {
 
-        if (true) { // single file per rank
+        if (file_per_rank) { // single file per rank
 
             rank_exporters_.push_back(
                 nest::mc::util::make_unique<
                     nest::mc::communication::exporter_spike_file<Time, CommunicationPolicy> >(
                         "rank", "./", "gdf"));
-
-
         }
 
 
-        if (true) { // single file per simulation
+        if (!file_per_rank) { // single file per simulation
             single_exporters_.push_back(
                 nest::mc::util::make_unique<
                     nest::mc::communication::exporter_spike_single_file<Time, CommunicationPolicy> >(
diff --git a/src/model.hpp b/src/model.hpp
index 19e75a132b3cc523bf8f50ebe13f52e1b1696a9f..f7516c5ccb51bcc66123dfdbb07c71e9dfd986d5 100644
--- a/src/model.hpp
+++ b/src/model.hpp
@@ -72,7 +72,7 @@ public:
 
         bool single_file = true;
         if (single_file == true) {
-            exporter_ = nest::mc::util::make_unique<exporter_manager_type>();
+            exporter_ = nest::mc::util::make_unique<exporter_manager_type>(false);
         }
 
         // Allocate an empty queue buffer for each cell group
diff --git a/tests/performance/CMakeLists.txt b/tests/performance/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..351be926371b61bcf130d43efc42e5fb0ff53eee
--- /dev/null
+++ b/tests/performance/CMakeLists.txt
@@ -0,0 +1,2 @@
+# Unit tests
+add_subdirectory(io)
diff --git a/tests/performance/io/CMakeLists.txt b/tests/performance/io/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..861b4e411bb5425f483444ae1d1c1ec906612770
--- /dev/null
+++ b/tests/performance/io/CMakeLists.txt
@@ -0,0 +1,18 @@
+set(HEADERS
+)
+
+set(DISK_IO_SOURCES
+    disk_io.cpp
+)
+
+add_executable(disk_io.exe ${DISK_IO_SOURCES} ${HEADERS})
+
+target_link_libraries(disk_io.exe LINK_PUBLIC cellalgo)
+
+if(WITH_MPI)
+    target_link_libraries(disk_io.exe LINK_PUBLIC ${MPI_C_LIBRARIES})
+    set_property(TARGET disk_io.exe APPEND_STRING PROPERTY LINK_FLAGS "${MPI_C_LINK_FLAGS}")
+endif()
+
+# Copy the python file that drives the performance tests and produces the output
+file(COPY disk_io.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
\ No newline at end of file
diff --git a/tests/performance/io/disk_io.cpp b/tests/performance/io/disk_io.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f9353c2053961d02ba7115c9d21f39a60e18fcbe
--- /dev/null
+++ b/tests/performance/io/disk_io.cpp
@@ -0,0 +1,155 @@
+#include <iostream>
+#include <cstdlib>
+#include <ctime>
+#include <fstream>
+#include <numeric>
+
+
+#include <common_types.hpp>
+#include <fvm_cell.hpp>
+#include <cell.hpp>
+#include <cell_group.hpp>
+
+#include <communication/communicator.hpp>
+#include <communication/global_policy.hpp>
+#include <communication/export_manager.hpp>
+
+
+
+using namespace nest::mc;
+
+using global_policy = communication::global_policy;
+using lowered_cell = nest::mc::fvm::fvm_cell<double, cell_local_size_type>;
+using cell_group_type = cell_group<lowered_cell>;
+using time_type = typename cell_group_type::time_type;
+using spike_type = communication::exporter_spike_file<time_type,
+    global_policy>::spike_type;
+
+int main(int argc, char** argv) {
+    // Setup the possible mpi environment
+    nest::mc::communication::global_policy_guard global_guard(argc, argv);
+
+    // very simple command line parsing
+    if (argc < 3)
+    {
+        std::cout << "disk_io <int nrspikes> <int nr_repeats> <file_per_rank (true|false)> [simple_output (false|true)]" << std::endl;
+        << "   Simple performance test runner for the exporter manager"
+            << "   It exports nrspikes nr_repeats using the export_manager and will produce"
+            << "   the total, mean and std of the time needed to perform the output to disk"
+            << "   <file_per_rank> true will produce a single file per mpi rank"
+            << "   <simple_output> true will produce a simplyfied comma seperated output for automatic parsing"
+            << "    The application can be started with mpi support and will produce output on a single rank";
+
+        std::cout << "    if nrspikes is not a multiple of the nr of mpi rank, floor is take" << std::endl;
+        exit(1);
+    }
+    int nr_spikes = atoi(argv[1]);
+
+    if (nr_spikes == 0)
+    {
+        std::cout << "disk_io <nrspikes>" << std::endl;
+        std::cout << "  nrspikes should be a valid integer higher then zero" << std::endl;
+        exit(1);
+    }
+    int nr_repeats = atoi(argv[2]);
+
+    if (nr_repeats == 0)
+    {
+        std::cout << "disk_io <nrspikes>" << std::endl;
+        std::cout << "  nr_repeats should be a valid integer higher then zero" << std::endl;
+        exit(1);
+    }
+    
+    bool file_per_rank = false;
+    std::string single(argv[3]);
+    if (single == std::string("true"))
+    {
+        file_per_rank = true;
+    }
+
+    bool simple_stats = false;
+    if (argc == 5)
+    {
+        std::string simple(argv[4]);
+        if (simple == std::string("true")) 
+        {
+            simple_stats = true;
+        }
+    }
+
+    // Create the sut  
+    nest::mc::communication::export_manager<time_type, global_policy> manager(file_per_rank);
+
+    // We need the nr of ranks to calculate the nr of spikes to produce per
+    // rank
+    global_policy communication_policy;
+    unsigned nr_ranks = communication_policy.size();
+    unsigned spikes_per_rank = nr_spikes / nr_ranks;   
+
+    // Create a set of spikes
+    std::vector<spike_type> spikes;
+    for (unsigned idx = 0; idx < spikes_per_rank; ++idx) 
+    {
+        spikes.push_back({ { idx, 0 }, 0.0f + idx });
+    }
+
+    std::vector<int> timings;
+
+    int time_total = 0;
+
+    // now output to disk nr_repeats times, while keeping track of the times
+    for (int idx = 0; idx < nr_repeats; ++idx) 
+    {
+        int time_start = clock();
+
+        manager.do_export_rank(spikes);
+
+
+        int time_stop = clock();
+        int run_time = (time_stop - time_start);
+        time_total += run_time;
+        timings.push_back(run_time);
+    }
+    
+
+    // Autoput the individual timings to a comma seperated file
+    std::ofstream file("file_io_results.csv");
+    file << *timings.begin() / double(CLOCKS_PER_SEC) * 1000;
+    for (auto time_entry = timings.begin()++; time_entry < timings.end(); ++time_entry) 
+    {
+
+        file << "," << *time_entry / double(CLOCKS_PER_SEC) * 1000 ;
+    }
+    file << std::endl;
+
+    // Calculate some statistics
+    double sum = std::accumulate(timings.begin(), timings.end(), 0.0);
+    double mean = sum / timings.size();
+
+    std::vector<double> diff(timings.size());
+    std::transform(timings.begin(), timings.end(), diff.begin(),
+        std::bind2nd(std::minus<double>(), mean));
+    double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
+    double stdev = std::sqrt(sq_sum / timings.size());
+
+    if (communication_policy.id() != 0)
+    {
+        return 0;
+    }
+
+    // and output
+    if (simple_stats)
+    {
+        std::cout << time_total / double(CLOCKS_PER_SEC) * 1000 << "," << 
+                     mean / double(CLOCKS_PER_SEC) * 1000 << "," << 
+                     stdev / double(CLOCKS_PER_SEC) * 1000;
+    }
+    else
+    {
+        std::cout << "total time (ms): " << time_total / double(CLOCKS_PER_SEC) * 1000 << std::endl;
+        std::cout << "mean  time (ms): " << mean / double(CLOCKS_PER_SEC) * 1000 << std::endl;
+        std::cout << "stdev  time (ms): " << stdev / double(CLOCKS_PER_SEC) * 1000 << std::endl;
+    }
+
+    return 0;
+}
diff --git a/tests/performance/io/disk_io.py b/tests/performance/io/disk_io.py
new file mode 100644
index 0000000000000000000000000000000000000000..e8b40b7b8052d10cc5d4a0ab950359ffd4cc84bc
--- /dev/null
+++ b/tests/performance/io/disk_io.py
@@ -0,0 +1,42 @@
+import subprocess
+import os
+
+import matplotlib.pyplot as plt
+
+
+current_script_dir = os.path.dirname(os.path.abspath(__file__))
+
+spikes_to_save = 100000
+
+range_nr_rank = [1, 2, 4, 8, 16, 24, 32, 48, 64]
+mean = []
+std = []
+for n_rank in range_nr_rank:
+    # open the disk_io executable 
+    p1 = subprocess.Popen(["mpirun", "-n",str(n_rank), 
+                           os.path.join(current_script_dir, "disk_io.exe"),
+                           str(spikes_to_save), str(10), "true" ,"true"],                         
+                          
+                          stdout=subprocess.PIPE)
+    
+    #and grab the raw stats
+    stats =  p1.communicate()[0]
+
+    # convert into list
+    stats = stats.split(",")
+
+    mean.append(float(stats[1]))
+    std.append(float(stats[2]))
+
+    print ( "performed test for n_rank= " + str(n_rank))
+
+
+
+print ( range_nr_rank )
+print ( mean )
+print ( std )
+
+plt.errorbar(range_nr_rank, mean, yerr=std, fmt='-o')
+plt.xscale('log')
+plt.yscale('log')
+plt.show()
\ No newline at end of file