diff --git a/format.c b/format.c
index b913f56a..80e72cf0 100644
--- a/format.c
+++ b/format.c
@@ -41,7 +41,6 @@
 struct format_expand_state;
 
 static char	*format_job_get(struct format_expand_state *, const char *);
-static void	 format_job_timer(int, short, void *);
 static char	*format_expand1(struct format_expand_state *, const char *);
 static int	 format_replace(struct format_expand_state *, const char *,
 		     size_t, char **, size_t *, size_t *);
@@ -69,7 +68,6 @@ struct format_job {
 };
 
 /* Format job tree. */
-static struct event format_job_event;
 static int format_job_cmp(struct format_job *, struct format_job *);
 static RB_HEAD(format_job_tree, format_job) format_jobs = RB_INITIALIZER();
 RB_GENERATE_STATIC(format_job_tree, format_job, entry, format_job_cmp);
@@ -437,6 +435,19 @@ format_job_tidy(struct format_job_tree *jobs, int force)
 	}
 }
 
+/* Tidy old jobs for all clients. */
+void
+format_tidy_jobs(void)
+{
+	struct client	*c;
+
+	format_job_tidy(&format_jobs, 0);
+	TAILQ_FOREACH(c, &clients, entry) {
+		if (c->jobs != NULL)
+			format_job_tidy(c->jobs, 0);
+	}
+}
+
 /* Remove old jobs for client. */
 void
 format_lost_client(struct client *c)
@@ -446,23 +457,6 @@ format_lost_client(struct client *c)
 	free(c->jobs);
 }
 
-/* Remove old jobs periodically. */
-static void
-format_job_timer(__unused int fd, __unused short events, __unused void *arg)
-{
-	struct client	*c;
-	struct timeval	 tv = { .tv_sec = 60 };
-
-	format_job_tidy(&format_jobs, 0);
-	TAILQ_FOREACH(c, &clients, entry) {
-		if (c->jobs != NULL)
-			format_job_tidy(c->jobs, 0);
-	}
-
-	evtimer_del(&format_job_event);
-	evtimer_add(&format_job_event, &tv);
-}
-
 /* Wrapper for asprintf. */
 static char * printflike(1, 2)
 format_printf(const char *fmt, ...)
@@ -3048,11 +3042,6 @@ format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
 {
 	struct format_tree	*ft;
 
-	if (!event_initialized(&format_job_event)) {
-		evtimer_set(&format_job_event, format_job_timer, NULL);
-		format_job_timer(-1, 0, NULL);
-	}
-
 	ft = xcalloc(1, sizeof *ft);
 	RB_INIT(&ft->tree);
 
diff --git a/server.c b/server.c
index a286e779..6ac08a4d 100644
--- a/server.c
+++ b/server.c
@@ -48,6 +48,7 @@ static int		 server_fd = -1;
 static uint64_t		 server_client_flags;
 static int		 server_exit;
 static struct event	 server_ev_accept;
+static struct event	 server_ev_tidy;
 
 struct cmd_find_state	 marked_pane;
 
@@ -151,15 +152,29 @@ fail:
 	return (-1);
 }
 
+/* Tidy up every hour. */
+static void
+server_tidy_event(__unused int fd, __unused short events, __unused void *data)
+{
+    struct timeval	tv = { .tv_sec = 3600 };
+    uint64_t		t = get_timer();
+
+    format_tidy_jobs();
+
+    log_debug("%s: took %llu milliseconds", __func__, get_timer() - t);
+    evtimer_add(&server_ev_tidy, &tv);
+}
+
 /* Fork new server. */
 int
 server_start(struct tmuxproc *client, int flags, struct event_base *base,
     int lockfd, char *lockfile)
 {
-	int		  fd;
-	sigset_t	  set, oldset;
-	struct client	 *c = NULL;
-	char		 *cause = NULL;
+	int		 fd;
+	sigset_t	 set, oldset;
+	struct client	*c = NULL;
+	char		*cause = NULL;
+	struct timeval	 tv = { .tv_sec = 3600 };
 
 	sigfillset(&set);
 	sigprocmask(SIG_BLOCK, &set, &oldset);
@@ -218,6 +233,9 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base,
 		free(cause);
 	}
 
+	evtimer_set(&server_ev_tidy, server_tidy_event, NULL);
+	evtimer_add(&server_ev_tidy, &tv);
+
 	server_add_accept(0);
 	proc_loop(server_proc, server_loop);
 
diff --git a/tmux.h b/tmux.h
index e8d2e8c3..1fc27b53 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1947,6 +1947,7 @@ char		*paste_make_sample(struct paste_buffer *);
 struct format_tree;
 struct format_modifier;
 typedef void *(*format_cb)(struct format_tree *);
+void		 format_tidy_jobs(void);
 const char	*format_skip(const char *, const char *);
 int		 format_true(const char *);
 struct format_tree *format_create(struct client *, struct cmdq_item *, int,