diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerBlockEntityEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerBlockEntityEvents.java
index 1e3e1a2520..37bcf4c241 100644
--- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerBlockEntityEvents.java
+++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerBlockEntityEvents.java
@@ -49,6 +49,15 @@ private ServerBlockEntityEvents() {
 		}
 	});
 
+	/**
+	 * Called when a BlockEntity is ticked by a ServerWorld.
+	 */
+	public static final Event<Tick> BLOCK_ENTITY_TICK = EventFactory.createArrayBacked(ServerBlockEntityEvents.Tick.class, callbacks -> (blockEntity, world) -> {
+		for (Tick callback : callbacks) {
+			callback.onTick(blockEntity, world);
+		}
+	});
+
 	@FunctionalInterface
 	public interface Load {
 		void onLoad(BlockEntity blockEntity, ServerWorld world);
@@ -58,4 +67,9 @@ public interface Load {
 	public interface Unload {
 		void onUnload(BlockEntity blockEntity, ServerWorld world);
 	}
+
+	@FunctionalInterface
+	public interface Tick {
+		void onTick(BlockEntity blockEntity, ServerWorld world);
+	}
 }
diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerChunkEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerChunkEvents.java
index f986b7be92..4d05e2566d 100644
--- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerChunkEvents.java
+++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerChunkEvents.java
@@ -48,6 +48,15 @@ private ServerChunkEvents() {
 		}
 	});
 
+	/**
+	 * Called when a chunk is ticked by a ServerWorld.
+	 */
+	public static final Event<ServerChunkEvents.Tick> CHUNK_TICK = EventFactory.createArrayBacked(ServerChunkEvents.Tick.class, callbacks -> (serverWorld, chunk) -> {
+		for (Tick callback : callbacks) {
+			callback.onChunkTick(serverWorld, chunk);
+		}
+	});
+
 	@FunctionalInterface
 	public interface Load {
 		void onChunkLoad(ServerWorld world, WorldChunk chunk);
@@ -57,4 +66,9 @@ public interface Load {
 	public interface Unload {
 		void onChunkUnload(ServerWorld world, WorldChunk chunk);
 	}
+
+	@FunctionalInterface
+	public interface Tick {
+		void onChunkTick(ServerWorld world, WorldChunk chunk);
+	}
 }
diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java
index dfc1cd7696..5008ee9047 100644
--- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java
+++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java
@@ -63,6 +63,15 @@ private ServerEntityEvents() {
 		}
 	});
 
+	/**
+	 * Called when an entity is ticked by a ServerWorld.
+	 */
+	public static final Event<ServerEntityEvents.Tick> ENTITY_TICK = EventFactory.createArrayBacked(ServerEntityEvents.Tick.class, callbacks -> (serverWorld, entity) -> {
+		for (ServerEntityEvents.Tick callback : callbacks) {
+			callback.onTick(serverWorld, entity);
+		}
+	});
+
 	@FunctionalInterface
 	public interface Load {
 		void onLoad(Entity entity, ServerWorld world);
@@ -77,4 +86,9 @@ public interface Unload {
 	public interface EquipmentChange {
 		void onChange(LivingEntity livingEntity, EquipmentSlot equipmentSlot, ItemStack previousStack, ItemStack currentStack);
 	}
+
+	@FunctionalInterface
+	public interface Tick {
+		void onTick(Entity entity, ServerWorld world);
+	}
 }
diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/ServerWorldMixin.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/ServerWorldMixin.java
index 454abf4bca..0ec88e43cb 100644
--- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/ServerWorldMixin.java
+++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/ServerWorldMixin.java
@@ -19,17 +19,28 @@
 import java.util.function.BooleanSupplier;
 
 import org.objectweb.asm.Opcodes;
+import org.spongepowered.asm.mixin.Final;
 import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
 import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.Inject;
 import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 
+import net.minecraft.entity.Entity;
+import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.world.ServerWorld;
+import net.minecraft.world.chunk.WorldChunk;
 
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
 import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
 
 @Mixin(ServerWorld.class)
 public abstract class ServerWorldMixin {
+	@Shadow
+	@Final
+	private MinecraftServer server;
+
 	// Make sure "insideBlockTick" is true before we call the start tick, so inject after it is set
 	@Inject(method = "tick", at = @At(value = "FIELD", target = "Lnet/minecraft/server/world/ServerWorld;inBlockTick:Z", opcode = Opcodes.PUTFIELD, ordinal = 0, shift = At.Shift.AFTER))
 	private void startWorldTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
@@ -40,4 +51,19 @@ private void startWorldTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci)
 	private void endWorldTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
 		ServerTickEvents.END_WORLD_TICK.invoker().onEndTick((ServerWorld) (Object) this);
 	}
