async and poll
Every task in this course so far has run and blocked until it finished, before the next one started. That’s fine for anything quick — but a genuinely long-running task, a large download or a lengthy build process, risks running past normal connection timeouts if Ansible just sits there waiting the whole time. This chapter covers the alternative.
The Problem: Tasks That Genuinely Take A While
By default, Ansible waits for a task to fully complete before moving on, holding the connection open the entire time. A task that takes considerably longer than usual can hit connection timeout limits well before it’s actually done — failing not because anything went wrong, but purely because the wait itself took too long.
async: Setting A Maximum Runtime
- name: Run a long build process
ansible.builtin.command: /usr/local/bin/build-something.sh
async: 600
poll: 10async: 600 gives the task up to 600 seconds to complete, decoupling it from the normal blocking wait — Ansible checks in periodically instead of holding one continuous connection open the whole time.
poll: How Often To Check Back
poll: 10 (the default) means Ansible checks the task’s progress every 10 seconds until it finishes or the async timeout is reached. From the playbook’s own perspective, this still behaves like an ordinary blocking task — it just polls periodically instead of waiting on one unbroken connection, which is what actually avoids the timeout problem.
Fire And Forget: poll: 0
- name: Start a long job and don't wait at all
ansible.builtin.command: /usr/local/bin/long-running-task.sh
async: 3600
poll: 0poll: 0 is genuinely different — Ansible starts the task and moves on immediately, without checking on it again during this run at all. The task keeps running on the remote host, entirely independent of the playbook that started it, which by this point has already moved on to whatever comes next.
Best Practices
- Use
async/poll(with a nonzeropoll) for any task expected to run considerably longer than usual — this is the direct fix for a connection timeout that has nothing to do with anything actually being wrong. - Reserve
poll: 0for genuinely fire-and-forget work — something you don’t need this particular playbook run to wait on at all. - Set
asyncto a realistic maximum, not an arbitrarily large number “just in case” — it’s a genuine timeout, not a formality.