diff --git a/src/cats/configuration/configuration.c b/src/cats/configuration/configuration.c
index 00b2e74cdf9cd6b010c1cbba272639006d68560e..361d694d61bfab701de03cfa032302f2df07c8c7 100644
--- a/src/cats/configuration/configuration.c
+++ b/src/cats/configuration/configuration.c
@@ -60,7 +60,7 @@ void init_cats_configuration(struct cats_configuration *conf)
                 log_message(LOG_ERROR, "conf is NULL in %s", __func__);
                 exit(EXIT_FAILURE);
         }
-
+        init_stats_registry(&conf->stats_registry);
         init_module_registry(&conf->modules);
         reset_overlay(&conf->overlays);
         zero_statistics_stats(&conf->global_stats);
diff --git a/src/cats/configuration/configuration.h b/src/cats/configuration/configuration.h
index 15542b32603c58d418b5d51d210939d9ec800738..1613e915be901baa179a281c2c8c9105a6dbcf7e 100644
--- a/src/cats/configuration/configuration.h
+++ b/src/cats/configuration/configuration.h
@@ -135,6 +135,8 @@ struct cats_configuration {
         bool debug_enabled;
         struct cats_ini *ini;
 
+        struct cats_stats_registry stats_registry;
+
         // cats_stats
         cats_dt_population stats_populated_threshold;
 
diff --git a/src/cats/grids/cats_grid.c b/src/cats/grids/cats_grid.c
index e55be91ca49b16cd508e8835804d0ad288d5bfa5..912b4cf9bf19edae2bface737dde4c1c269fe2d7 100644
--- a/src/cats/grids/cats_grid.c
+++ b/src/cats/grids/cats_grid.c
@@ -187,7 +187,7 @@ void initialize_grid(struct cats_grid *grid, struct cats_configuration *conf, st
         // FIXME: SCALE FACTOR make this unnecessary and decouple scale factor calculations from **grids
 
         // Attention: we need to call finalize_grid() later if only partially initialised
-        init_statistics(&grid->stats);
+        init_statistics(&grid->stats, &conf->stats_registry);
 
 
         setup_grid_population_structures(grid);
@@ -344,7 +344,7 @@ void do_all_grids(struct cats_grid **grids, struct cats_configuration *conf, gri
 void initialize_grid_stats(struct cats_grid *grid, struct cats_configuration *conf)
 {
         assert(grid != NULL);
-        init_statistics(&grid->stats);
+        init_statistics(&grid->stats, &conf->stats_registry);
         grid->stats.has_been_populated = (char **) new_raw_2d_array_from_dimension(grid->dimension, sizeof(char));
 
         char *filename = get_grid_stat_filename(grid, conf);
diff --git a/src/cats/stats/statistics.c b/src/cats/stats/statistics.c
index e0c63deafe896b2fd7a5af4446a7629654b2e2dd..73e4c208f9c714d3a74a8c1c19b22a41849012b1 100644
--- a/src/cats/stats/statistics.c
+++ b/src/cats/stats/statistics.c
@@ -23,8 +23,11 @@
 
 
 #include <assert.h>
+#include <stdlib.h>
 #include "statistics.h"
 #include "cats_strings/cats_strings.h"
+#include "memory/cats_memory.h"
+#include "configuration/configuration.h"
 
 
 void zero_statistics_stats(struct statistics *stats)
@@ -36,28 +39,71 @@ void zero_statistics_stats(struct statistics *stats)
         char **has_been_populated_ts = stats->has_been_populated_ts;
         int32_t *N = stats->populated_by_classes;
         struct string_array *header = stats->stats_header;
-
+        int64_t *custom_stats = stats->custom_stats;
+        int64_t custom_stat_count = stats->custom_stat_count;
         // reset everything
         struct statistics empty = {0};
         *stats = empty;
 
+
         // restore some values
         stats->file = file;
         stats->has_been_populated = has_been_populated;
         stats->has_been_populated_ts = has_been_populated_ts;
         stats->populated_by_classes = N;
         stats->stats_header = header;
+        stats->custom_stats = custom_stats;
+        stats->custom_stat_count = custom_stat_count;
+
+        for (int32_t i = 0; i < STAT_MAX; i++) {
+                stats->stats[i] = 0;
+        }
+
+        for (int64_t i = 0; i < stats->custom_stat_count; i++) {
+                stats->custom_stats[i] = 0;
+        }
+
 }
 
 
-void init_statistics(struct statistics *stats)
+void init_statistics(struct statistics *stats, struct cats_stats_registry *registry)
 {
+        if (stats->initialized) {
+                log_message(LOG_WARNING, "statistics are already initialised");
+        }
         struct statistics empty = {0};
         *stats = empty;
+        stats->custom_stat_count = registry->count;
+        stats->custom_stats = calloc_or_die(stats->custom_stat_count, sizeof(int64_t));
+        stats->initialized = true;
 }
 
 
 void cleanup_statistics(struct statistics *stats)
 {
         if (stats->stats_header) free_string_array(&stats->stats_header);
-}
\ No newline at end of file
+        free(stats->custom_stats);
+}
+
+
+int64_t add_custom_stat(struct cats_stats_registry *registry, const char *name)
+{
+        int64_t count = registry->count;
+        string_array_add(registry->names, name);
+        registry->count += 1;
+        return count;
+}
+
+
+void init_stats_registry(struct cats_stats_registry *registry)
+{
+        registry->count = 0;
+        registry->names = new_string_array();
+}
+
+void cleanup_stats_registry(struct cats_stats_registry *registry)
+{
+        registry->count = 0;
+        free_string_array(&registry->names);
+        registry->names = NULL;
+}
diff --git a/src/cats/stats/statistics.h b/src/cats/stats/statistics.h
index df0208d8300382553d6de9d67a803014e917963c..f5f9f5b3b08f6078ff1830487c01ad45e20021f9 100644
--- a/src/cats/stats/statistics.h
+++ b/src/cats/stats/statistics.h
@@ -23,10 +23,16 @@
 
 #ifndef CATS_STATISTICS_H
 #define CATS_STATISTICS_H
-
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdint.h>
 
+struct cats_stats_registry {
+    int64_t count;
+    struct string_array *names;
+};
+
+
 // STAT_MIN and STAT_MAX are used for enumeration purposes
 // CS (CELL STATS) count the number of cells where the value of the specified stat is larger than zero
 // GS (GRID SUM) is the sum of the specified stat over the whole simulation area
@@ -69,8 +75,10 @@ enum cats_stats {
 
 /// @brief data structure for collected statistics, both on a per-grid and global basis
 struct statistics {
-
+        bool initialized;
         int64_t stats[STAT_MAX];       ///< individual cell stats, on for each \sa enum cats_stats
+        int64_t *custom_stats;
+        int64_t custom_stat_count;
         FILE *file;                    ///< file handle for output file
         int32_t *populated_by_classes; ///< only used for global stats: how many cells are populated by 1, 2, 3, ... N classes
         char **has_been_populated;     ///< which cells have already been populated at least once?
@@ -80,8 +88,9 @@ struct statistics {
 
 void zero_statistics_stats(struct statistics *stats);
 
-void init_statistics(struct statistics *stats);
+void init_statistics(struct statistics *stats, struct cats_stats_registry *registry);
 
 void cleanup_statistics(struct statistics *stats);
-
+void init_stats_registry(struct cats_stats_registry *registry);
+int64_t add_custom_stat(struct cats_stats_registry *registry, const char *name);
 #endif //CATS_STATISTICS_H
diff --git a/src/cats/stats/write_stats.c b/src/cats/stats/write_stats.c
index b4e440dad9041af9531419b56420ff0d82a75fd9..b567bec652a7b6b3c399f26f1bffc026e11f7fa3 100644
--- a/src/cats/stats/write_stats.c
+++ b/src/cats/stats/write_stats.c
@@ -35,6 +35,8 @@
 
 const char *get_stat_name(enum cats_stats which)
 {
+
+
         switch (which) {
                 case CS_POPULATED:
                         return "populated";
diff --git a/src/cats/threading/threading-helpers.c b/src/cats/threading/threading-helpers.c
index 653006e2696072790bbde6ff99c920023d8ca0ae..1a8ff5d82ed210f7203b70324d1d29cca067b946 100644
--- a/src/cats/threading/threading-helpers.c
+++ b/src/cats/threading/threading-helpers.c
@@ -30,6 +30,13 @@
 #include "misc/cats_random.h"
 #include "stats/grid_stats.h"
 #include "data/error.h"
+#include "memory/cats_memory.h"
+
+void create_custom_stats_for_thread(struct statistics *thread_stats, struct statistics *grid_stats)
+{
+        thread_stats->custom_stat_count = grid_stats->custom_stat_count;
+        thread_stats->custom_stats = calloc_or_die(grid_stats->custom_stat_count, sizeof(int64_t));
+}
 
 void
 initialize_thread(struct cats_thread_info *thread, struct cats_grid *grid, struct cats_configuration *conf, int32_t id)
@@ -37,7 +44,9 @@ initialize_thread(struct cats_thread_info *thread, struct cats_grid *grid, struc
         thread->rng = allocate_rng();
         thread->rng_seed = conf->rng_seed;
 
-        for (int32_t i = 0; i < MAX_CLASSES; i++) {
+        for (int32_t i = 0; i < conf->grid_count; i++) {
+
+                create_custom_stats_for_thread(&thread->stats[i], &grid->stats);
                 zero_statistics_stats(&thread->stats[i]);
         }
 
@@ -60,7 +69,11 @@ void cleanup_threads(struct cats_thread_info *threads, int32_t num_threads)
                 gsl_rng_free(threads[i].rng);
         }
 
-
+        for (int32_t i = 0; i < num_threads; i++) {
+                for (int32_t j = 0; j < threads[i].conf->grid_count; j++) {
+                        free(threads[i].stats->custom_stats);
+                }
+        }
         free(threads);
 }