diff --git a/src/metabase/driver/ddl/interface.clj b/src/metabase/driver/ddl/interface.clj
index c8b57994cb9b062f9b5398b3f88fe7eda992d6f3..3a00b1fb0a52cd57ae5eadd8ae76be48ba6c71e7 100644
--- a/src/metabase/driver/ddl/interface.clj
+++ b/src/metabase/driver/ddl/interface.clj
@@ -2,7 +2,15 @@
   (:require
    [clojure.string :as str]
    [metabase.driver :as driver]
-   [metabase.util.i18n :refer [tru]]))
+   [metabase.public-settings :as public-settings]
+   [metabase.util.i18n :refer [tru]])
+  (:import
+   (java.time Instant)
+   (java.time.format DateTimeFormatter)))
+
+(set! *warn-on-reflection* true)
+
+
 
 (defn schema-name
   "Returns a schema name for persisting models. Needs the database to use the db id and the site-uuid to ensure that
@@ -41,6 +49,31 @@
   (fn [database] (driver/dispatch-on-initialized-driver (:engine database)))
   :hierarchy #'driver/hierarchy)
 
+(defn create-kv-table-honey-sql-form
+  "The honeysql form that creates the persisted schema `cache_info` table."
+  [schema-name]
+  {:create-table [(keyword schema-name "cache_info") :if-not-exists]
+   :with-columns [[:key :text] [:value :text]]})
+
+(defn kv-table-values
+  "Version 1 of the values to go in the key/value table `cache_info` table."
+  []
+  [{:key   "settings-version"
+    :value "1"}
+   {:key   "created-at"
+    ;; "2023-03-29T14:01:27.871697Z"
+    :value (.format DateTimeFormatter/ISO_INSTANT (Instant/now))}
+   {:key   "instance-uuid"
+    :value (public-settings/site-uuid)}
+   {:key   "instance-name"
+    :value (public-settings/site-name)}])
+
+(defn populate-kv-table-honey-sql-form
+  "The honeysql form that populates the persisted schema `cache_info` table."
+  [schema-name]
+  {:insert-into [(keyword schema-name "cache_info")]
+   :values (kv-table-values)})
+
 (defn error->message
   "Human readable messages for different connection errors."
   [error schema]
diff --git a/src/metabase/driver/mysql/ddl.clj b/src/metabase/driver/mysql/ddl.clj
index 920664aa15bfc2abec829ca80d647c902057a0f0..6086ca0c76dbd00638280a6edfa0f31ab0c0ca3b 100644
--- a/src/metabase/driver/mysql/ddl.clj
+++ b/src/metabase/driver/mysql/ddl.clj
@@ -3,6 +3,7 @@
    [clojure.core.async :as a]
    [clojure.java.jdbc :as jdbc]
    [clojure.string :as str]
+   [honey.sql :as sql]
    [java-time :as t]
    [metabase.driver.ddl.interface :as ddl.i]
    [metabase.driver.sql-jdbc.connection :as sql-jdbc.conn]
@@ -117,7 +118,20 @@
                 (fn delete-table [conn]
                   (sql.ddl/execute! conn [(sql.ddl/drop-table-sql database table-name)]))
                 ;; This will never be called, if the last step fails it does not need to be undone
-                (constantly nil)]]]
+                (constantly nil)]
+               [:persist.check/create-kv-table
+                (fn create-kv-table [conn]
+                  (sql.ddl/execute! conn [(format "drop table if exists %s.cache_info"
+                                                  schema-name)])
+                  (sql.ddl/execute! conn (sql/format
+                                          (ddl.i/create-kv-table-honey-sql-form schema-name)
+                                          {:dialect :mysql})))]
+               [:persist.check/populate-kv-table
+                (fn create-kv-table [conn]
+                  (sql.ddl/execute! conn (sql/format
+                                          (ddl.i/populate-kv-table-honey-sql-form
+                                           schema-name)
+                                          {:dialect :mysql})))]]]
     ;; Unlike postgres, mysql ddl clauses will not rollback in a transaction.
     ;; So we keep track of undo-steps to manually rollback previous, completed steps.
     (jdbc/with-db-connection [conn db-spec]
diff --git a/src/metabase/driver/postgres/ddl.clj b/src/metabase/driver/postgres/ddl.clj
index aed71ea2e1f13442947a647d29d8c78235027b15..596a55440b9755de49be5200abd11c2ca7840d58 100644
--- a/src/metabase/driver/postgres/ddl.clj
+++ b/src/metabase/driver/postgres/ddl.clj
@@ -69,17 +69,30 @@
                      [:persist.check/create-table
                       (fn create-table [conn]
                         (sql.ddl/execute! conn [(sql.ddl/create-table-sql database
-                                                          {:table-name table-name
-                                                           :field-definitions [{:field-name "field"
-                                                                                :base-type :type/Text}]}
-                                                          "select 1")]))]
+                                                                          {:table-name table-name
+                                                                           :field-definitions [{:field-name "field"
+                                                                                                :base-type :type/Text}]}
+                                                                          "select 1")]))]
                      [:persist.check/read-table
                       (fn read-table [conn]
                         (sql.ddl/jdbc-query conn [(format "select * from %s.%s"
-                                                   schema-name table-name)]))]
+                                                          schema-name table-name)]))]
                      [:persist.check/delete-table
                       (fn delete-table [conn]
-                        (sql.ddl/execute! conn [(sql.ddl/drop-table-sql database table-name)]))]]]
+                        (sql.ddl/execute! conn [(sql.ddl/drop-table-sql database table-name)]))]
+                     [:persist.check/create-kv-table
+                      (fn create-kv-table [conn]
+                        (sql.ddl/execute! conn [(format "drop table if exists %s.cache_info"
+                                                        schema-name)])
+                        (sql.ddl/execute! conn (sql/format
+                                                (ddl.i/create-kv-table-honey-sql-form schema-name)
+                                                {:dialect :ansi})))]
+                     [:persist.check/populate-kv-table
+                      (fn create-kv-table [conn]
+                        (sql.ddl/execute! conn (sql/format
+                                                (ddl.i/populate-kv-table-honey-sql-form
+                                                 schema-name)
+                                                {:dialect :ansi})))]]]
     (jdbc/with-db-connection [conn (sql-jdbc.conn/db->pooled-connection-spec database)]
       (jdbc/with-db-transaction
         [tx conn]
diff --git a/test/metabase/query_processor/persistence_test.clj b/test/metabase/query_processor/persistence_test.clj
index dd9ead9c2344a4c65b28e138a531ef1a7cedbac7..0e1de01bd53fb27832d499578fc560177cebcbde 100644
--- a/test/metabase/query_processor/persistence_test.clj
+++ b/test/metabase/query_processor/persistence_test.clj
@@ -3,6 +3,7 @@
    [clojure.core.async :as a]
    [clojure.string :as str]
    [clojure.test :refer :all]
+   [honey.sql :as sql]
    [metabase.driver :as driver]
    [metabase.driver.ddl.interface :as ddl.i]
    [metabase.models :refer [Card]]
@@ -13,7 +14,12 @@
    [metabase.query-processor.middleware.fix-bad-references
     :as fix-bad-refs]
    [metabase.test :as mt]
-   [toucan2.core :as t2]))
+   [toucan2.core :as t2])
+  (:import
+   (java.time Instant)
+   (java.time.temporal ChronoUnit)))
+
+(set! *warn-on-reflection* true)
 
 (deftest can-persist-test
   (testing "Can each database that allows for persistence actually persist"
@@ -22,7 +28,29 @@
         (mt/dataset test-data
           (let [[success? error] (ddl.i/check-can-persist (mt/db))]
             (is success? (str "Not able to persist on " driver/*driver*))
-            (is (= :persist.check/valid error))))))))
+            (is (= :persist.check/valid error)))
+          (testing "Populates the `cache_info` table with v1 information"
+            (let [schema-name (ddl.i/schema-name (mt/db) (public-settings/site-uuid))
+                  query       {:query
+                               (first
+                                (sql/format {:select [:key :value]
+                                             :from   [(keyword schema-name "cache_info")]}
+                                            {:dialect (if (= (:engine (mt/db)) :mysql)
+                                                        :mysql
+                                                        :ansi)}))}
+                  values      (into {} (->> query mt/native-query qp/process-query mt/rows))]
+              (is (partial= {"settings-version" "1"
+                             "instance-uuid"    (public-settings/site-uuid)}
+                            (into {} (->> query mt/native-query qp/process-query mt/rows))))
+              (let [[low high]       [(.minus (Instant/now) 1 ChronoUnit/MINUTES)
+                                      (.plus (Instant/now) 1 ChronoUnit/MINUTES)]
+                    ^Instant created (some-> (get values "created-at")
+                                             (java.time.Instant/parse))]
+                (if created
+                  (is (and (.isAfter created low) (.isBefore created high))
+                      "Date was not created recently")
+                  (throw (ex-info "Did not find `created-at` in `cache_info` table"
+                                  {})))))))))))
 
 (deftest persisted-models-max-rows-test
   (testing "Persisted models should have the full number of rows of the underlying query,