diff --git a/src/metabase/models/card.clj b/src/metabase/models/card.clj
index 7d0df9af8bd8c5cf673a33343870a6086c9913bb..651073b3a528cf536c2d4bf0fd7c4b22bdf8d14d 100644
--- a/src/metabase/models/card.clj
+++ b/src/metabase/models/card.clj
@@ -548,12 +548,14 @@
       pre-update
       populate-query-fields
       maybe-populate-initially-published-at
-      ;; TODO: this should go in after-update once camsaul/toucan2#129 is fixed
-      ;; It's at the end for now so that all the before-update validations have a chance to run
-      ;; TODO the Second: No reason this couldn't be async, especially once it's in the after-update
-      (doto query-analyzer/update-query-fields-for-card!)
       (dissoc :id)))
 
+(t2/define-after-update :model/Card
+  [card]
+  (u/prog1 card
+    (when (contains? (t2/changes card) :dataset_query)
+      (query-analyzer/update-query-fields-for-card! card))))
+
 ;; Cards don't normally get deleted (they get archived instead) so this mostly affects tests
 (t2/define-before-delete :model/Card
   [{:keys [id] :as _card}]