Ansible Performance Tuning: Forks, Pipelining and Strategy Prompt
Diagnose slow Ansible runs and tune forks, pipelining, fact gathering, and strategy to cut wall-clock time without exhausting the control node or breaking become.
- Target user
- Ansible engineers whose playbooks are slow at scale across hundreds or thousands of hosts
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior automation engineer who makes slow Ansible runs fast without making them fragile. You know the real bottlenecks are usually SSH round-trips, unbounded fact gathering, low fork counts, and serialized task execution — and that cranking a single knob (like `forks: 500`) blindly can melt the control node or overwhelm a shared service. I will describe a slow playbook and its scale. Profile it, find where the time actually goes, and propose tuning with the trade-offs and risks of each change spelled out. Steps: 1. **Measure before tuning**: recommend enabling the `profile_tasks` and `timer` callbacks and (where relevant) `--start-at-task`, so we rank tasks by wall-clock time and separate per-task cost from per-host round-trips. Never tune from a guess. 2. **Reduce SSH overhead**: - `pipelining = True` (and the requirement that target sudoers does not force `requiretty`). - ControlPersist / `ssh_args` with `ControlMaster=auto` and a sane `ControlPersist` timeout. - Fact caching (`jsonfile`/`redis`) plus `gather_facts: false` where facts are unused, or `gather_subset` to collect only what is needed. 3. **Right-size parallelism**: choose `forks` from the control node's CPU/memory and the target services' capacity, not an arbitrary max; explain how `serial` interacts with forks for rolling changes and how forks stress shared dependencies (package repos, APIs). 4. **Pick a strategy deliberately**: compare `linear` (default) vs `free` vs `host_pinned`, and note when `free` helps (independent hosts) vs hurts (ordering/coordination matters). Mention mitogen as an option with its compatibility caveats. 5. **Cut redundant work**: loops that should be a single module call, `until` retries with long delays, unnecessary `delegate_to`/`run_once` patterns, and templating in hot paths. 6. **Re-measure and bound risk**: after each change, re-run with `profile_tasks` to confirm the gain is real, and confirm correctness (idempotence, become) did not regress. Fill in: - Playbook / roles and rough task count: [PASTE or DESCRIBE] - Host count and grouping: [e.g. 800 hosts across 6 groups] - Current runtime and where it feels slow: [DESCRIBE] - Control node specs + current ansible.cfg: [PASTE] Output format: a ranked list of bottlenecks (with the numbers that justify them), the specific `ansible.cfg` / playbook changes for each, the trade-off and risk of every change, and a before/after measurement plan. Do not recommend a fork count or `free` strategy without stating what it stresses. Flag any change that could overwhelm a shared service or the control node.
Run this prompt with AI
Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.
Why this prompt works
The default reaction to a slow playbook is to bump forks and hope, which either does nothing (the bottleneck was SSH round-trips) or takes down a shared package mirror the moment 500 hosts hit it at once. This prompt refuses to tune from a guess: it starts with profile_tasks and the timer callback so every recommendation is backed by where the wall-clock time actually goes, per-task cost separated from per-host overhead.
The highest-leverage fixes are usually not parallelism at all — they are killing SSH round-trips with pipelining and ControlPersist, and stopping needless fact gathering with gather_facts: false, gather_subset, or a fact cache. The prompt orders the tuning that way on purpose, and it ties pipelining to its real prerequisite (no requiretty in sudoers) so the speedup does not silently break become.
The strategy and forks guidance is deliberately hedged because these are the knobs that turn a fast run into an outage: free gives up cross-host ordering, and a big fork count stresses the control node and every downstream service simultaneously. By forcing each change to come with its trade-off and a re-measurement step, the prompt keeps you honest about whether you actually got faster — or just moved the failure somewhere less visible.
Related prompts
-
Ansible Strategy Plugin Selection & Tuning Prompt
Choose and tune the right execution strategy (linear, free, host_pinned) with forks and serial for a play, trading throughput against blast radius and ordering guarantees.
-
Ansible async and poll Orchestration Design Prompt
Design fire-and-forget and long-running Ansible tasks with async, poll, and async_status so jobs don't time out and results are collected reliably.
-
Ansible Cacheable set_fact Design Prompt
Design cacheable set_fact and registered facts with clean namespacing so reruns are fast and deterministic instead of recomputing everything every play.
-
Ansible Callback Plugin Authoring Prompt
Draft a custom callback plugin that hooks play/task events for profiling, structured logging, or notifications without changing any playbook.
More Ansible prompts & error guides
Browse every Ansible prompt and troubleshooting guide in one place.
Reading prompts? Get all 500 in one free PDF
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.