diff --git a/ansible/gather-facts.yml b/ansible/gather-facts.yml
index 8ec05730fb255136bab2f075ac4c13444138be17..25f84368fb388da74b8fac2b0c453e3f5e5c528b 100644
--- a/ansible/gather-facts.yml
+++ b/ansible/gather-facts.yml
@@ -1,17 +1,12 @@
 ---
 # NOTE(awiddersheim): Gather facts for all hosts as a
 # first step since several plays below require them when
-# building their configurations. The below 'gather_facts'
-# set to 'false' is a bit confusing but this is to avoid
-# Ansible gathering facts twice.
+# building their configurations.
 - name: Gather facts for all hosts
   hosts: all
   serial: '{{ kolla_serial|default("0") }}'
-  gather_facts: false
+  gather_facts: true
   tasks:
-    - name: Gather facts
-      setup:
-
     - name: Group hosts to determine when using --limit
       group_by:
         key: "all_using_limit_{{ (ansible_play_batch | length) != (groups['all'] | length) }}"
@@ -40,5 +35,6 @@
       delegate_to: "{{ item }}"
       with_items: "{{ delegate_hosts }}"
       # We gathered facts for all hosts in the batch during the first play.
-      when: item not in ansible_play_batch
+      when:
+        - not hostvars[item].module_setup | default(false)
   tags: always
diff --git a/releasenotes/notes/avoid-unconditional-fact-gathering-94760984b2de0796.yaml b/releasenotes/notes/avoid-unconditional-fact-gathering-94760984b2de0796.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bf4137ce8eacf8d58af6fc6114803caad30d5a9e
--- /dev/null
+++ b/releasenotes/notes/avoid-unconditional-fact-gathering-94760984b2de0796.yaml
@@ -0,0 +1,8 @@
+---
+upgrade:
+  - |
+    Avoids unnecessary fact gathering using the ``setup`` module. This should
+    improve the performance of environments using fact caching and the Ansible
+    ``smart`` fact gathering policy. See `blueprint
+    <https://blueprints.launchpad.net/kolla-ansible/+spec/performance-improvements>`__
+    for details.