         servers (into {} (for [[k v] servers]
                            [k (assoc v :html (build-server-popover v))]))]
     (reset! cached {:updated-at now
-                    :regions new-regions
-                    :servers servers
-                    :tables  (group-by-tables new-regions)})))
+                    :regions    new-regions
+                    :servers    servers
+                    :tables     (group-by-tables new-regions)
+                    :response   {}})))
 
 (defn start-periodic-updater!
   "Starts a thread that periodically runs update-regions!"

              (wrap-routes wrap-defaults site-defaults))
          (-> api-routes
              (wrap-routes wrap-defaults api-defaults)
              wrap-json-response

              ;; Response middlewares
              wrap-gzip

        (catch Exception e
          (util/error e)))
      (recur))))

(defn json-response
  [data]
  (-> data json/generate-string response))

(defmacro cached-json-response
  [[& keys] & forms]
  (let [keys (vec keys)]
    `(if-let [body# (get-in @cached [:response ~keys])]
       (do
         (util/debug (format "Returning cached JSON [%s]" (str ~keys)))
         (response body#))
       (let [json# (json/generate-string (do ~@forms))]
         (swap! cached #(assoc-in % [:response ~keys] json#))
         (response json#)))))

;;; Compojure route for web app
(defroutes app-routes