+
+	@Inject(method = "tickChunk", at = @At("RETURN"))
+	private void tick(WorldChunk chunk, int randomTickSpeed, CallbackInfo ci) {
+		ServerChunkEvents.CHUNK_TICK.invoker().onChunkTick((ServerWorld) (Object) this, chunk);
+	}
+
+	@Inject(method = "tickEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;tick()V", shift = At.Shift.AFTER))
+	private void tick(Entity entity, CallbackInfo ci) {
+		ServerEntityEvents.ENTITY_TICK.invoker().onTick(entity, (ServerWorld) (Object) this);
+	}
+
+	@Inject(method = "tickPassenger", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;tickRiding()V", shift = At.Shift.AFTER))
+	private void tickRiding(Entity vehicle, Entity passenger, CallbackInfo ci) {
+		ServerEntityEvents.ENTITY_TICK.invoker().onTick(passenger, (ServerWorld) (Object) this);
+	}
 }
diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/WorldChunkMixin.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/WorldChunkMixin.java
new file mode 100644
index 0000000000..8d09cc81ab
--- /dev/null
+++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/WorldChunkMixin.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.mixin.event.lifecycle;
+
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.server.world.ServerWorld;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.WorldChunk;
+
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
+
+@Mixin(WorldChunk.class)
+public abstract class WorldChunkMixin {
+	@Shadow
+	@Final
+	World world;
+
+	@Inject(method = "updateTicker", at = @At("HEAD"))
+	private <T extends BlockEntity> void getBlockEntityTicker(T blockEntity, CallbackInfo ci) {
+		if (this.world instanceof ServerWorld serverWorld) {
+			ServerBlockEntityEvents.BLOCK_ENTITY_TICK.invoker().onTick(blockEntity, serverWorld);
+		}
+	}
+}
diff --git a/fabric-lifecycle-events-v1/src/main/resources/fabric-lifecycle-events-v1.mixins.json b/fabric-lifecycle-events-v1/src/main/resources/fabric-lifecycle-events-v1.mixins.json
index f186b59c2d..89191170fc 100644
--- a/fabric-lifecycle-events-v1/src/main/resources/fabric-lifecycle-events-v1.mixins.json
+++ b/fabric-lifecycle-events-v1/src/main/resources/fabric-lifecycle-events-v1.mixins.json
@@ -8,9 +8,10 @@
     "LivingEntityMixin",
     "MinecraftServerMixin",
     "PlayerManagerMixin",
-    "ServerWorldServerEntityHandlerMixin",
-    "ServerWorldMixin",
     "ServerChunkLoadingManagerMixin",
