The Problem
Your playbook hangs on "Gathering Facts" for minutes, or times out entirely:
TASK [Gathering Facts] *********************************************************
fatal: [slowserver]: FAILED! => {"msg": "Timeout (12s) waiting for privilege escalation prompt:"}
Solution 1: Disable Facts When Not Needed
- hosts: webservers
gather_facts: false # Skip if you don't need ansible_* variables
tasks:
- name: Copy config file
ansible.builtin.copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
Solution 2: Gather Only What You Need
- hosts: webservers
gather_facts: true
gather_subset:
- network
- hardware
# Skip: all, min, distribution, devices, virtual, ohai, facter
tasks:
- debug:
msg: "IP: {{ ansible_default_ipv4.address }}"
Minimum facts (fastest):
gather_subset:
- "!all"
- "!min"
- network
Solution 3: Enable Fact Caching
# ansible.cfg
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts_cache
fact_caching_timeout = 86400 # 24 hours
Or use Redis for multi-user environments:
[defaults]
fact_caching = redis
fact_caching_connection = localhost:6379:0
fact_caching_timeout = 3600
Solution 4: Increase Timeout
# ansible.cfg
[defaults]
gather_timeout = 30 # default is 10
[ssh_connection]
ssh_args = -o ConnectTimeout=30
Solution 5: Use Async & Forks
# ansible.cfg
[defaults]
forks = 20 # default is 5 — run on 20 hosts simultaneously
Performance Comparison
| Method | 100 Hosts | Improvement |
|---|---|---|
| Default | ~200s | baseline |
| gather_subset: min | ~80s | 2.5x faster |
| gather_facts: false | ~20s | 10x faster |
| Fact caching (warm) | ~5s | 40x faster |
| forks=20 | ~40s | 5x faster |
Conclusion
For maximum speed: disable facts when possible, use gather_subset when you need them, and enable fact caching for repeated runs. Combining these techniques can speed up playbooks by 10-40x.