diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py
index 4320bf90b6..f84cd61dfb 100644
--- a/openstackclient/compute/v2/usage.py
+++ b/openstackclient/compute/v2/usage.py
@@ -15,8 +15,10 @@
 
 """Usage action implementations"""
 
+import collections
 import datetime
 
+from novaclient import api_versions
 from osc_lib.command import command
 from osc_lib import utils
 import six
@@ -24,6 +26,36 @@ import six
 from openstackclient.i18n import _
 
 
+def _get_usage_marker(usage):
+    marker = None
+    if hasattr(usage, 'server_usages') and usage.server_usages:
+        marker = usage.server_usages[-1]['instance_id']
+    return marker
+
+
+def _get_usage_list_marker(usage_list):
+    marker = None
+    if usage_list:
+        marker = _get_usage_marker(usage_list[-1])
+    return marker
+
+
+def _merge_usage(usage, next_usage):
+    usage.server_usages.extend(next_usage.server_usages)
+    usage.total_hours += next_usage.total_hours
+    usage.total_memory_mb_usage += next_usage.total_memory_mb_usage
+    usage.total_vcpus_usage += next_usage.total_vcpus_usage
+    usage.total_local_gb_usage += next_usage.total_local_gb_usage
+
+
+def _merge_usage_list(usages, next_usage_list):
+    for next_usage in next_usage_list:
+        if next_usage.tenant_id in usages:
+            _merge_usage(usages[next_usage.tenant_id], next_usage)
+        else:
+            usages[next_usage.tenant_id] = next_usage
+
+
 class ListUsage(command.Lister):
     _description = _("List resource usage per project")
 
@@ -83,7 +115,23 @@ class ListUsage(command.Lister):
         else:
             end = now + datetime.timedelta(days=1)
 
-        usage_list = compute_client.usage.list(start, end, detailed=True)
+        if compute_client.api_version < api_versions.APIVersion("2.40"):
+            usage_list = compute_client.usage.list(start, end, detailed=True)
+        else:
+            # If the number of instances used to calculate the usage is greater
+            # than CONF.api.max_limit, the usage will be split across multiple
+            # requests and the responses will need to be merged back together.
+            usages = collections.OrderedDict()
+            usage_list = compute_client.usage.list(start, end, detailed=True)
+            _merge_usage_list(usages, usage_list)
+            marker = _get_usage_list_marker(usage_list)
+            while marker:
+                next_usage_list = compute_client.usage.list(
+                    start, end, detailed=True, marker=marker)
+                marker = _get_usage_list_marker(next_usage_list)
+                if marker:
+                    _merge_usage_list(usages, next_usage_list)
+            usage_list = list(usages.values())
 
         # Cache the project list
         project_cache = {}
diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py
index 234bbd9b80..38f4ff67f1 100644
--- a/openstackclient/tests/unit/compute/v2/fakes.py
+++ b/openstackclient/tests/unit/compute/v2/fakes.py
@@ -1304,6 +1304,7 @@ class FakeUsage(object):
                     'local_gb': 1,
                     'memory_mb': 512,
                     'name': 'usage-name-' + uuid.uuid4().hex,
+                    'instance_id': uuid.uuid4().hex,
                     'state': 'active',
                     'uptime': 3600,
                     'vcpus': 1
diff --git a/openstackclient/tests/unit/compute/v2/test_usage.py b/openstackclient/tests/unit/compute/v2/test_usage.py
index a7aa1374e6..76dcc963fb 100644
--- a/openstackclient/tests/unit/compute/v2/test_usage.py
+++ b/openstackclient/tests/unit/compute/v2/test_usage.py
@@ -14,6 +14,7 @@
 import datetime
 
 import mock
+from novaclient import api_versions
 
 from openstackclient.compute.v2 import usage
 from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
@@ -104,6 +105,31 @@ class TestUsageList(TestUsage):
         self.assertEqual(self.columns, columns)
         self.assertEqual(tuple(self.data), tuple(data))
 
+    def test_usage_list_with_pagination(self):
+        arglist = []
+        verifylist = [
+            ('start', None),
+            ('end', None),
+        ]
+
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.40')
+        self.usage_mock.list.reset_mock()
+        self.usage_mock.list.side_effect = [self.usages, []]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.projects_mock.list.assert_called_with()
+        self.usage_mock.list.assert_has_calls([
+            mock.call(mock.ANY, mock.ANY, detailed=True),
+            mock.call(mock.ANY, mock.ANY, detailed=True,
+                      marker=self.usages[0]['server_usages'][0]['instance_id'])
+        ])
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+
 
 class TestUsageShow(TestUsage):