diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm
index fa0c93cd29d..cc882df9b9a 100644
--- a/code/controllers/subsystem/timer.dm
+++ b/code/controllers/subsystem/timer.dm
@@ -548,6 +548,77 @@ SUBSYSTEM_DEF(timer)
else
. = "[callBack.object.type]"
+GLOBAL_LIST_EMPTY(timers_by_type)
+// Allows us to track what types generate the most timers. Just invokes the global addtimer
+/datum/proc/addtimer(datum/callback/callback, wait = 0, flags = 0)
+ var/tt = "[type]"
+ if(tt in GLOB.timers_by_type)
+ GLOB.timers_by_type[tt]++
+ else
+ GLOB.timers_by_type[tt] = 1
+ return global.addtimer(callback, wait, flags)
+
+/**
+ * Opens a log of timers
+ *
+ * In-round ability to view what has created a timer, and how many times a timer for that path has been created
+ */
+/client/proc/timer_log()
+ set name = "View Timer Log"
+ set category = "Debug"
+ set desc = "Shows the log of what types created timers this round"
+
+ if(!check_rights(R_DEBUG))
+ return
+
+ var/list/sorted = sortTim(GLOB.timers_by_type, cmp=/proc/cmp_numeric_dsc, associative = TRUE)
+ var/list/text = list("
Timer Log
", "")
+ for(var/key in sorted)
+ text += "- [key] - [sorted[key]]
"
+
+ text += "
"
+ usr << browse(text.Join(), "window=timerlog")
+
+/client/proc/debug_timers()
+ set name = "Debug Timers"
+ set category = "Debug"
+ set desc = "Shows currently active timers, grouped by callback"
+
+ var/list/timers = list()
+ for(var/id in SStimer.timer_id_dict)
+ var/datum/timedevent/T = SStimer.timer_id_dict[id]
+ var/cbtxt = "[T.callBack.delegate]"
+ if(cbtxt in timers)
+ timers[cbtxt]++
+ else
+ timers[cbtxt] = 1
+
+
+ var/list/sorted = sortTim(timers, cmp=/proc/cmp_numeric_dsc, associative = TRUE)
+ var/list/text = list("All active timers sorted by callback
", "")
+ for(var/key in sorted)
+ text += "- [key] - [sorted[key]]
"
+
+ text += "
"
+
+ var/list/timers2 = list()
+
+ for(var/datum/timedevent/T in SStimer.bucket_list)
+ var/cbtxt = "[T.callBack.delegate]"
+ if(cbtxt in timers2)
+ timers2[cbtxt]++
+ else
+ timers2[cbtxt] = 1
+
+ text += "All buckets, sorted by callback
"
+ var/list/sorted2 = sortTim(timers2, cmp=/proc/cmp_numeric_dsc, associative = TRUE)
+ for(var/key in sorted2)
+ text += "- [key] - [sorted2[key]]
"
+
+ text += "
"
+ usr << browse(text.Join(), "window=timerdebug")
+
+
/**
* Create a new timer and insert it in the queue.
* You should not call this directly, and should instead use the addtimer macro, which includes source information.
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index e56b0c2b8c9..5b2ee652e76 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -173,6 +173,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug, list(
#endif
/client/proc/dmapi_debug,
/client/proc/dmapi_log,
+ /client/proc/timer_log,
+ /client/proc/debug_timers,
))
GLOBAL_LIST_INIT(admin_verbs_possess, list(
/proc/possess,