diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py
index 307c238afe..69fa04e8ba 100644
--- a/openstackclient/compute/v2/usage.py
+++ b/openstackclient/compute/v2/usage.py
@@ -17,7 +17,9 @@
 
 import collections
 import datetime
+import functools
 
+from cliff import columns as cliff_columns
 from novaclient import api_versions
 from osc_lib.command import command
 from osc_lib import utils
@@ -25,6 +27,57 @@ from osc_lib import utils
 from openstackclient.i18n import _
 
 
+# TODO(stephenfin): This exists in a couple of places and should be moved to a
+# common module
+class ProjectColumn(cliff_columns.FormattableColumn):
+    """Formattable column for project column.
+
+    Unlike the parent FormattableColumn class, the initializer of the class
+    takes project_cache as the second argument.
+    ``osc_lib.utils.get_item_properties`` instantiates ``FormattableColumn``
+    objects with a single parameter, the column value, so you need to pass a
+    partially initialized class like ``functools.partial(ProjectColumn,
+    project_cache)`` to use this.
+    """
+
+    def __init__(self, value, project_cache=None):
+        super().__init__(value)
+        self.project_cache = project_cache or {}
+
+    def human_readable(self):
+        project = self._value
+        if not project:
+            return ''
+
+        if project in self.project_cache.keys():
+            return self.project_cache[project].name
+
+        return project
+
+
+class CountColumn(cliff_columns.FormattableColumn):
+
+    def human_readable(self):
+        return len(self._value)
+
+
+class FloatColumn(cliff_columns.FormattableColumn):
+
+    def human_readable(self):
+        return float("%.2f" % self._value)
+
+
+def _formatters(project_cache):
+    return {
+        'tenant_id': functools.partial(
+            ProjectColumn, project_cache=project_cache),
+        'server_usages': CountColumn,
+        'total_memory_mb_usage': FloatColumn,
+        'total_vcpus_usage': FloatColumn,
+        'total_local_gb_usage': FloatColumn,
+    }
+
+
 def _get_usage_marker(usage):
     marker = None
     if hasattr(usage, 'server_usages') and usage.server_usages:
@@ -147,17 +200,15 @@ class ListUsage(command.Lister):
                 "end": end.strftime(dateformat),
             })
 
-        return (column_headers,
-                (utils.get_item_properties(
+        return (
+            column_headers,
+            (
+                utils.get_item_properties(
                     s, columns,
-                    formatters={
-                        'tenant_id': _format_project,
-                        'server_usages': lambda x: len(x),
-                        'total_memory_mb_usage': lambda x: float("%.2f" % x),
-                        'total_vcpus_usage': lambda x: float("%.2f" % x),
-                        'total_local_gb_usage': lambda x: float("%.2f" % x),
-                    },
-                ) for s in usage_list))
+                    formatters=_formatters(project_cache),
+                ) for s in usage_list
+            ),
+        )
 
 
 class ShowUsage(command.ShowOne):
@@ -222,17 +273,21 @@ class ShowUsage(command.ShowOne):
                 "project": project,
             })
 
-        info = {}
-        info['Servers'] = (
-            len(usage.server_usages)
-            if hasattr(usage, "server_usages") else None)
-        info['RAM MB-Hours'] = (
-            float("%.2f" % usage.total_memory_mb_usage)
-            if hasattr(usage, "total_memory_mb_usage") else None)
-        info['CPU Hours'] = (
-            float("%.2f" % usage.total_vcpus_usage)
-            if hasattr(usage, "total_vcpus_usage") else None)
-        info['Disk GB-Hours'] = (
-            float("%.2f" % usage.total_local_gb_usage)
-            if hasattr(usage, "total_local_gb_usage") else None)
-        return zip(*sorted(info.items()))
+        columns = (
+            "tenant_id",
+            "server_usages",
+            "total_memory_mb_usage",
+            "total_vcpus_usage",
+            "total_local_gb_usage"
+        )
+        column_headers = (
+            "Project",
+            "Servers",
+            "RAM MB-Hours",
+            "CPU Hours",
+            "Disk GB-Hours"
+        )
+
+        data = utils.get_item_properties(
+            usage, columns, formatters=_formatters(None))
+        return column_headers, data
diff --git a/openstackclient/tests/unit/compute/v2/test_usage.py b/openstackclient/tests/unit/compute/v2/test_usage.py
index c08710256b..bbccb9bdc7 100644
--- a/openstackclient/tests/unit/compute/v2/test_usage.py
+++ b/openstackclient/tests/unit/compute/v2/test_usage.py
@@ -16,7 +16,7 @@ from unittest import mock
 
 from novaclient import api_versions
 
