diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index 23230f98711dc25dd7d470b0068a071985f3339f..aa4938b08045d43528fa468a8c3477c86e327766 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -82,6 +82,8 @@ external_ntp_servers:
 database_address: "{{ kolla_internal_fqdn }}"
 database_user: "root"
 database_port: "3306"
+database_connection_recycle_time: 10
+database_max_pool_size: 1
 
 
 ####################
diff --git a/ansible/roles/aodh/templates/aodh.conf.j2 b/ansible/roles/aodh/templates/aodh.conf.j2
index fe826d6edc0dae93a52d4fc72bc5b4a5682c0c43..6745323ca695fbb5d75a6ed328409b4180abd71c 100644
--- a/ansible/roles/aodh/templates/aodh.conf.j2
+++ b/ansible/roles/aodh/templates/aodh.conf.j2
@@ -12,6 +12,8 @@ host = {{ api_interface_address }}
 
 [database]
 connection = mysql+pymysql://{{ aodh_database_user }}:{{ aodh_database_password }}@{{ aodh_database_address }}/{{ aodh_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 
 [keystone_authtoken]
 memcache_security_strategy = ENCRYPT
diff --git a/ansible/roles/blazar/templates/blazar.conf.j2 b/ansible/roles/blazar/templates/blazar.conf.j2
index 275e5d4dbc7ce2e77cdf7401ea05ee75a913147a..734b9c326d5054baecfaf4b22f00c3c0f4c4ec34 100644
--- a/ansible/roles/blazar/templates/blazar.conf.j2
+++ b/ansible/roles/blazar/templates/blazar.conf.j2
@@ -40,6 +40,8 @@ memcached_servers = {% for host in groups['memcached'] %}{{ 'api' | kolla_addres
 
 [database]
 connection = mysql+pymysql://{{ blazar_database_user }}:{{ blazar_database_password }}@{{ blazar_database_address }}/{{ blazar_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [physical:host]
diff --git a/ansible/roles/cinder/templates/cinder.conf.j2 b/ansible/roles/cinder/templates/cinder.conf.j2
index 5fcae8daa00997c323927f732d2f84630ec5d0ad..2ab967de6f34842723081e674b6c8b41527bd420 100644
--- a/ansible/roles/cinder/templates/cinder.conf.j2
+++ b/ansible/roles/cinder/templates/cinder.conf.j2
@@ -91,6 +91,8 @@ cafile = {{ openstack_cacert }}
 
 [database]
 connection = mysql+pymysql://{{ cinder_database_user }}:{{ cinder_database_password }}@{{ cinder_database_address }}/{{ cinder_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2 b/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
index b450c7e46ff20a7041628af9f5bd9ddb411434c8..cc1ebaf5aa531165275deecae47ffe7d26b937bb 100644
--- a/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
+++ b/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
@@ -12,6 +12,8 @@ transport_url = {{ rpc_transport_url }}
 
 [database]
 connection = mysql+pymysql://{{ cloudkitty_database_user }}:{{ cloudkitty_database_password }}@{{ cloudkitty_database_address }}/{{ cloudkitty_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/cyborg/templates/cyborg.conf.j2 b/ansible/roles/cyborg/templates/cyborg.conf.j2
index 0330edf19720fc0df83636bb5c221e8b59f031c3..61a5673b1df99a87bde99d0c03f89c284f53b556 100644
--- a/ansible/roles/cyborg/templates/cyborg.conf.j2
+++ b/ansible/roles/cyborg/templates/cyborg.conf.j2
@@ -12,6 +12,8 @@ host = {{ api_interface_address }}
 
 [database]
 connection = mysql+pymysql://{{ cyborg_database_user }}:{{ cyborg_database_password }}@{{ cyborg_database_address }}/{{ cyborg_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 
 [keystone_authtoken]
 memcache_security_strategy = ENCRYPT
diff --git a/ansible/roles/freezer/templates/freezer.conf.j2 b/ansible/roles/freezer/templates/freezer.conf.j2
index 57b28254273955e2148e2498f2d32d4bdf493285..025d56bc4ca490d5d544869df3a2a145bf41db43 100644
--- a/ansible/roles/freezer/templates/freezer.conf.j2
+++ b/ansible/roles/freezer/templates/freezer.conf.j2
@@ -55,6 +55,8 @@ driver = sqlalchemy
 
 [database]
 connection = mysql+pymysql://{{ freezer_database_user }}:{{ freezer_database_password }}@{{ freezer_database_address }}/{{ freezer_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 {% endif %}
 
diff --git a/ansible/roles/glance/templates/glance-api.conf.j2 b/ansible/roles/glance/templates/glance-api.conf.j2
index 76968ec7ed01f2dbc03158c767a09e332cb2e6dc..5ad3a5c00cf26324550315449ab523d17c63c7b4 100644
--- a/ansible/roles/glance/templates/glance-api.conf.j2
+++ b/ansible/roles/glance/templates/glance-api.conf.j2
@@ -36,6 +36,8 @@ image_cache_dir = /var/lib/glance/image-cache
 
 [database]
 connection = mysql+pymysql://{{ glance_database_user }}:{{ glance_database_password }}@{{ glance_database_address }}/{{ glance_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/gnocchi/templates/gnocchi.conf.j2 b/ansible/roles/gnocchi/templates/gnocchi.conf.j2
index 79ba8b504b6d117f8e2d32648261c24e32f3040d..7d4d5122cad3eb48a6ac474a73eb8f5987e383fd 100644
--- a/ansible/roles/gnocchi/templates/gnocchi.conf.j2
+++ b/ansible/roles/gnocchi/templates/gnocchi.conf.j2
@@ -23,8 +23,9 @@ enable_proxy_headers_parsing = True
 
 [database]
 connection = mysql+pymysql://{{ gnocchi_database_user }}:{{ gnocchi_database_password }}@{{ gnocchi_database_address }}/{{ gnocchi_database_name }}
-max_pool_size = 50
+connection_recycle_time = {{ database_connection_recycle_time }}
 max_overflow = 1000
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 {% if enable_gnocchi_statsd | bool %}
diff --git a/ansible/roles/heat/templates/heat.conf.j2 b/ansible/roles/heat/templates/heat.conf.j2
index 4ab451247b1c390c4f14a28d19307102f981f39a..c7245e0a26c80fe9fbc33e37e138b59f9c422385 100644
--- a/ansible/roles/heat/templates/heat.conf.j2
+++ b/ansible/roles/heat/templates/heat.conf.j2
@@ -38,6 +38,8 @@ workers = {{ openstack_service_workers }}
 
 [database]
 connection = mysql+pymysql://{{ heat_database_user }}:{{ heat_database_password }}@{{ heat_database_address }}/{{ heat_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/ironic/templates/ironic-inspector.conf.j2 b/ansible/roles/ironic/templates/ironic-inspector.conf.j2
index 4019e4b77c5b063c0668b50e890b4462862a0eb9..3a3d4a8933898754e5f140deff64d17face946e9 100644
--- a/ansible/roles/ironic/templates/ironic-inspector.conf.j2
+++ b/ansible/roles/ironic/templates/ironic-inspector.conf.j2
@@ -52,6 +52,8 @@ policy_file = {{ ironic_policy_file }}
 
 [database]
 connection = mysql+pymysql://{{ ironic_inspector_database_user }}:{{ ironic_inspector_database_password }}@{{ ironic_inspector_database_address }}/{{ ironic_inspector_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 
 [processing]
 ramdisk_logs_dir = /var/log/kolla/ironic-inspector
diff --git a/ansible/roles/ironic/templates/ironic.conf.j2 b/ansible/roles/ironic/templates/ironic.conf.j2
index 7e79cd278974a8d9c1dfaeec8db428570044be61..ef337041b0afb81dcc42dce7287c27af9221cb93 100644
--- a/ansible/roles/ironic/templates/ironic.conf.j2
+++ b/ansible/roles/ironic/templates/ironic.conf.j2
@@ -49,6 +49,8 @@ automated_clean=false
 
 [database]
 connection = mysql+pymysql://{{ ironic_database_user }}:{{ ironic_database_password }}@{{ ironic_database_address }}/{{ ironic_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 {% if enable_keystone | bool %}
diff --git a/ansible/roles/karbor/templates/karbor.conf.j2 b/ansible/roles/karbor/templates/karbor.conf.j2
index 643b9da3c09a34018ef340823df77a07139cf8b9..d31985b12c7815302c882af38528a6da38444bc8 100644
--- a/ansible/roles/karbor/templates/karbor.conf.j2
+++ b/ansible/roles/karbor/templates/karbor.conf.j2
@@ -11,6 +11,8 @@ osapi_karbor_workers = {{ openstack_service_workers }}
 
 [database]
 connection = mysql+pymysql://{{ karbor_database_user }}:{{ karbor_database_password }}@{{ karbor_database_address }}/{{ karbor_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [trustee]
diff --git a/ansible/roles/keystone/templates/keystone.conf.j2 b/ansible/roles/keystone/templates/keystone.conf.j2
index 1e028935b495d0acef626f40a56837a1cdf50f4f..06d57eb3b2f6312f84c0224758fe7d55ea7c56ba 100644
--- a/ansible/roles/keystone/templates/keystone.conf.j2
+++ b/ansible/roles/keystone/templates/keystone.conf.j2
@@ -17,6 +17,8 @@ policy_file = {{ keystone_policy_file }}
 
 [database]
 connection = mysql+pymysql://{{ keystone_database_user }}:{{ keystone_database_password }}@{{ keystone_database_address }}/{{ keystone_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 {% if keystone_domain_directory.stat.exists %}
diff --git a/ansible/roles/magnum/templates/magnum.conf.j2 b/ansible/roles/magnum/templates/magnum.conf.j2
index 36fffc2b3694dfa5c29e3f72f07fce93e5ccf894..c0cb531aa9c86cea563295e027ca1af79a1629f8 100644
--- a/ansible/roles/magnum/templates/magnum.conf.j2
+++ b/ansible/roles/magnum/templates/magnum.conf.j2
@@ -16,6 +16,8 @@ workers = {{ openstack_service_workers }}
 
 [database]
 connection = mysql+pymysql://{{ magnum_database_user }}:{{ magnum_database_password }}@{{ magnum_database_address }}/{{ magnum_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 {% if enable_cinder | bool %}
diff --git a/ansible/roles/manila/templates/manila.conf.j2 b/ansible/roles/manila/templates/manila.conf.j2
index c316ccfcca3d99bb8a54f07344a9ed49b634d20d..171033f732accc77accbf3b008543aa2c4903460 100644
--- a/ansible/roles/manila/templates/manila.conf.j2
+++ b/ansible/roles/manila/templates/manila.conf.j2
@@ -26,6 +26,8 @@ lock_path = /var/lib/manila/tmp
 
 [database]
 connection = mysql+pymysql://{{ manila_database_user }}:{{ manila_database_password }}@{{ manila_database_address }}/{{ manila_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/masakari/templates/masakari.conf.j2 b/ansible/roles/masakari/templates/masakari.conf.j2
index 92dc06b1edef95cdf8c639ec98e3dcdff0b8594d..5a0bab0fc945759ac9444af7bd0d8fdae13763d0 100644
--- a/ansible/roles/masakari/templates/masakari.conf.j2
+++ b/ansible/roles/masakari/templates/masakari.conf.j2
@@ -16,6 +16,8 @@ nova_ca_certificates_file = {{ openstack_cacert }}
 
 [database]
 connection = mysql+pymysql://{{ masakari_database_user }}:{{ masakari_database_password }}@{{ masakari_database_address }}/{{ masakari_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/mistral/templates/mistral.conf.j2 b/ansible/roles/mistral/templates/mistral.conf.j2
index 2d0cd3b31d37fbb589f2111abc87b9e806ba63a0..de3540ad5c393bd57d4631a0303013781353a63e 100644
--- a/ansible/roles/mistral/templates/mistral.conf.j2
+++ b/ansible/roles/mistral/templates/mistral.conf.j2
@@ -34,6 +34,8 @@ host = {{ api_interface_address }}
 
 [database]
 connection = mysql+pymysql://{{ mistral_database_user }}:{{ mistral_database_password }}@{{ mistral_database_address }}/{{ mistral_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/monasca/templates/monasca-api/api.conf.j2 b/ansible/roles/monasca/templates/monasca-api/api.conf.j2
index 581cbf7d8e0e291839c431282d95f7dc137a8224..9233c7ad3319f1bba59fc05ce65bc2a4c721a6e0 100644
--- a/ansible/roles/monasca/templates/monasca-api/api.conf.j2
+++ b/ansible/roles/monasca/templates/monasca-api/api.conf.j2
@@ -8,6 +8,8 @@ enable_logs_api = True
 [database]
 database = {{ monasca_database_name }}
 connection = mysql+pymysql://{{ monasca_database_user }}:{{ monasca_database_password }}@{{ monasca_database_address | put_address_in_context('url') }}:{{ monasca_database_port }}/{{ monasca_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 
 [influxdb]
 database_name = {{ monasca_influxdb_name }}
diff --git a/ansible/roles/murano/templates/murano.conf.j2 b/ansible/roles/murano/templates/murano.conf.j2
index 2e717bcc75f89dbeea8274ee0e892ec6bacb039c..ce67b458f7e043806622fa03a603261d6fd8416a 100644
--- a/ansible/roles/murano/templates/murano.conf.j2
+++ b/ansible/roles/murano/templates/murano.conf.j2
@@ -16,6 +16,8 @@ agent_timeout = {{ murano_agent_timeout }}
 
 [database]
 connection = mysql+pymysql://{{ murano_database_user }}:{{ murano_database_password }}@{{ murano_database_address }}/{{ murano_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/neutron/templates/neutron.conf.j2 b/ansible/roles/neutron/templates/neutron.conf.j2
index 115169ac534c617ad42d83e748ffb721ea2cbf5e..4b8510dea5a77feba7f29f5bc199b870ef5c7021 100644
--- a/ansible/roles/neutron/templates/neutron.conf.j2
+++ b/ansible/roles/neutron/templates/neutron.conf.j2
@@ -97,6 +97,8 @@ root_helper = sudo neutron-rootwrap /etc/neutron/rootwrap.conf
 
 [database]
 connection = mysql+pymysql://{{ neutron_database_user }}:{{ neutron_database_password }}@{{ neutron_database_address }}/{{ neutron_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/nova-cell/templates/nova.conf.j2 b/ansible/roles/nova-cell/templates/nova.conf.j2
index e97e41900de1b8e0f6441ba7502f650419a38d49..d54ab23be5563a9b59e01700032684df1b5de20d 100644
--- a/ansible/roles/nova-cell/templates/nova.conf.j2
+++ b/ansible/roles/nova-cell/templates/nova.conf.j2
@@ -136,13 +136,16 @@ valid_interfaces = internal
 {% if not service_name.startswith('nova-compute') %}
 [database]
 connection = mysql+pymysql://{{ nova_cell_database_user }}:{{ nova_cell_database_password }}@{{ nova_cell_database_address | put_address_in_context('url') }}:{{ nova_cell_database_port }}/{{ nova_cell_database_name }}
-max_pool_size = 50
+connection_recycle_time = {{ database_connection_recycle_time }}
 max_overflow = 1000
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 {% if service_name == 'nova-cell-bootstrap' or (service_name == 'nova-conductor' and nova_cell_conductor_has_api_database | bool) %}
 [api_database]
 connection = mysql+pymysql://{{ nova_api_database_user }}:{{ nova_api_database_password }}@{{ nova_api_database_address }}/{{ nova_api_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 {% endif %}
 {% endif %}
diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2
index 2c51f86a370322d501b97421ab0d49863d86be44..5a7f88dbbda2cc10ae9c90516cf21f6ae997181a 100644
--- a/ansible/roles/nova/templates/nova.conf.j2
+++ b/ansible/roles/nova/templates/nova.conf.j2
@@ -88,12 +88,15 @@ cafile = {{ openstack_cacert }}
 
 [database]
 connection = mysql+pymysql://{{ nova_cell0_database_user }}:{{ nova_cell0_database_password }}@{{ nova_cell0_database_address }}/{{ nova_cell0_database_name }}
-max_pool_size = 50
+connection_recycle_time = {{ database_connection_recycle_time }}
 max_overflow = 1000
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [api_database]
 connection = mysql+pymysql://{{ nova_api_database_user }}:{{ nova_api_database_password }}@{{ nova_api_database_address }}/{{ nova_api_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [cache]
diff --git a/ansible/roles/octavia/templates/octavia.conf.j2 b/ansible/roles/octavia/templates/octavia.conf.j2
index a9e2406d1fe08e0957cecd12a44e9ec517a74bc7..33289a9a91763b9d3f193ab0819b51e5e8c18ab9 100644
--- a/ansible/roles/octavia/templates/octavia.conf.j2
+++ b/ansible/roles/octavia/templates/octavia.conf.j2
@@ -25,6 +25,8 @@ client_cert = /etc/octavia/certs/client.cert-and-key.pem
 
 [database]
 connection = mysql+pymysql://{{ octavia_database_user }}:{{ octavia_database_password }}@{{ octavia_database_address }}/{{ octavia_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [service_auth]
diff --git a/ansible/roles/panko/templates/panko.conf.j2 b/ansible/roles/panko/templates/panko.conf.j2
index 9f54d9c91bc44d60ab8f0877bfcddc8bb23a1167..093e24b1ba8e803a8519b21dcd3b93da5327df09 100644
--- a/ansible/roles/panko/templates/panko.conf.j2
+++ b/ansible/roles/panko/templates/panko.conf.j2
@@ -9,6 +9,8 @@ log_file = /var/log/kolla/panko/panko-api.log
 
 [database]
 connection = mysql+pymysql://{{ panko_database_user }}:{{ panko_database_password }}@{{ panko_database_mysql_address }}/{{ panko_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 metering_connection = mysql+pymysql://{{ panko_database_user }}:{{ panko_database_password }}@{{ panko_database_mysql_address }}/{{ panko_database_name }}
 
 [keystone_authtoken]
diff --git a/ansible/roles/placement/templates/placement.conf.j2 b/ansible/roles/placement/templates/placement.conf.j2
index 3f4947d2872cb1e5548ebfd72d6fffc2b7f6baa8..b8c64321a7d672d88a741b49fe0c0558571b2f87 100644
--- a/ansible/roles/placement/templates/placement.conf.j2
+++ b/ansible/roles/placement/templates/placement.conf.j2
@@ -23,8 +23,9 @@ lock_path = /var/lib/placement/tmp
 
 [placement_database]
 connection = mysql+pymysql://{{ placement_database_user }}:{{ placement_database_password }}@{{ placement_database_address }}/{{ placement_database_name }}
-max_pool_size = 50
+connection_recycle_time = {{ database_connection_recycle_time }}
 max_overflow = 1000
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [cache]
diff --git a/ansible/roles/qinling/templates/qinling.conf.j2 b/ansible/roles/qinling/templates/qinling.conf.j2
index 2166c73d35a558475873f01437a3c4e13e86b0c1..030edd9354574377630206695fe2b2d2fd07542f 100644
--- a/ansible/roles/qinling/templates/qinling.conf.j2
+++ b/ansible/roles/qinling/templates/qinling.conf.j2
@@ -16,6 +16,8 @@ host = {{ api_interface_address }}
 
 [database]
 connection = mysql+pymysql://{{ qinling_database_user }}:{{ qinling_database_password }}@{{ qinling_database_address }}/{{ qinling_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/rally/templates/rally.conf.j2 b/ansible/roles/rally/templates/rally.conf.j2
index 7a43d10406df97e2935e10694e98310976d3d06e..a1a0a7ea1f5bb2bc66e2e499212a7f83e1e0b3c9 100644
--- a/ansible/roles/rally/templates/rally.conf.j2
+++ b/ansible/roles/rally/templates/rally.conf.j2
@@ -6,6 +6,8 @@ log_dir = /var/log/kolla/rally/
 
 [database]
 connection = mysql+pymysql://{{ rally_database_user }}:{{ rally_database_password }}@{{ rally_database_address }}/{{ rally_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 {% if rally_policy_file is defined %}
diff --git a/ansible/roles/sahara/templates/sahara.conf.j2 b/ansible/roles/sahara/templates/sahara.conf.j2
index 616a39474c0a0c894605f4f85990124ce344eb4a..9b4c15661fcd61307b30f09e4c5c87c24ce52524 100644
--- a/ansible/roles/sahara/templates/sahara.conf.j2
+++ b/ansible/roles/sahara/templates/sahara.conf.j2
@@ -12,6 +12,8 @@ use_rootwrap = True
 
 [database]
 connection = mysql+pymysql://{{ sahara_database_user }}:{{ sahara_database_password }}@{{ sahara_database_address }}/{{ sahara_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 
 [keystone_authtoken]
 auth_url = {{ keystone_admin_url }}
diff --git a/ansible/roles/senlin/templates/senlin.conf.j2 b/ansible/roles/senlin/templates/senlin.conf.j2
index 3fc59d3fb04f0637080b8853cdb11fd0dadd6b39..2764bf07d31934a4165d1fdf0287a9436b52a3c0 100644
--- a/ansible/roles/senlin/templates/senlin.conf.j2
+++ b/ansible/roles/senlin/templates/senlin.conf.j2
@@ -27,6 +27,8 @@ workers = {{ openstack_service_workers }}
 
 [database]
 connection = mysql+pymysql://{{ senlin_database_user }}:{{ senlin_database_password }}@{{ senlin_database_address }}/{{ senlin_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 {% if service_name == 'senlin-engine' %}
diff --git a/ansible/roles/solum/templates/solum.conf.j2 b/ansible/roles/solum/templates/solum.conf.j2
index 33dda508dc59664202ffbdcb4fc0f267d3a1ad2f..02d46ecc9e684c3d80dbdd7f43df9c3055b5190b 100644
--- a/ansible/roles/solum/templates/solum.conf.j2
+++ b/ansible/roles/solum/templates/solum.conf.j2
@@ -40,6 +40,8 @@ host = {{ ansible_hostname }}_{{ item }}
 
 [database]
 connection = mysql+pymysql://{{ solum_database_user }}:{{ solum_database_password }}@{{ solum_database_address }}/{{ solum_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/tacker/templates/tacker.conf.j2 b/ansible/roles/tacker/templates/tacker.conf.j2
index 10c4c174354a3f37d28b2c91aed046f4a9943832..c76b83bd201009c8d4484d151413df508a467867 100644
--- a/ansible/roles/tacker/templates/tacker.conf.j2
+++ b/ansible/roles/tacker/templates/tacker.conf.j2
@@ -27,6 +27,8 @@ alarm_monitor_driver = ceilometer
 
 [database]
 connection = mysql+pymysql://{{ tacker_database_user }}:{{ tacker_database_password }}@{{ tacker_database_address }}/{{ tacker_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/trove/templates/trove-conductor.conf.j2 b/ansible/roles/trove/templates/trove-conductor.conf.j2
index 63bcbff06d814b00d6290c9d537a05cdb2d0304c..42247a3b03d112ab23fb4d4447339eeac435d99c 100644
--- a/ansible/roles/trove/templates/trove-conductor.conf.j2
+++ b/ansible/roles/trove/templates/trove-conductor.conf.j2
@@ -27,6 +27,8 @@ driver = noop
 
 [database]
 connection = mysql+pymysql://{{ trove_database_user }}:{{ trove_database_password }}@{{ trove_database_address }}/{{ trove_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 {% if enable_osprofiler | bool %}
diff --git a/ansible/roles/trove/templates/trove-taskmanager.conf.j2 b/ansible/roles/trove/templates/trove-taskmanager.conf.j2
index 5c64fb4405f775b2c4679a60d9a0ec1cc990b27b..9c4d4ac49824eb957ec6fb88e0876663073b6908 100644
--- a/ansible/roles/trove/templates/trove-taskmanager.conf.j2
+++ b/ansible/roles/trove/templates/trove-taskmanager.conf.j2
@@ -35,6 +35,8 @@ username = {{ trove_keystone_user }}
 
 [database]
 connection = mysql+pymysql://{{ trove_database_user }}:{{ trove_database_password }}@{{ trove_database_address }}/{{ trove_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [oslo_messaging_notifications]
diff --git a/ansible/roles/trove/templates/trove.conf.j2 b/ansible/roles/trove/templates/trove.conf.j2
index 95b0fde5116319aff3a8d2688a4287a7d12b9b1c..3bb9199aa6b357661fa33eb02d1a7e81c9553809 100644
--- a/ansible/roles/trove/templates/trove.conf.j2
+++ b/ansible/roles/trove/templates/trove.conf.j2
@@ -32,6 +32,8 @@ username = {{ trove_keystone_user }}
 
 [database]
 connection = mysql+pymysql://{{ trove_database_user }}:{{ trove_database_password }}@{{ trove_database_address }}/{{ trove_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 
 [keystone_authtoken]
 www_authenticate_uri = {{ keystone_internal_url }}
diff --git a/ansible/roles/vitrage/templates/vitrage.conf.j2 b/ansible/roles/vitrage/templates/vitrage.conf.j2
index fe25b29bd843169ba8f676e4579b236f5da1a2f4..12cf804956574433f788719ba97840d4db479ce5 100644
--- a/ansible/roles/vitrage/templates/vitrage.conf.j2
+++ b/ansible/roles/vitrage/templates/vitrage.conf.j2
@@ -20,6 +20,8 @@ workers = {{ openstack_service_workers }}
 
 [database]
 connection = mysql+pymysql://{{ vitrage_database_user }}:{{ vitrage_database_password }}@{{ vitrage_database_address }}/{{ vitrage_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 
 {% if vitrage_datasources %}
 [datasources]
diff --git a/ansible/roles/watcher/templates/watcher.conf.j2 b/ansible/roles/watcher/templates/watcher.conf.j2
index fc320f6df1d28fc5226a982459ea2e31d510ae5a..33178edd47ac567042809c5d5df21e2d4cdf8aa7 100644
--- a/ansible/roles/watcher/templates/watcher.conf.j2
+++ b/ansible/roles/watcher/templates/watcher.conf.j2
@@ -14,6 +14,8 @@ workers = {{ openstack_service_workers }}
 
 [database]
 connection = mysql+pymysql://{{ watcher_database_user }}:{{ watcher_database_password }}@{{ watcher_database_address }}/{{ watcher_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 [keystone_authtoken]
diff --git a/ansible/roles/zun/templates/zun.conf.j2 b/ansible/roles/zun/templates/zun.conf.j2
index 8ff658d1321b471e3dc7a4f246b5b3de4ccbf2f9..a3358c51c59148b55e6783cf45d7b53fe6dfae5b 100644
--- a/ansible/roles/zun/templates/zun.conf.j2
+++ b/ansible/roles/zun/templates/zun.conf.j2
@@ -23,6 +23,8 @@ workers = {{ openstack_service_workers }}
 
 [database]
 connection = mysql+pymysql://{{ zun_database_user }}:{{ zun_database_password }}@{{ zun_database_address }}/{{ zun_database_name }}
+connection_recycle_time = {{ database_connection_recycle_time }}
+max_pool_size = {{ database_max_pool_size }}
 max_retries = -1
 
 # NOTE(yoctozepto): despite what the docs say, both keystone_auth and
diff --git a/releasenotes/notes/reduce-db-connection-pooling-b44da77eaa390f22.yaml b/releasenotes/notes/reduce-db-connection-pooling-b44da77eaa390f22.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e0345ba41a528d61717117500f7d6a4a4b1dffd3
--- /dev/null
+++ b/releasenotes/notes/reduce-db-connection-pooling-b44da77eaa390f22.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Reduce the use of SQLAlchemy connection pooling, to improve service
+    reliability during a failover of the controller with the internal VIP.
+    `LP#1896635 <https://bugs.launchpad.net/kolla-ansible/+bug/1896635>`__