Q: Ansible playbook runs take over 15 minutes across a fleet of 800 servers, with 70% of execution time spent during fact-gathering. How do you optimize fact gathering and caching?
Fact gathering against large fleets creates severe network and CPU bottlenecks. Optimize by disabling facts when not needed, filtering specific facts, or implementing persistent fact caching with Redis or JSON backends.
Want to master this scenario in a live sandbox? KodeKloud's CKA & CKAD Hands-On Certification Track covers this exact problem with hands-on terminal drills.
🛠️ Production Runbook & Step-by-Step Resolution
Disable Facts When Not Required
Most deployment playbooks only deploy pre-built packages and configurations, requiring zero host facts. Turn off fact gathering globally in the play:
gather_facts: falseat the top of your play.- Saves 100% of the fact collection phase, reducing start times from minutes to seconds.
Gather Only Specific Fact Subsets
If your play only needs networking or OS family information, prune the gathering scope using gather_subset:
gather_subset: ['!all', '!min', 'network']- Avoids expensive disk partition, hardware, and virtual memory scans across large fleets.
Implement Centralized Fact Caching (Redis/JSON)
Cache gathered facts persistently on the controller or in Redis so subsequent runs bypass the setup module entirely:
- In
ansible.cfg, configure Redis caching:gathering = smartfact_caching = redisfact_caching_timeout = 86400fact_caching_connection = localhost:6379:0 - With
gathering = smart, Ansible only collects facts if the cache has expired or host is new.
- The default setup module collects hundreds of facts per host, creating severe network bottlenecks on 500+ node fleets.
- Set 'gather_facts: false' for standard application deployments that do not evaluate host conditions.
- Use 'gather_subset: ["!all", "network"]' to collect only the specific facts your templates require.
- Enable 'gathering = smart' in ansible.cfg to automatically skip fact gathering if facts are already cached.
- Implement high-performance fact caching using Redis ('fact_caching = redis') with a 24-hour TTL.
- For simple controllers, use file-based JSON caching ('fact_caching = jsonfile') stored in /tmp/ansible_facts.
Senior hiring managers and bar raisers evaluate how you prioritize during outages. Avoid these common anti-patterns:
- Leaving gather_facts: true enabled on every single play in a multi-tier playbook Repeats the expensive 500-node fact collection phase multiple times during a single playbook run.
- Setting fact_caching_timeout to 0 or infinite without TTL expiration Stale cached facts cause playbooks to evaluate outdated IP addresses and memory stats long after hardware changes.
- Failing to secure the Redis fact caching backend Redis stores complete system metadata and environment variables; expose it only on localhost or over TLS.