diff --git src/bp-groups/bp-groups-functions.php src/bp-groups/bp-groups-functions.php
index 9ecddaad7..00f4956eb 100644
--- src/bp-groups/bp-groups-functions.php
+++ src/bp-groups/bp-groups-functions.php
@@ -500,6 +500,9 @@ function groups_get_id_by_previous_slug( $group_slug ) {
 /**
  * Remove a user from a group.
  *
+ * @todo Check if group exists first.
+ * @todo Get group by other fields: slug/id/object. See #6749.
+ *
  * @since 1.0.0
  *
  * @param int $group_id ID of the group.
@@ -542,6 +545,9 @@ function groups_leave_group( $group_id, $user_id = 0 ) {
 /**
  * Add a user to a group.
  *
+ * @todo Check if group exists first.
+ * @todo Get group by other fields: slug/id/object. See #6749.
+ *
  * @since 1.0.0
  *
  * @param int $group_id ID of the group.
@@ -551,22 +557,26 @@ function groups_leave_group( $group_id, $user_id = 0 ) {
  */
 function groups_join_group( $group_id, $user_id = 0 ) {
 
-	if ( empty( $user_id ) )
+	if ( empty( $user_id ) ) {
 		$user_id = bp_loggedin_user_id();
+	}
 
 	// Check if the user has an outstanding invite. If so, delete it.
-	if ( groups_check_user_has_invite( $user_id, $group_id ) )
+	if ( groups_check_user_has_invite( $user_id, $group_id ) ) {
 		groups_delete_invite( $user_id, $group_id );
+	}
 
 	// Check if the user has an outstanding request. If so, delete it.
-	if ( groups_check_for_membership_request( $user_id, $group_id ) )
+	if ( groups_check_for_membership_request( $user_id, $group_id ) ) {
 		groups_delete_membership_request( null, $user_id, $group_id );
+	}
 
 	// User is already a member, just return true.
-	if ( groups_is_user_member( $user_id, $group_id ) )
+	if ( groups_is_user_member( $user_id, $group_id ) ) {
 		return true;
+	}
 
-	$new_member                = new BP_Groups_Member;
+	$new_member                = new BP_Groups_Member();
 	$new_member->group_id      = $group_id;
 	$new_member->user_id       = $user_id;
 	$new_member->inviter_id    = 0;
@@ -575,34 +585,40 @@ function groups_join_group( $group_id, $user_id = 0 ) {
 	$new_member->date_modified = bp_core_current_time();
 	$new_member->is_confirmed  = 1;
 
-	if ( !$new_member->save() )
+	if ( ! $new_member->save() ) {
 		return false;
+	}
 
 	$bp = buddypress();
 
-	if ( !isset( $bp->groups->current_group ) || !$bp->groups->current_group || $group_id != $bp->groups->current_group->id )
+	if ( ! isset( $bp->groups->current_group ) || ! $bp->groups->current_group || $group_id !== $bp->groups->current_group->id ) {
 		$group = groups_get_group( $group_id );
-	else
+	} else {
 		$group = $bp->groups->current_group;
+	}
 
 	// Record this in activity streams.
 	if ( bp_is_active( 'activity' ) ) {
-		groups_record_activity( array(
-			'type'    => 'joined_group',
-			'item_id' => $group_id,
-			'user_id' => $user_id,
-		) );
+		groups_record_activity(
+			array(
+				'type'    => 'joined_group',
+				'item_id' => $group_id,
+				'user_id' => $user_id,
+			)
+		);
 	}
 
 	/**
 	 * Fires after a user joins a group.
 	 *
 	 * @since 1.0.0
+	 * @since 10.0.0 Added the `$group` parameter.
 	 *
-	 * @param int $group_id ID of the group.
-	 * @param int $user_id  ID of the user joining the group.
+	 * @param int             $group_id ID of the group.
+	 * @param int             $user_id  ID of the user joining the group.
+	 * @param BP_Groups_Group $group    The group object.
 	 */
-	do_action( 'groups_join_group', $group_id, $user_id );
+	do_action( 'groups_join_group', $group_id, $user_id, $group );
 
 	return true;
 }
@@ -767,12 +783,14 @@ function groups_get_group_members( $args = array() ) {
  * Get the member count for a group.
  *
  * @since 1.2.3
+ * @since 10.0.0 Updated to use `BP_Groups_Group::get_total_member_count`
  *
- * @param int $group_id Group ID.
+ * @param int  $group_id   Group ID.
+ * @param bool $skip_cache Skip grabbing from cache.
  * @return int Count of confirmed members for the group.
  */
-function groups_get_total_member_count( $group_id ) {
-	return BP_Groups_Group::get_total_member_count( $group_id );
+function groups_get_total_member_count( $group_id, $skip_cache = false ) {
+	return (int) BP_Groups_Group::get_total_member_count( $group_id, $skip_cache );
 }
 
 /** Group Fetching, Filtering & Searching  ************************************/
diff --git src/bp-groups/classes/class-bp-groups-group.php src/bp-groups/classes/class-bp-groups-group.php
index f06ec8055..57fdd5e7a 100644
--- src/bp-groups/classes/class-bp-groups-group.php
+++ src/bp-groups/classes/class-bp-groups-group.php
@@ -1667,8 +1667,9 @@ class BP_Groups_Group {
 		global $wpdb;
 
 		$hidden_sql = '';
-		if ( !bp_current_user_can( 'bp_moderate' ) )
+		if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 			$hidden_sql = "WHERE status != 'hidden'";
+		}
 
 		$bp = buddypress();
 
@@ -1679,16 +1680,40 @@ class BP_Groups_Group {
 	 * Get the member count for a group.
 	 *
 	 * @since 1.6.0
+	 * @since 10.0.0 Updated to use the `groups_get_group_members`.
 	 *
-	 * @param int $group_id Group ID.
+	 * @param int  $group_id   Group ID.
+	 * @param bool $skip_cache Skip getting count from cache.
 	 * @return int Count of confirmed members for the group.
 	 */
-	public static function get_total_member_count( $group_id ) {
-		global $wpdb;
+	public static function get_total_member_count( $group_id, $skip_cache = false ) {
+		$cache_key = 'total_member_count';
+		$count     = groups_get_groupmeta( $group_id, $cache_key );
 
-		$bp = buddypress();
+		if ( false === $count || true === $skip_cache ) {
+			$members = groups_get_group_members(
+				array(
+					'group_id'            => $group_id,
+					'exclude_banned'      => true,
+					'exclude_admins_mods' => false,
+					'type'                => 'active',
+				)
+			);
+
+			$count = $members['count'] ?? 0;
 
-		return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 1 AND is_banned = 0", $group_id ) );
+			groups_update_groupmeta( $group_id, $cache_key, (int) $count );
+		}
+
+		/**
+		 * Filters the total member count for a group.
+		 *
+		 * @since 10.0.0
+		 *
+		 * @param int $count    Total member count for group.
+		 * @param int $group_id The ID of the group.
+		 */
+		return apply_filters( 'bp_groups_total_member_count', (int) $count, (int) $group_id );
 	}
 
 	/**
diff --git src/bp-groups/classes/class-bp-groups-list-table.php src/bp-groups/classes/class-bp-groups-list-table.php
index be3864b32..4a102b3fd 100644
--- src/bp-groups/classes/class-bp-groups-list-table.php
+++ src/bp-groups/classes/class-bp-groups-list-table.php
@@ -701,11 +701,12 @@ class BP_Groups_List_Table extends WP_List_Table {
 	 * Markup for the Number of Members column.
 	 *
 	 * @since 1.7.0
+	 * @since 10.0.0 Updated to use `groups_get_total_member_count`.
 	 *
 	 * @param array $item Information about the current row.
 	 */
 	public function column_members( $item = array() ) {
-		$count = groups_get_groupmeta( $item['id'], 'total_member_count' );
+		$count = groups_get_total_member_count( absint( $item['id'] ) );
 
 		/**
 		 * Filters the markup for the number of Members column.
diff --git src/bp-groups/classes/class-bp-groups-member.php src/bp-groups/classes/class-bp-groups-member.php
index a442ce932..d26de99ea 100644
--- src/bp-groups/classes/class-bp-groups-member.php
+++ src/bp-groups/classes/class-bp-groups-member.php
@@ -465,7 +465,7 @@ class BP_Groups_Member {
 	/** Static Methods ****************************************************/
 
 	/**
-	 * Refresh the total_group_count for a user.
+	 * Refresh the `total_group_count` for a user.
 	 *
 	 * @since 1.8.0
 	 *
@@ -477,15 +477,18 @@ class BP_Groups_Member {
 	}
 
 	/**
-	 * Refresh the total_member_count for a group.
+	 * Refresh the `total_member_count` for a group.
+	 *
+	 * The request skip the current cache so that we always grab the lastest total count.
 	 *
 	 * @since 1.8.0
+	 * @since 10.0.0 Updated to use `BP_Groups_Group::get_total_member_count`
 	 *
 	 * @param int $group_id ID of the group.
-	 * @return bool|int True on success, false on failure.
+	 * @return int Count of confirmed members for the group.
 	 */
 	public static function refresh_total_member_count_for_group( $group_id ) {
-		return groups_update_groupmeta( $group_id, 'total_member_count', (int) BP_Groups_Group::get_total_member_count( $group_id ) );
+		return (int) BP_Groups_Group::get_total_member_count( $group_id, true );
 	}
 
 	/**
@@ -495,7 +498,7 @@ class BP_Groups_Member {
 	 *
 	 * @param int $user_id  ID of the user.
 	 * @param int $group_id ID of the group.
-	 * @return True on success, false on failure.
+	 * @return bool True on success, false on failure.
 	 */
 	public static function delete( $user_id, $group_id ) {
 		global $wpdb;
@@ -510,7 +513,7 @@ class BP_Groups_Member {
 		 */
 		do_action( 'bp_groups_member_before_delete', $user_id, $group_id );
 
-		$bp = buddypress();
+		$bp     = buddypress();
 		$remove = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d", $user_id, $group_id ) );
 
 		// Update the user's group count.
@@ -529,7 +532,7 @@ class BP_Groups_Member {
 		 */
 		do_action( 'bp_groups_member_after_delete', $user_id, $group_id );
 
-		return $remove;
+		return (bool) $remove;
 	}
 
 	/**
diff --git src/bp-groups/screens/single/members.php src/bp-groups/screens/single/members.php
index 6174fd604..fccce2902 100644
--- src/bp-groups/screens/single/members.php
+++ src/bp-groups/screens/single/members.php
@@ -14,14 +14,12 @@
  */
 function groups_screen_group_members() {
 
-	if ( !bp_is_single_item() )
+	if ( ! bp_is_single_item() ) {
 		return false;
+	}
 
 	$bp = buddypress();
 
-	// Refresh the group member count meta.
-	groups_update_groupmeta( $bp->groups->current_group->id, 'total_member_count', groups_get_total_member_count( $bp->groups->current_group->id ) );
-
 	/**
 	 * Fires before the loading of a group's Members page.
 	 *
@@ -39,4 +37,4 @@ function groups_screen_group_members() {
 	 * @param string $value Path to a group's Members template.
 	 */
 	bp_core_load_template( apply_filters( 'groups_template_group_members', 'groups/single/home' ) );
-}
\ No newline at end of file
+}
diff --git tests/phpunit/testcases/groups/functions.php tests/phpunit/testcases/groups/functions.php
index 4b7533f55..8a852a9ff 100644
--- tests/phpunit/testcases/groups/functions.php
+++ tests/phpunit/testcases/groups/functions.php
@@ -184,7 +184,7 @@ class BP_Tests_Groups_Functions extends BP_UnitTestCase {
 		$g = self::factory()->group->create( array( 'creator_id' => $u1 ) );
 
 		groups_join_group( $g, $u2 );
-		$this->assertEquals( 2, groups_get_groupmeta( $g, 'total_member_count' ) );
+		$this->assertEquals( 2, groups_get_total_member_count( $g ) );
 	}
 
 	/**
@@ -193,11 +193,16 @@ class BP_Tests_Groups_Functions extends BP_UnitTestCase {
 	 */
 	public function test_total_member_count_groups_leave_group() {
 		$u1 = self::factory()->user->create();
+		$u2 = self::factory()->user->create();
 		$g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );
-		groups_join_group( $g1, $u1 );
 
-		groups_leave_group( $g1, $u1 );
-		$this->assertEquals( 1, groups_get_groupmeta( $g1, 'total_member_count' ) );
+		groups_join_group( $g1, $u2 );
+
+		$this->assertEquals( 2, groups_get_total_member_count( $g1 ) );
+
+		groups_leave_group( $g1, $u2 );
+
+		$this->assertEquals( 1, groups_get_total_member_count( $g1 ) );
 	}
 
 	/**
@@ -214,9 +219,11 @@ class BP_Tests_Groups_Functions extends BP_UnitTestCase {
 		$this->set_current_user( $u1 );
 		buddypress()->is_item_admin = true;
 
+		$this->assertEquals( 2, groups_get_total_member_count( $g1 ) );
+
 		groups_ban_member( $u2, $g1 );
 
-		$this->assertEquals( 1, groups_get_groupmeta( $g1, 'total_member_count' ) );
+		$this->assertEquals( 1, groups_get_total_member_count( $g1 ) );
 	}
 
 	/**
@@ -235,9 +242,11 @@ class BP_Tests_Groups_Functions extends BP_UnitTestCase {
 
 		groups_ban_member( $u2, $g1 );
 
+		$this->assertEquals( 1, groups_get_total_member_count( $g1 ) );
+
 		groups_unban_member( $u2, $g1 );
 
-		$this->assertEquals( 2, groups_get_groupmeta( $g1, 'total_member_count' ) );
+		$this->assertEquals( 2, groups_get_total_member_count( $g1 ) );
 	}
 
 	/**
@@ -255,9 +264,11 @@ class BP_Tests_Groups_Functions extends BP_UnitTestCase {
 			'send_invite' => 1,
 		) );
 
+		$this->assertEquals( 1, groups_get_total_member_count( $g ) );
+
 		groups_accept_invite( $u2, $g );
 
-		$this->assertEquals( 2, groups_get_groupmeta( $g, 'total_member_count' ) );
+		$this->assertEquals( 2, groups_get_total_member_count( $g ) );
 	}
 
 	/**
@@ -275,7 +286,7 @@ class BP_Tests_Groups_Functions extends BP_UnitTestCase {
 		) );
 		groups_accept_membership_request( 0, $u2, $g );
 
-		$this->assertEquals( 2, groups_get_groupmeta( $g, 'total_member_count' ) );
+		$this->assertEquals( 2, groups_get_total_member_count( $g ) );
 	}
 
 	/**
@@ -294,7 +305,32 @@ class BP_Tests_Groups_Functions extends BP_UnitTestCase {
 
 		groups_remove_member( $u2, $g1 );
 
-		$this->assertEquals( 1, groups_get_groupmeta( $g1, 'total_member_count' ) );
+		$this->assertEquals( 1, groups_get_total_member_count( $g1 ));
+	}
+
+	/**
+	 * @group total_member_count
+	 * @group groups_remove_member
+	 */
+	public function test_total_member_count_groups_delete_member() {
+		$u1 = self::factory()->user->create();
+		$u2 = self::factory()->user->create();
+		$u3 = self::factory()->user->create();
+		$g1 = self::factory()->group->create( array( 'creator_id' => $u1 ) );
+
+		groups_join_group( $g1, $u2 );
+		groups_join_group( $g1, $u3 );
+
+		$this->set_current_user( $u1 );
+
+		$this->assertEquals( 3, groups_get_total_member_count( $g1 ) );
+		$this->assertEquals( 3, BP_Groups_Group::get_total_member_count( $g1 ) );
+
+		// Delete user.
+		wp_delete_user( $u2 );
+
+		$this->assertEquals( 2, groups_get_total_member_count( $g1 ) );
+		$this->assertEquals( 2, BP_Groups_Group::get_total_member_count( $g1 ) );
 	}
 
 	/**
@@ -313,7 +349,7 @@ class BP_Tests_Groups_Functions extends BP_UnitTestCase {
 			'date_created' => bp_core_current_time(),
 		) );
 
-		$this->assertEquals( 1, groups_get_groupmeta( $g, 'total_member_count' ) );
+		$this->assertEquals( 1, groups_get_total_member_count( $g ) );
 	}
 
 	/**
