diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx
index 1ef30c080..0c721517b 100644
--- a/src/event/Loop.cxx
+++ b/src/event/Loop.cxx
@@ -131,14 +131,6 @@ EventLoop::AddTimer(TimerEvent &t, std::chrono::steady_clock::duration d) noexce
 	again = true;
 }
 
-void
-EventLoop::CancelTimer(TimerEvent &t) noexcept
-{
-	assert(IsInside());
-
-	timers.erase(timers.iterator_to(t));
-}
-
 inline std::chrono::steady_clock::duration
 EventLoop::HandleTimers() noexcept
 {
diff --git a/src/event/Loop.hxx b/src/event/Loop.hxx
index 93080afbe..442b53004 100644
--- a/src/event/Loop.hxx
+++ b/src/event/Loop.hxx
@@ -64,7 +64,7 @@ class EventLoop final : SocketMonitor
 
 	using TimerSet =
 		boost::intrusive::multiset<TimerEvent,
-					   boost::intrusive::base_hook<boost::intrusive::set_base_hook<>>,
+					   boost::intrusive::base_hook<boost::intrusive::set_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>>,
 					   boost::intrusive::compare<TimerCompare>,
 					   boost::intrusive::constant_time_size<false>>;
 	TimerSet timers;
@@ -186,7 +186,6 @@ public:
 
 	void AddTimer(TimerEvent &t,
 		      std::chrono::steady_clock::duration d) noexcept;
-	void CancelTimer(TimerEvent &t) noexcept;
 
 	/**
 	 * Schedule a call to DeferEvent::RunDeferred().
diff --git a/src/event/TimerEvent.cxx b/src/event/TimerEvent.cxx
index 5b21ecd00..4eff77369 100644
--- a/src/event/TimerEvent.cxx
+++ b/src/event/TimerEvent.cxx
@@ -20,13 +20,6 @@
 #include "TimerEvent.hxx"
 #include "Loop.hxx"
 
-void
-TimerEvent::Cancel() noexcept
-{
-	if (IsActive())
-		loop.CancelTimer(*this);
-}
-
 void
 TimerEvent::Schedule(std::chrono::steady_clock::duration d) noexcept
 {
diff --git a/src/event/TimerEvent.hxx b/src/event/TimerEvent.hxx
index c47314086..4081c370b 100644
--- a/src/event/TimerEvent.hxx
+++ b/src/event/TimerEvent.hxx
@@ -37,7 +37,7 @@ class EventLoop;
  * as thread-safe.
  */
 class TimerEvent final
-	: public boost::intrusive::set_base_hook<>
+	: public boost::intrusive::set_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>
 {
 	friend class EventLoop;
 
@@ -57,10 +57,6 @@ public:
 		:loop(_loop), callback(_callback) {
 	}
 
-	~TimerEvent() noexcept {
-		Cancel();
-	}
-
 	auto &GetEventLoop() const noexcept {
 		return loop;
 	}
@@ -70,7 +66,10 @@ public:
 	}
 
 	void Schedule(std::chrono::steady_clock::duration d) noexcept;
-	void Cancel() noexcept;
+
+	void Cancel() noexcept {
+		unlink();
+	}
 
 private:
 	void Run() noexcept {