diff --git a/enterprise/backend/src/metabase_enterprise/serialization/upsert.clj b/enterprise/backend/src/metabase_enterprise/serialization/upsert.clj
index 8caea6552831afea68142e6deb9cde6acf860d79..6aba8857b7e0807a6707be6f67d7127d7150dd9a 100644
--- a/enterprise/backend/src/metabase_enterprise/serialization/upsert.clj
+++ b/enterprise/backend/src/metabase_enterprise/serialization/upsert.clj
@@ -27,7 +27,6 @@
    [metabase.util.i18n :as i18n :refer [trs]]
    [metabase.util.log :as log]
    [methodical.core :as methodical]
-   [toucan.db :as db]
    [toucan2.core :as t2]
    [toucan2.tools.after :as t2.after]))
 
@@ -91,9 +90,9 @@
   (if (has-post-insert? model)
     (insert-many-individually! model on-error entities)
     (if (= :abort on-error)
-      (db/insert-many! model entities)
+      (t2/insert-returning-pks! model entities)
       (try
-        (db/insert-many! model entities)
+        (t2/insert-returning-pks! model entities)
         ;; Retry each individually so we can do as much as we can
         (catch Throwable _
           (insert-many-individually! model on-error entities))))))
diff --git a/enterprise/backend/test/metabase_enterprise/content_management/api/review_test.clj b/enterprise/backend/test/metabase_enterprise/content_management/api/review_test.clj
index c77e02ebcf25c0ce11db80228d9bcc88395a91d6..a92424e30b8bda5811d52a7e1dc9e2467f9daf56 100644
--- a/enterprise/backend/test/metabase_enterprise/content_management/api/review_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/content_management/api/review_test.clj
@@ -5,7 +5,6 @@
    [metabase.models.moderation-review :as moderation-review :refer [ModerationReview]]
    [metabase.public-settings.premium-features-test :as premium-features-test]
    [metabase.test :as mt]
-   [toucan.db :as db]
    [toucan2.core :as t2]))
 
 (defn- normalized-response
@@ -67,13 +66,13 @@
                                :moderated_item_id card-id
                                :moderated_item_type "card"))))))
             (testing "Ensures we never have more than `modreview/max-moderation-reviews`"
-              (db/insert-many! ModerationReview (repeat (* 2 moderation-review/max-moderation-reviews)
-                                                        {:moderated_item_id   card-id
-                                                         :moderated_item_type "card"
-                                                         :moderator_id        (mt/user->id :crowberto)
-                                                         :most_recent         false
-                                                         :status              "verified"
-                                                         :text                "old review"}))
+              (t2/insert! ModerationReview (repeat (* 2 moderation-review/max-moderation-reviews)
+                                                   {:moderated_item_id   card-id
+                                                    :moderated_item_type "card"
+                                                    :moderator_id        (mt/user->id :crowberto)
+                                                    :most_recent         false
+                                                    :status              "verified"
+                                                    :text                "old review"}))
               ;; manually inserted many
 
               (is (> (review-count) moderation-review/max-moderation-reviews))
diff --git a/modules/drivers/bigquery-cloud-sdk/test/metabase/driver/bigquery_cloud_sdk_test.clj b/modules/drivers/bigquery-cloud-sdk/test/metabase/driver/bigquery_cloud_sdk_test.clj
index 7e03429f3e1a70e1d8bd6bcef8c33e4a04c2c58c..580a78c1d1938bcca7078a0c84c60d984194b93f 100644
--- a/modules/drivers/bigquery-cloud-sdk/test/metabase/driver/bigquery_cloud_sdk_test.clj
+++ b/modules/drivers/bigquery-cloud-sdk/test/metabase/driver/bigquery_cloud_sdk_test.clj
@@ -16,7 +16,6 @@
    [metabase.test.util.random :as tu.random]
    [metabase.util :as u]
    [metabase.util.log :as log]
-   [toucan.db :as db]
    [toucan2.core :as t2])
   (:import
    (com.google.cloud.bigquery BigQuery)))
