diff --git a/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx b/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
index a022aaca4e46d52e327ce2d86117c390489806ab..a4f7123a1b55490a319f2f63052a81de11050412 100644
--- a/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
+++ b/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
@@ -2,7 +2,6 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Link } from "react-router";
-import _ from "underscore";
 import { connect } from "react-redux";
 
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
@@ -30,7 +29,7 @@ export const MODAL_RESET_PASSWORD_EMAIL = "MODAL_RESET_PASSWORD_EMAIL";
 export const MODAL_USER_ADDED_WITH_INVITE = "MODAL_USER_ADDED_WITH_INVITE";
 export const MODAL_USER_ADDED_WITH_PASSWORD = "MODAL_USER_ADDED_WITH_PASSWORD";
 
-import { getUsers, getModal, getGroups } from "../selectors";
+import { getSortedUsers, getModal, getGroups } from "../selectors";
 import {
   createUser,
   deleteUser,
@@ -48,7 +47,7 @@ import {
 
 const mapStateToProps = (state, props) => {
   return {
-    users: getUsers(state, props),
+    users: getSortedUsers(state, props),
     modal: getModal(state, props),
     user: state.currentUser,
     groups: getGroups(state, props),
@@ -402,8 +401,6 @@ export default class PeopleListingApp extends Component {
     let { modal, users, groups } = this.props;
     let { error } = this.state;
 
-    users = _.values(users).sort((a, b) => b.date_joined - a.date_joined);
-
     return (
       <LoadingAndErrorWrapper loading={!users} error={error}>
         {() => (
diff --git a/frontend/src/metabase/admin/people/selectors.js b/frontend/src/metabase/admin/people/selectors.js
index 358d1aad1698b253aa0501ff8810c7ed09756248..577178f90162f4f09118909c5d42882b207f6038 100644
--- a/frontend/src/metabase/admin/people/selectors.js
+++ b/frontend/src/metabase/admin/people/selectors.js
@@ -23,3 +23,19 @@ export const getUsers = createSelector(
           .value(),
     })),
 );
+
+// sort the users list by last_name, ignore case or diacritical marks. If last names are the same then compare by first
+// name
+const compareNames = (a, b) =>
+  a.localeCompare(b, undefined, { sensitivty: "base" });
+
+export const getSortedUsers = createSelector(
+  [getUsers],
+  users =>
+    users &&
+    _.values(users).sort(
+      (a, b) =>
+        compareNames(a.last_name, b.last_name) ||
+        compareNames(a.first_name, b.first_name),
+    ),
+);
diff --git a/src/metabase/api/user.clj b/src/metabase/api/user.clj
index fdb7a6b7191c02fdf13da5a6bcf85fa60549c9c2..342e59eb7a586eb2c79620fc78daf83c00653b92 100644
--- a/src/metabase/api/user.clj
+++ b/src/metabase/api/user.clj
@@ -23,7 +23,9 @@
   "Fetch a list of all active `Users` for the admin People page."
   []
   (db/select [User :id :first_name :last_name :email :is_superuser :google_auth :ldap_auth :last_login]
-    :is_active true))
+    :is_active true
+    {:order-by [[:%lower.last_name :asc]
+                [:%lower.first_name :asc]]}))
 
 (defn- reactivate-user! [existing-user first-name last-name]
   (when-not (:is_active existing-user)