+    "ServerWorldMixin",
+    "ServerWorldServerEntityHandlerMixin",
+    "WorldChunkMixin",
     "WorldMixin"
   ],
   "server": [
diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerBlockEntityLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerBlockEntityLifecycleTests.java
index 52091d4268..3f7f9cf42d 100644
--- a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerBlockEntityLifecycleTests.java
+++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerBlockEntityLifecycleTests.java
@@ -40,6 +40,12 @@ public final class ServerBlockEntityLifecycleTests implements ModInitializer {
 	public void onInitialize() {
 		final Logger logger = ServerLifecycleTests.LOGGER;
 
+		ServerBlockEntityEvents.BLOCK_ENTITY_TICK.register((blockEntity, world) -> {
+			if (PRINT_SERVER_BLOCKENTITY_MESSAGES) {
+				logger.info("[SERVER] TICKED " + Registries.BLOCK_ENTITY_TYPE.getId(blockEntity.getType()).toString() + " - BlockEntities: " + this.serverBlockEntities.size());
+			}
+		});
+
 		ServerBlockEntityEvents.BLOCK_ENTITY_LOAD.register((blockEntity, world) -> {
 			this.serverBlockEntities.add(blockEntity);
 
diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerChunkLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerChunkLifecycleTests.java
new file mode 100644
index 0000000000..d6050863a1
--- /dev/null
+++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerChunkLifecycleTests.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.test.event.lifecycle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+
+import net.minecraft.world.chunk.WorldChunk;
+
+import net.fabricmc.api.ModInitializer;
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
+
+/**
+ * Tests related to the lifecycle of chunks.
+ */
+public class ServerChunkLifecycleTests implements ModInitializer {
+	private static final boolean PRINT_SERVER_CHUNK_MESSAGES = System.getProperty("fabric-lifecycle-events-testmod.printServerChunkMessages") != null;
+
+	private final List<WorldChunk> chunks = new ArrayList<>();
+
+	@Override
+	public void onInitialize() {
+		final Logger logger = ServerLifecycleTests.LOGGER;
+
+		ServerChunkEvents.CHUNK_TICK.register((world, chunk) -> {
+			if (PRINT_SERVER_CHUNK_MESSAGES) {
+				logger.info("[SERVER] TICKING CHUNK AT x={} z={} - Tracking {} Chunks", chunk.getPos().x, chunk.getPos().z, this.chunks.size());
+			}
+		});
+
+		ServerChunkEvents.CHUNK_LOAD.register((world, chunk) -> {
+			this.chunks.add(chunk);
+
+			if (PRINT_SERVER_CHUNK_MESSAGES) {
+				logger.info("[SERVER] LOADED CHUNK AT x={} z={} - Tracking {} Chunks", chunk.getPos().x, chunk.getPos().z, this.chunks.size());
+			}
+		});
+
+		ServerChunkEvents.CHUNK_UNLOAD.register((world, chunk) -> {
+			this.chunks.remove(chunk);
+
+			if (PRINT_SERVER_CHUNK_MESSAGES) {
+				logger.info("[SERVER] UNLOADED CHUNK AT x={} z={} - Tracking {} Chunks", chunk.getPos().x, chunk.getPos().z, this.chunks.size());
+			}
+		});
+	}
+}
diff --git a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerEntityLifecycleTests.java b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerEntityLifecycleTests.java
index b03dd7fef1..bf4353e361 100644
--- a/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerEntityLifecycleTests.java
+++ b/fabric-lifecycle-events-v1/src/testmod/java/net/fabricmc/fabric/test/event/lifecycle/ServerEntityLifecycleTests.java
@@ -23,6 +23,8 @@
 import org.slf4j.Logger;
 
 import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.Items;
 import net.minecraft.server.world.ServerWorld;
 
 import net.fabricmc.api.ModInitializer;
@@ -42,11 +44,17 @@ public final class ServerEntityLifecycleTests implements ModInitializer {
 	public void onInitialize() {
 		final Logger logger = ServerLifecycleTests.LOGGER;
 
+		ServerEntityEvents.ENTITY_TICK.register((entity, world) -> {
+			if (PRINT_SERVER_ENTITY_MESSAGES && entity instanceof PlayerEntity player && player.getMainHandStack().isOf(Items.LILY_PAD) && player.isSneaking()) {
+				logger.info("[SERVER] TICKING {}.", player.getName().getString());
+			}
+		});
+
 		ServerEntityEvents.ENTITY_LOAD.register((entity, world) -> {
 			this.serverEntities.add(entity);
 
 			if (PRINT_SERVER_ENTITY_MESSAGES) {
-				logger.info("[SERVER] LOADED " + entity.toString() + " - Entities: " + this.serverEntities.size());
+				logger.info("[SERVER] LOADED {} - Entities: {}", entity.toString(), this.serverEntities.size());
 			}
 		});
 
@@ -54,7 +62,7 @@ public void onInitialize() {
 			this.serverEntities.remove(entity);
 
 			if (PRINT_SERVER_ENTITY_MESSAGES) {
-				logger.info("[SERVER] UNLOADED " + entity.toString() + " - Entities: " + this.serverEntities.size());
+				logger.info("[SERVER] UNLOADED {} - Entities: {}", entity.toString(), this.serverEntities.size());
 			}
 		});
 
@@ -72,7 +80,7 @@ public void onInitialize() {
 					final int worldEntities = Iterables.size(world.iterateEntities());
 
 					if (PRINT_SERVER_ENTITY_MESSAGES) {
-						logger.info("[SERVER] Tracked Entities in " + world.getRegistryKey().toString() + " - " + worldEntities);
+						logger.info("[SERVER] Tracked Entities in {} - {}", world.getRegistryKey().toString(), worldEntities);
 					}
 
 					entities += worldEntities;
@@ -92,7 +100,7 @@ public void onInitialize() {
 		ServerLifecycleEvents.SERVER_STOPPED.register(server -> {
 			logger.info("[SERVER] Disconnected. Tracking: " + this.serverEntities.size() + " entities");
 
-			if (this.serverEntities.size() != 0) {
+			if (!this.serverEntities.isEmpty()) {
 				logger.error("[SERVER] Mismatch in tracked entities, expected 0");
 			}
 		});
diff --git a/fabric-lifecycle-events-v1/src/testmod/resources/fabric.mod.json b/fabric-lifecycle-events-v1/src/testmod/resources/fabric.mod.json
index a6bdc95691..d5a3e74c71 100644
--- a/fabric-lifecycle-events-v1/src/testmod/resources/fabric.mod.json
+++ b/fabric-lifecycle-events-v1/src/testmod/resources/fabric.mod.json
@@ -12,6 +12,7 @@
     "main": [
       "net.fabricmc.fabric.test.event.lifecycle.CommonLifecycleTests",
       "net.fabricmc.fabric.test.event.lifecycle.ServerBlockEntityLifecycleTests",
+      "net.fabricmc.fabric.test.event.lifecycle.ServerChunkLifecycleTests",
       "net.fabricmc.fabric.test.event.lifecycle.ServerEntityLifecycleTests",
       "net.fabricmc.fabric.test.event.lifecycle.ServerLifecycleTests",
       "net.fabricmc.fabric.test.event.lifecycle.ServerTickTests",