                                   "purge_reports"))
                               "other"])]
             (interspaced gc-interval-millis
-                         #(try
-                            (clean-up write-db database what)
-                            (catch Exception ex
-                              (log/error ex)))
+                         (fn []
+                           (.lock clean-lock)
+                           (try
+                             (try
+                               (clean-up write-db clean-lock database what)
+                               (catch Exception ex
+                                 (log/error ex)))
+                             (finally
+                               (.unlock clean-lock))))
                          job-pool)))
         (when (pos? dlo-compression-interval-millis)
           (interspaced dlo-compression-interval-millis

  "Cleans up the resources specified by request, or everything if
  request is empty?."
  [db
   {:keys [node-ttl node-purge-ttl report-ttl]} :- {:node-ttl Period
                                                    :node-purge-ttl Period
                                                    :report-ttl Period
                                                    s/Keyword s/Any}
   ;; Later, the values might be maps, i.e. {:limit 1000}
   request :- clean-request-schema]
  (let [request (if (empty? request) clean-options (set request))]
    (when (request "expire_nodes")
      (auto-expire-nodes! node-ttl db))

                     (throw e)))
          globals {:scf-read-db read-db
                   :scf-write-db write-db
                   :pretty-print pretty-print}
          clean-lock (ReentrantLock.)]
      (transfer-old-messages! (conf/mq-endpoint config))

      (when-not disable-update-checking
