What is Ansible throttle?
The throttle keyword limits how many hosts can execute a specific task at the same time — even if forks or serial allows more.
This is essential when a task hits a shared resource (database, API, load balancer) that can't handle many simultaneous connections.
Basic Syntax
- name: Run database migration
ansible.builtin.command: /opt/app/migrate.sh
throttle: 1 # Only 1 host at a time
throttle vs serial vs forks
| Setting | Scope | What it controls |
|---|---|---|
forks | Global (ansible.cfg) | Max SSH connections Ansible opens |
serial | Play-level | How many hosts per batch |
throttle | Task-level | Max concurrent hosts for one task |
# forks=10 (in ansible.cfg)
- name: Rolling deployment
hosts: webservers
serial: 5 # Process 5 hosts per batch
tasks:
- name: Update application
ansible.builtin.apt:
name: myapp
state: latest
# Runs on 5 hosts at once (limited by serial)
- name: Run database migration
ansible.builtin.command: /opt/app/migrate.sh
throttle: 1
# Only 1 host at a time, even though serial=5
Practical Examples
API Rate Limiting
- name: Register with external API
ansible.builtin.uri:
url: "https://api.example.com/register"
method: POST
body:
hostname: "{{ inventory_hostname }}"
body_format: json
throttle: 2 # API allows max 2 concurrent requests
Database Operations
- name: Apply schema migration
ansible.builtin.command: python manage.py migrate
throttle: 1 # One migration at a time to avoid locks
run_once: true
Load Balancer Registration
- name: Register with load balancer
ansible.builtin.uri:
url: "https://lb.example.com/api/register"
method: POST
body:
server: "{{ inventory_hostname }}"
body_format: json
throttle: 3 # LB can handle 3 registrations at once
- name: Wait for health check
ansible.builtin.uri:
url: "http://{{ inventory_hostname }}:8080/health"
status_code: 200
retries: 10
delay: 5
throttle: 5
Certificate Renewal
- name: Renew SSL certificates
ansible.builtin.command: certbot renew
throttle: 1 # Avoid Let's Encrypt rate limits
Rolling Restart Without Downtime
- name: Rolling restart
hosts: app_servers
serial: "30%"
tasks:
- name: Stop application
ansible.builtin.service:
name: myapp
state: stopped
- name: Update code
ansible.builtin.git:
repo: https://github.com/myorg/myapp.git
dest: /opt/myapp
version: main
- name: Start application
ansible.builtin.service:
name: myapp
state: started
- name: Verify health
ansible.builtin.uri:
url: "http://localhost:8080/health"
status_code: 200
retries: 5
delay: 3
throttle: 1 # Verify one at a time
Key Rules
throttlecannot be higher thanserialorforks— it only reduces concurrency, never increases itthrottleis set per-task, not per-play- Value must be a positive integer
- Works with all strategies (
linear,free,host_pinned)
When to Use throttle
- API rate limits — external services cap concurrent requests
- Database migrations — prevent lock conflicts
- License servers — limited concurrent connections
- Shared storage — avoid I/O bottleneck
- Certificate authorities — rate-limited issuance
- Load balancer registration — gradual traffic shifting
Learn more about Ansible execution control in our performance optimization guide and 800+ tutorials.