@@ -335,7 +334,7 @@
         (try
           (let [synced-tables (t2/select Table :db_id (mt/id))]
             (is (= 2 (count synced-tables)))
-            (db/insert-many! Table (map #(dissoc % :id :schema) synced-tables))
+            (t2/insert! Table (map #(dissoc % :id :schema) synced-tables))
             (sync/sync-database! (mt/db) {:scan :schema})
             (let [synced-tables (t2/select Table :db_id (mt/id))]
               (is (partial= {true [{:name "messages"} {:name "users"}]
diff --git a/src/metabase/api/bookmark.clj b/src/metabase/api/bookmark.clj
index 9062f576be6e71fef2a7c0af48998e7be931660c..69bfc4695a8110ca0b8e2a592a3392338e90966b 100644
--- a/src/metabase/api/bookmark.clj
+++ b/src/metabase/api/bookmark.clj
@@ -71,7 +71,7 @@
   "Sets the order of bookmarks for user."
   [:as {{:keys [orderings]} :body}]
   {orderings BookmarkOrderings}
-  (bookmark/save-ordering api/*current-user-id* orderings)
+  (bookmark/save-ordering! api/*current-user-id* orderings)
   api/generic-204-no-content)
 
 (api/define-routes)
diff --git a/src/metabase/api/metric.clj b/src/metabase/api/metric.clj
index 25ac7d25fd26a134a4fb7672ef0443cf986a0633..5ae3206884c9009da818180837a54de7b6bb7d03 100644
--- a/src/metabase/api/metric.clj
+++ b/src/metabase/api/metric.clj
@@ -16,7 +16,6 @@
    [metabase.util.malli.schema :as ms]
    [metabase.util.schema :as su]
    [schema.core :as s]
-   [toucan.db :as db]
    [toucan.hydrate :refer [hydrate]]
    [toucan2.core :as t2]))
 
@@ -122,8 +121,8 @@
     (when (seq fields-to-remove)
       (t2/delete! (t2/table-name MetricImportantField) {:metric_id id, :field_id [:in fields-to-remove]}))
     ;; add new fields as needed
-    (db/insert-many! 'MetricImportantField (for [field-id fields-to-add]
-                                             {:metric_id id, :field_id field-id}))
+    (t2/insert! 'MetricImportantField (for [field-id fields-to-add]
+                                        {:metric_id id, :field_id field-id}))
     {:success true}))
 
 
diff --git a/src/metabase/models/bookmark.clj b/src/metabase/models/bookmark.clj
index 00d50657d5a7539ddd2fb1acbbba8f72669d8bb0..13cc3a16bb558f1d6312d38701510c9d668d803f 100644
--- a/src/metabase/models/bookmark.clj
+++ b/src/metabase/models/bookmark.clj
@@ -121,11 +121,11 @@
                      [:created_at :desc]]})
        (map normalize-bookmark-result)))
 
-(defn save-ordering
+(defn save-ordering!
   "Saves a bookmark ordering of shape `[{:type, :item_id}]`
    Deletes all existing orderings for user so should be given a total ordering."
   [user-id orderings]
   (t2/delete! BookmarkOrdering :user_id user-id)
-  (db/insert-many! BookmarkOrdering (->> orderings
-                                         (map #(select-keys % [:type :item_id]))
-                                         (map-indexed #(assoc %2 :user_id user-id :ordering %1)))))
+  (t2/insert! BookmarkOrdering (->> orderings
+                                    (map #(select-keys % [:type :item_id]))
+                                    (map-indexed #(assoc %2 :user_id user-id :ordering %1)))))
diff --git a/src/metabase/models/collection.clj b/src/metabase/models/collection.clj
index fb641a8ce6bc127f2b6729d0b4d5507abaf34d66..95f030befaa96364c6cdb1b966f14a11d1d22ef0 100644
--- a/src/metabase/models/collection.clj
+++ b/src/metabase/models/collection.clj
@@ -694,7 +694,7 @@
         group-ids-with-write-perms (t2/select-fn-set :group_id Permissions
                                                      :object (perms/collection-readwrite-path source-collection-or-id))]
     ;; ...and insert corresponding rows for each destination Collection
-    (db/insert-many! Permissions
+    (t2/insert! Permissions
       (concat
        ;; insert all the new read-perms records
        (for [dest     dest-collections-or-ids
diff --git a/src/metabase/models/dashboard_card.clj b/src/metabase/models/dashboard_card.clj
index dbad3fff94a1b6d5714d8a247bcc840f81dbc564..81d028d4b98884c597f594cd7c66594f4fad0143 100644
--- a/src/metabase/models/dashboard_card.clj
+++ b/src/metabase/models/dashboard_card.clj
@@ -136,7 +136,7 @@
                                 [:= :dashcard.id (:id dashcard)]]}))
 
 (s/defn update-dashboard-card-series!
-  "Update the DashboardCardSeries for a given DashboardCard.
+  "Update the DashboardCardSeries for a given DashboardCard and return the updated DashboardCardSeries.
    `card-ids` should be a definitive collection of *all* IDs of cards for the dashboard card in the desired order.
 
    *  If an ID in `card-ids` has no corresponding existing DashboardCardSeries object, one will be created.
@@ -152,7 +152,7 @@
     (let [cards (map-indexed (fn [i card-id]
                                {:dashboardcard_id id, :card_id card-id, :position i})
                              card-ids)]
-      (db/insert-many! DashboardCardSeries cards))))
+      (t2/insert! DashboardCardSeries cards))))
 
 (def ^:private DashboardCardUpdates
   {:id                                      su/IntGreaterThanZero
diff --git a/src/metabase/models/permissions.clj b/src/metabase/models/permissions.clj
index ec9027a20ff981e5852d4b48cbc1233e0a66fc59..b0eb3d668fddbcdb0bdb22b2c61ecc4fc4418179 100644
--- a/src/metabase/models/permissions.clj
+++ b/src/metabase/models/permissions.clj
@@ -194,7 +194,6 @@
    [metabase.util.regex :as u.regex]
    [metabase.util.schema :as su]
    [schema.core :as s]
-   [toucan.db :as db]
    [toucan.models :as models]
    [toucan2.core :as t2]))
 
@@ -1024,8 +1023,8 @@
   (delete-related-permissions! group-or-id (apply (partial feature-perms-path :download :limited) path-components)))
 
 (defn grant-permissions!
-  "Grant permissions for `group-or-id`. Two-arity grants any arbitrary Permissions `path`. With > 2 args, grants the
-  data permissions from calling [[data-perms-path]]."
+  "Grant permissions for `group-or-id` and return the inserted permissions. Two-arity grants any arbitrary Permissions `path`.
+  With > 2 args, grants the data permissions from calling [[data-perms-path]]."
   ([group-or-id db-id schema & more]
    (grant-permissions! group-or-id (apply data-perms-path db-id schema more)))
 
@@ -1037,10 +1036,10 @@
    (t2/delete! Permissions :group_id (u/the-id group-or-id) :object [:like "/query/%"])
    (t2/delete! Permissions :group_id (u/the-id group-or-id) :object [:like "/data/%"])
    (try
-     (db/insert-many! Permissions
-       (map (fn [path-object]
-              {:group_id (u/the-id group-or-id) :object path-object})
-            (distinct (conj (->v2-path path) path))))
+     (t2/insert-returning-instances! Permissions
+                                     (map (fn [path-object]
+                                            {:group_id (u/the-id group-or-id) :object path-object})
+                                          (distinct (conj (->v2-path path) path))))
      ;; on some occasions through weirdness we might accidentally try to insert a key that's already been inserted
      (catch Throwable e
        (log/error e (u/format-color 'red (tru "Failed to grant permissions")))
diff --git a/src/metabase/models/persisted_info.clj b/src/metabase/models/persisted_info.clj
index 3fceaf6940b313fa6d6e5269cf38817086448dba..9eb1556164f4124b9edf1e8480d9f31d27e7589a 100644
--- a/src/metabase/models/persisted_info.clj
+++ b/src/metabase/models/persisted_info.clj
@@ -8,7 +8,6 @@
    [metabase.util :as u]
    [metabase.util.schema :as su]
    [schema.core :as s]
-   [toucan.db :as db]
    [toucan.models :as models]
    [toucan2.core :as t2]))
 
@@ -119,10 +118,7 @@
                                        [:not [:exists {:select [1]
                                                        :from [:persisted_info]
                                                        :where [:= :persisted_info.card_id :report_card.id]}]]]})]
-    (db/insert-many! PersistedInfo (map #(create-row nil %) cards))))
-
-(comment
-  (ready-unpersisted-models! 183))
+    (t2/insert! PersistedInfo (map #(create-row nil %) cards))))
 
 (defn turn-on-model!
   "Marks PersistedInfo as `creating`, these will at some point be persisted by the PersistRefresh task."
diff --git a/src/metabase/models/pulse.clj b/src/metabase/models/pulse.clj
index a8b9eeabda1f1d920e7420bfbc22e3757d008f60..add0c7d27539d5bea163d1622f477a597315e1eb 100644
--- a/src/metabase/models/pulse.clj
+++ b/src/metabase/models/pulse.clj
@@ -30,7 +30,6 @@
    [metabase.util.i18n :refer [deferred-tru tru]]
    [metabase.util.schema :as su]
    [schema.core :as s]
-   [toucan.db :as db]
    [toucan.hydrate :refer [hydrate]]
    [toucan.models :as models]
    [toucan2.core :as t2]))
@@ -427,7 +426,7 @@
                                 :include_xls       include_xls
                                 :dashboard_card_id dashboard_card_id})
                              card-refs)]
-      (db/insert-many! PulseCard cards))))
+      (t2/insert! PulseCard cards))))
 
 (defn- create-update-delete-channel!
   "Utility function used by [[update-notification-channels!]] which determines how to properly update a single pulse
diff --git a/src/metabase/models/pulse_card.clj b/src/metabase/models/pulse_card.clj
index cc713ff57fb75a4d382a4fa22fd1f87f803e3f18..f92e854bc18e638d7bb8a2dd8bc814ec660ce7e2 100644
--- a/src/metabase/models/pulse_card.clj
+++ b/src/metabase/models/pulse_card.clj
@@ -5,7 +5,6 @@
    [metabase.util :as u]
    [metabase.util.schema :as su]
    [schema.core :as s]
-   [toucan.db :as db]
    [toucan.models :as models]
    [toucan2.core :as t2]))
 
@@ -42,7 +41,7 @@
   "Creates new PulseCards, joining the given card, pulse, and dashboard card and setting appropriate defaults for other
   values if they're not provided."
   [new-pulse-cards :- [NewPulseCard]]
-  (db/insert-many! PulseCard
+  (t2/insert! PulseCard
     (for [{:keys [card_id pulse_id dashboard_card_id position include_csv include_xls]} new-pulse-cards]
       {:card_id           card_id
        :pulse_id          pulse_id
diff --git a/src/metabase/models/pulse_channel.clj b/src/metabase/models/pulse_channel.clj
index 4e9539aae20f48ab3c65e4be2522519a8deb1c85..7343b7d742ce38f0edaecf4e6fb0b58c411e93d8 100644
--- a/src/metabase/models/pulse_channel.clj
+++ b/src/metabase/models/pulse_channel.clj
@@ -12,7 +12,6 @@
    [metabase.util.i18n :refer [tru]]
    [methodical.core :as methodical]
    [schema.core :as s]
-   [toucan.db :as db]
    [toucan.models :as models]
    [toucan2.core :as t2]))
 
@@ -279,7 +278,7 @@
         recipients-    (set/difference recipients-old recipients-new)]
     (when (seq recipients+)
       (let [vs (map #(assoc {:pulse_channel_id id} :user_id %) recipients+)]
-        (db/insert-many! PulseChannelRecipient vs)))
+        (t2/insert! PulseChannelRecipient vs)))
     (when (seq recipients-)
       (t2/delete! (t2/table-name PulseChannelRecipient)
         :pulse_channel_id id
diff --git a/src/metabase/models/user.clj b/src/metabase/models/user.clj
index 46d2a2c10b78f2d1bee515ca8b69a4cbb63be6fb..17c51e0b0df23ad876b18271dbaaa67bdcaf3b82 100644
--- a/src/metabase/models/user.clj
+++ b/src/metabase/models/user.clj
@@ -392,6 +392,7 @@
        ;; a little inefficient, but we need to do a separate `insert!` for each group we're adding membership to,
        ;; because `insert-many!` does not currently trigger methods such as `pre-insert`. We rely on those methods to
        ;; do things like automatically set the `is_superuser` flag for a User
+       ;; TODO use multipel insert here
        (doseq [group-id to-add]
          (t2/insert! PermissionsGroupMembership {:user_id user-id, :group_id group-id}))))
     true))
diff --git a/src/metabase/sync/sync_metadata/fields/sync_instances.clj b/src/metabase/sync/sync_metadata/fields/sync_instances.clj
index 837e553780200374687f265f503fafe008201381..85a31f7353e8a2205d944468dd357abd2742cef1 100644
--- a/src/metabase/sync/sync_metadata/fields/sync_instances.clj
+++ b/src/metabase/sync/sync_metadata/fields/sync_instances.clj
@@ -19,7 +19,6 @@
    [metabase.util.log :as log]
    [metabase.util.schema :as su]
    [schema.core :as s]
-   [toucan.db :as db]
    [toucan2.core :as t2]))
 
 ;;; +----------------------------------------------------------------------------------------------------------------+
@@ -41,7 +40,7 @@
   "Insert new Field rows for for all the Fields described by `new-field-metadatas`."
   [table :- i/TableInstance, new-field-metadatas :- [i/TableMetadataField], parent-id :- common/ParentID]
   (when (seq new-field-metadatas)
-    (db/insert-many! Field
+    (t2/insert-returning-pks! Field
       (for [{:keys [database-type database-is-auto-increment database-required base-type effective-type coercion-strategy
                     field-comment database-position nfc-path visibility-type], field-name :name :as field} new-field-metadatas]
         (do
diff --git a/test/metabase/api/activity_test.clj b/test/metabase/api/activity_test.clj
index e1104e89a3450af831f21fad65e0b51e06673ab4..be80fbf513ae484743f9c81204d9797bb335c70c 100644
--- a/test/metabase/api/activity_test.clj
+++ b/test/metabase/api/activity_test.clj
@@ -15,7 +15,6 @@
    [metabase.test :as mt]
    [metabase.test.fixtures :as fixtures]
    [metabase.util :as u]
-   [toucan.db :as db]
    [toucan2.core :as t2]))
 
 (set! *warn-on-reflection* true)
@@ -110,8 +109,8 @@
                         (reverse views)
                         (range))
                    (group-by #(if (:card_id %) :card :other)))]
-    (db/insert-many! ViewLog (:other views))
-    (db/insert-many! QueryExecution (:card views))))
+    (t2/insert! ViewLog (:other views))
+    (t2/insert! QueryExecution (:card views))))
 
 (deftest recent-views-test
   (mt/with-temp* [Card      [card1 {:name                   "rand-name"
diff --git a/test/metabase/models/params/chain_filter_test.clj b/test/metabase/models/params/chain_filter_test.clj
index 655aec311433ce46f34fabc08287b41ba5df69fb..73b2f8f7edafa228f0e3931b1577620350da25f8 100644
--- a/test/metabase/models/params/chain_filter_test.clj
+++ b/test/metabase/models/params/chain_filter_test.clj
@@ -8,7 +8,6 @@
    [metabase.models.params.field-values :as params.field-values]
    [metabase.test :as mt]
    [metabase.util :as u]
-   [toucan.db :as db]
    [toucan2.core :as t2]))
 
 (defmacro ^:private chain-filter [field field->value & options]
@@ -573,7 +572,7 @@
         (thunk)
         (finally
          (t2/update! Field field-id {:has_field_values has_field_values})
-         (db/insert-many! FieldValues fvs))))))
+         (t2/insert! FieldValues fvs))))))
 
 (defmacro ^:private with-clean-field-values-for-field
   "Run `body` with all FieldValues for `field-id` deleted.
diff --git a/test/metabase/test.clj b/test/metabase/test.clj
index 7d2fb15406e96879e0c19d00c107c75476f30c41..778778679f3ba68b3f386c7293162aeadbf4cf68 100644
--- a/test/metabase/test.clj
+++ b/test/metabase/test.clj
@@ -48,7 +48,6 @@
    [metabase.util.log :as log]
    [pjstadig.humane-test-output :as humane-test-output]
    [potemkin :as p]
-   [toucan.db :as db]
    [toucan.util.test :as tt]
    [toucan2.core :as t2]))
 
@@ -323,7 +322,7 @@
         (t2/delete! User primary-key (primary-key temp-admin))
         (when (seq existing-admin-ids)
           (t2/update! (t2/table-name User) {:id [:in existing-admin-ids]} {:is_superuser true}))
-        (db/insert-many! PermissionsGroupMembership existing-admin-memberships)))))
+        (t2/insert! PermissionsGroupMembership existing-admin-memberships)))))
 
 (defmacro with-single-admin-user
   "Creates an admin user (with details described in the `options-map`) and (temporarily) removes the administrative
diff --git a/test/metabase/test/data/impl.clj b/test/metabase/test/data/impl.clj
index 0a3473eaad352542a9eda1972031b43d848e0938..ae22b60cf62b0e74b3479e207d490c92b9380cda 100644
--- a/test/metabase/test/data/impl.clj
+++ b/test/metabase/test/data/impl.clj
@@ -252,14 +252,14 @@
 ;;; +----------------------------------------------------------------------------------------------------------------+
 
 (defn- copy-table-fields! [old-table-id new-table-id]
-  (db/insert-many! Field
+  (t2/insert! Field
     (for [field (t2/select Field :table_id old-table-id {:order-by [[:id :asc]]})]
       (-> field (dissoc :id :fk_target_field_id) (assoc :table_id new-table-id))))
   ;; now copy the FieldValues as well.
   (let [old-field-id->name (t2/select-pk->fn :name Field :table_id old-table-id)
         new-field-name->id (t2/select-fn->pk :name Field :table_id new-table-id)
         old-field-values   (t2/select FieldValues :field_id [:in (set (keys old-field-id->name))])]
-    (db/insert-many! FieldValues
+    (t2/insert! FieldValues
       (for [{old-field-id :field_id, :as field-values} old-field-values
             :let                                       [field-name (get old-field-id->name old-field-id)]]
         (-> field-values
@@ -268,7 +268,7 @@
 
 (defn- copy-db-tables! [old-db-id new-db-id]
   (let [old-tables    (t2/select Table :db_id old-db-id {:order-by [[:id :asc]]})
-        new-table-ids (db/insert-many! Table
+        new-table-ids (t2/insert-returning-pks! Table
                         (for [table old-tables]
                           (-> table (dissoc :id) (assoc :db_id new-db-id))))]
     (doseq [[old-table-id new-table-id] (zipmap (map :id old-tables) new-table-ids)]
@@ -310,7 +310,7 @@
   (let [prop->old-id (get-linked-secrets database)]
     (if (seq prop->old-id)
       (let [secrets (t2/select [Secret :id :name :kind :source :value] :id [:in (set (vals prop->old-id))])
-            new-ids (db/insert-many! Secret (map #(dissoc % :id) secrets))
+            new-ids (t2/insert-returning-pks! Secret (map #(dissoc % :id) secrets))
             old-id->new-id (zipmap (map :id secrets) new-ids)]
         (assoc database
                :details