Admin UX PHP Intermediate

Show Last Login Date in the Users Table

Last updated: May 6, 2026

Knowing when your users last logged in is valuable for several reasons: identifying dormant accounts that should be cleaned up or have their access revoked, auditing activity on membership sites, understanding engagement patterns, and providing evidence during security reviews. WordPress doesn’t record login timestamps natively, but adding this capability is straightforward and requires no external plugin.

The Code

This snippet has four parts working together: recording the timestamp, adding the column, rendering the column, and making it sortable. Add all of it to your functions.php or a site-specific plugin.

Recording the Timestamp

The wp_login action fires after every successful authentication. The callback receives the username string and the full WP_User object. update_user_meta() stores the current server time in MySQL datetime format under the _last_login meta key. The leading underscore is a WordPress convention indicating that this is a private meta key, it won’t appear in the user’s profile edit screen by default.

The Column Display

The column renders the last login time using human_time_diff(), which produces readable relative strings like “3 days ago” or “2 hours ago”. The full formatted date is included as a tooltip via the title attribute using date_i18n(), which respects the site’s configured timezone and locale. Users who have never logged in since the snippet was installed show a greyed-out “Never” label.

Sortable Column

The manage_users_sortable_columns filter registers the column as sortable, and the pre_get_users action modifies the user query when that column is selected. The query is modified to sort by the _last_login meta value. Clicking the column header once sorts ascending (oldest first), clicking again sorts descending (most recent first), which is typically the most useful view for spotting inactive users.

Existing Users

The snippet only records logins that happen after it’s installed. Users who haven’t logged in since the snippet was added will show “Never” in the column. This is accurate for the purposes of the log, you know they haven’t logged in during the period you’ve been tracking, but it’s worth communicating to site administrators that the data is only valid from the date the snippet was activated.

Privacy Considerations

Logging last login times is generally considered acceptable from a privacy standpoint as it’s standard practice in web application security. However, if your site’s privacy policy or jurisdiction requires you to document all data collected about users, make sure login tracking is mentioned. On sites subject to GDPR, last login data is personal data and should be included in any data export or erasure request handling.

functions.php
// Record the login timestamp on successful login
add_action( 'wp_login', function( $user_login, $user ) {
    update_user_meta( $user->ID, '_last_login', current_time( 'mysql' ) );
}, 10, 2 );

// Add the column to the users table
add_filter( 'manage_users_columns', function( $columns ) {
    $columns['last_login'] = 'Last Login';
    return $columns;
} );

// Render the column value
add_filter( 'manage_users_custom_column', function( $output, $column, $user_id ) {
    if ( $column !== 'last_login' ) return $output;

    $last = get_user_meta( $user_id, '_last_login', true );
    if ( ! $last ) return '<span style="color:#94a3b8">Never</span>';

    $timestamp = strtotime( $last );
    return sprintf(
        '<span title="%s">%s</span>',
        esc_attr( date_i18n( 'F j, Y g:i a', $timestamp ) ),
        esc_html( human_time_diff( $timestamp ) . ' ago' )
    );
}, 10, 3 );

// Make the column sortable
add_filter( 'manage_users_sortable_columns', function( $columns ) {
    $columns['last_login'] = 'last_login';
    return $columns;
} );

// Handle the sort query
add_action( 'pre_get_users', function( $query ) {
    if ( ! is_admin() ) return;
    if ( $query->get( 'orderby' ) !== 'last_login' ) return;

    $query->set( 'meta_key', '_last_login' );
    $query->set( 'orderby',  'meta_value' );
} );

Built by Nahnu Plugins

Need something more powerful than a snippet?

Our commercial plugins go further, built for serious WordPress sites with full support, updates, and documentation included.

Browse All Plugins →

This website uses cookies to enhance your browsing experience and ensure the site functions properly. By continuing to use this site, you acknowledge and accept our use of cookies.

Accept All Accept Required Only