--- a/net/minecraft/world/entity/ai/sensing/Sensor.java
+++ b/net/minecraft/world/entity/ai/sensing/Sensor.java
@@ -26,8 +26,21 @@
         .ignoreInvisibilityTesting();
     private final int scanRate;
     private long timeToTick;
+    // Paper start - configurable sensor tick rate and timings
+    private final String configKey;
+    private final co.aikar.timings.Timing timing;
+    // Paper end
 
     public Sensor(int senseInterval) {
+        // Paper start - configurable sensor tick rate and timings
+        String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName();
+        int lastSeparator = key.lastIndexOf('.');
+        if (lastSeparator != -1) {
+            key = key.substring(lastSeparator + 1);
+        }
+        this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+        this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey, senseInterval);
+        // Paper end
         this.scanRate = senseInterval;
         this.timeToTick = (long)RANDOM.nextInt(senseInterval);
     }
@@ -38,8 +51,12 @@
 
     public final void tick(ServerLevel world, E entity) {
         if (--this.timeToTick <= 0L) {
-            this.timeToTick = (long)this.scanRate;
+            // Paper start - configurable sensor tick rate and timings
+            this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate);
+            this.timing.startTiming();
+            // Paper end
             this.doTick(world, entity);
+            this.timing.stopTiming(); // Paper - sensor timings
         }
     }
 
