--- a/net/minecraft/world/level/chunk/storage/EntityStorage.java
+++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java
@@ -70,12 +70,12 @@
         }
     }
 
-    private static ChunkPos readChunkPos(CompoundTag chunkNbt) {
+    public static ChunkPos readChunkPos(CompoundTag chunkNbt) { // Paper - public
         int[] is = chunkNbt.getIntArray("Position");
         return new ChunkPos(is[0], is[1]);
     }
 
-    private static void writeChunkPos(CompoundTag chunkNbt, ChunkPos pos) {
+    public static void writeChunkPos(CompoundTag chunkNbt, ChunkPos pos) { // Paper - public
         chunkNbt.put("Position", new IntArrayTag(new int[]{pos.x, pos.z}));
     }
 
@@ -92,7 +92,18 @@
             }
         } else {
             ListTag listTag = new ListTag();
+            final java.util.Map<net.minecraft.world.entity.EntityType<?>, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk
             dataList.getEntities().forEach(entity -> {
+                // Paper start - Entity load/save limit per chunk
+                final EntityType<?> entityType = entity.getType();
+                final int saveLimit = this.level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1);
+                if (saveLimit > -1) {
+                    if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) {
+                        return;
+                    }
+                    savedEntityCounts.merge(entityType, 1, Integer::sum);
+                }
+                // Paper end - Entity load/save limit per chunk
                 CompoundTag compoundTagx = new CompoundTag();
                 if (entity.save(compoundTagx)) {
                     listTag.add(compoundTagx);
