The hidden SSH setting that makes Ansible playbooks faster is ssh_args = -o ControlMaster=auto -o ControlPersist=60s in the [ssh_connection] section of ansible.cfg. This enables SSH connection multiplexing, so Ansible reuses a single TCP connection for multiple tasks instead of opening a new one each time, dramatically reducing overhead on playbooks with many tasks or hosts.
Why SSH Multiplexing Matters
Ansible runs each task by connecting to the target host over SSH, executing the module, and then closing the connection. Without multiplexing, every task incurs the full cost of a TCP handshake, SSH key exchange, and authentication. For a playbook with 50 tasks and 10 hosts, that’s 500 separate connection setups. With multiplexing, the first connection is reused for all subsequent tasks, cutting the overhead to just one connection per host. The speedup is most noticeable on high-latency networks or when running playbooks against many hosts, where connection setup can take several seconds each.
How ControlPersist Works
ControlPersist is an OpenSSH option that keeps a master connection alive in the background for a specified time after the last task. When Ansible needs to run another task on the same host, it sends the command through the existing master connection instead of creating a new one. The 60s value means the master connection stays open for 60 seconds after the last use, which is usually enough for a playbook run. If a playbook takes longer, you can increase it, but be aware that each idle master connection consumes a small amount of memory on the control node.
How to Enable It
To enable this setting, edit your ansible.cfg file (usually in the project root or /etc/ansible/ansible.cfg) and add or modify the [ssh_connection] section:
- Open
ansible.cfgin a text editor. - Add the following lines under a
[ssh_connection]section (create it if it doesn’t exist):
[ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=60s
If you already have ssh_args defined, append these options to the existing line. The ControlMaster=auto option tells SSH to use a master connection if one exists, or create one if not. ControlPersist=60s keeps it alive for 60 seconds after the last use.
When Not to Use It
There are situations where you should avoid or adjust this setting:
- Very short playbooks: If a playbook has only one or two tasks, the overhead of creating the master connection may outweigh the benefit. In such cases, the speedup is negligible.
- High concurrency with many hosts: Each master connection uses a small amount of memory and file descriptors. With hundreds of hosts, you might hit system limits. Increase
ControlPersisttime to reduce the number of reconnections, but monitor resource usage. - SSH options conflicts: If you use other SSH options like
ControlPathorProxyCommand, ensure they are compatible. For example, a customControlPathmust be unique per host to avoid collisions. - Network restrictions: Some firewalls or security policies may block long-lived SSH connections. If you see connection timeouts, try reducing
ControlPersistto 10s or disabling it.
Common Problems and Misconceptions
A frequent mistake is setting ControlPersist to a very high value like 3600s thinking it will help, but it only keeps idle connections open longer, which can exhaust resources if you run many playbooks. Another misconception is that this setting speeds up the actual module execution—it doesn’t; it only removes connection setup overhead. If your playbook is slow because of module execution, look elsewhere (e.g., facts gathering, package manager slowness). Also, note that this setting works with the default OpenSSH connection plugin. If you use a different connection plugin (e.g., paramiko), you need to adjust that plugin’s settings instead.
Comparison with Other Speed Options
Multiplexing is just one of several ways to speed up Ansible. Here’s how it compares:
- Forks: Increasing
forks(default 5) runs tasks on multiple hosts in parallel. This helps when you have many hosts, but it doesn’t reduce per-host connection overhead. Multiplexing complements forks by making each host’s connections faster. - SSH pipelining: Setting
pipelining = Truereduces the number of SSH operations per task by sending the module over the same connection. It works well with multiplexing but requires thatrequirettyis disabled on target hosts. - Fact caching: If you gather facts every run, caching them (e.g., with Redis or JSON files) saves time. This is independent of SSH settings.
Safety and Best Practices
There are no inherent security risks in enabling ControlPersist, but keep these points in mind:
- The master connection is encrypted and authenticated like any SSH connection. It does not bypass security.
- If you use agent forwarding, the master connection may keep your agent socket open for longer, which could be a security concern if you don’t want to expose it. Consider using
ControlPersistwithForwardAgent=nounless you explicitly need forwarding. - Always test the setting on a small subset of hosts before rolling it out to your entire inventory. Monitor for any unexpected connection failures.
- If you use a shared control path directory, ensure it is writable only by your user to prevent other users from hijacking connections.
Frequently Asked Questions
Does this work with Ansible Tower or AWX?
Yes, because it’s a configuration in ansible.cfg. You can set it in the project’s ansible.cfg or in the Tower/AWX job template’s extra variables by defining ansible_ssh_common_args as an inventory variable. For example, set ansible_ssh_common_args: '-o ControlMaster=auto -o ControlPersist=60s' in your inventory.
What if I already have ssh_args set?
You can combine them. Just add the ControlMaster and ControlPersist options to your existing ssh_args line, separated by spaces. For example: ssh_args = -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s.
Why do I not see a speedup on my localhost playbook?
For localhost, Ansible uses the local connection plugin by default, not SSH. The setting only affects SSH connections. If you force SSH to localhost, you might see a small improvement, but it’s usually negligible.
Can I set ControlPersist to 0 to disable it?
Yes, setting ControlPersist=0 disables the persistent connection, meaning the master connection closes immediately after the playbook finishes. This is useful if you want to avoid leaving idle connections, but you lose the benefit of reuse across tasks (though within a single playbook, the connection is still reused until the end).
Does this work with Windows hosts?
Yes, as long as you are connecting to Windows via SSH (e.g., with Win32-OpenSSH). The SSH connection plugin handles it the same way. The speedup applies similarly.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Increase Internal Memory Xiaomi Phones: How-To
- Nvidia Display Settings Are Not Available: Fixes
- Gmod Keeps Crashing? Fixes That Actually Work
- Net Code Analysis Workflow: A Reliable Setup Guide
- Satellite Internet Down: What to Do Now
- Audit an AI Agent’s Privacy Before Connecting Accounts