-from openstackclient.compute.v2 import usage
+from openstackclient.compute.v2 import usage as usage_cmds
 from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
 from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
 
@@ -49,11 +49,11 @@ class TestUsageList(TestUsage):
     )
 
     data = [(
-        usages[0].tenant_id,
-        len(usages[0].server_usages),
-        float("%.2f" % usages[0].total_memory_mb_usage),
-        float("%.2f" % usages[0].total_vcpus_usage),
-        float("%.2f" % usages[0].total_local_gb_usage),
+        usage_cmds.ProjectColumn(usages[0].tenant_id),
+        usage_cmds.CountColumn(usages[0].server_usages),
+        usage_cmds.FloatColumn(usages[0].total_memory_mb_usage),
+        usage_cmds.FloatColumn(usages[0].total_vcpus_usage),
+        usage_cmds.FloatColumn(usages[0].total_local_gb_usage),
     )]
 
     def setUp(self):
@@ -63,7 +63,7 @@ class TestUsageList(TestUsage):
 
         self.projects_mock.list.return_value = [self.project]
         # Get the command object to test
-        self.cmd = usage.ListUsage(self.app, None)
+        self.cmd = usage_cmds.ListUsage(self.app, None)
 
     def test_usage_list_no_options(self):
 
@@ -79,8 +79,8 @@ class TestUsageList(TestUsage):
 
         self.projects_mock.list.assert_called_with()
 
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
+        self.assertCountEqual(self.columns, columns)
+        self.assertCountEqual(tuple(self.data), tuple(data))
 
     def test_usage_list_with_options(self):
         arglist = [
@@ -102,8 +102,8 @@ class TestUsageList(TestUsage):
             datetime.datetime(2016, 12, 20, 0, 0),
             detailed=True)
 
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
+        self.assertCountEqual(self.columns, columns)
+        self.assertCountEqual(tuple(self.data), tuple(data))
 
     def test_usage_list_with_pagination(self):
         arglist = []
@@ -127,8 +127,8 @@ class TestUsageList(TestUsage):
             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))
+        self.assertCountEqual(self.columns, columns)
+        self.assertCountEqual(tuple(self.data), tuple(data))
 
 
 class TestUsageShow(TestUsage):
@@ -139,17 +139,19 @@ class TestUsageShow(TestUsage):
         attrs={'tenant_id': project.name})
 
     columns = (
+        'Project',
+        'Servers',
+        'RAM MB-Hours',
         'CPU Hours',
         'Disk GB-Hours',
-        'RAM MB-Hours',
-        'Servers',
     )
 
     data = (
-        float("%.2f" % usage.total_vcpus_usage),
-        float("%.2f" % usage.total_local_gb_usage),
-        float("%.2f" % usage.total_memory_mb_usage),
-        len(usage.server_usages),
+        usage_cmds.ProjectColumn(usage.tenant_id),
+        usage_cmds.CountColumn(usage.server_usages),
+        usage_cmds.FloatColumn(usage.total_memory_mb_usage),
+        usage_cmds.FloatColumn(usage.total_vcpus_usage),
+        usage_cmds.FloatColumn(usage.total_local_gb_usage),
     )
 
     def setUp(self):
@@ -159,7 +161,7 @@ class TestUsageShow(TestUsage):
 
         self.projects_mock.get.return_value = self.project
         # Get the command object to test
-        self.cmd = usage.ShowUsage(self.app, None)
+        self.cmd = usage_cmds.ShowUsage(self.app, None)
 
     def test_usage_show_no_options(self):
 
diff --git a/releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml b/releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml
index cbe950eace..7a42fa899d 100644
--- a/releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml
+++ b/releasenotes/notes/improved-server-output-6965b664f6abda8d.yaml
@@ -8,3 +8,9 @@ fixes:
     will now be rendered as objects. In addition, the ``power_state`` field
     will now be humanized and rendered as a string value when using the table
     formatter.
+  - |
+    The ``usage list`` and ``usage show`` commands will now display the name
+    of the project being queried rather than the ID when using the table
+    formatter. In addition, the ``server_usages``, ``total_memory_mb_usage``,
+    ``total_vcpus_usage`` and ``total_local_gb_usage`` values will only be
+    humanized when using the table formatter.