diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 3b902153e..bdcc2fe16 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -70,6 +70,7 @@ MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef):
 		m_parent(parent),
 		m_pos(pos),
 		m_pos_relative(pos * MAP_BLOCKSIZE),
+		data(new MapNode[nodecount]),
 		m_gamedef(gamedef)
 {
 	reallocate();
@@ -83,6 +84,8 @@ MapBlock::~MapBlock()
 		mesh = nullptr;
 	}
 #endif
+
+	delete[] data;
 }
 
 bool MapBlock::onObjectsActivation()
diff --git a/src/mapblock.h b/src/mapblock.h
index f0491e25c..0c6fec7a0 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -502,6 +502,13 @@ private:
 	*/
 	v3s16 m_pos_relative;
 
+	/*
+	 * Note that this is not an inline array because that has implications on
+	 * heap fragmentation (the array is exactly 16K), CPU caches and/or
+	 * optimizability of algorithms working on this array.
+	 */
+	MapNode *const data; // of `nodecount` elements
+
 	IGameDef *m_gamedef;
 
 	/*
@@ -558,7 +565,6 @@ private:
 	*/
 	int m_refcount = 0;
 
-	MapNode data[nodecount];
 	NodeTimerList m_node_timers;
 };