Index: wp-admin/admin.php
===================================================================
--- wp-admin/admin.php	(revision 13693)
+++ wp-admin/admin.php	(working copy)
@@ -37,7 +37,8 @@
 		 *
 		 * @since 2.8.4b
 		 */
-		$c = get_blog_count();
+		$c = ms_count_blogs();
+		$c = $c->active;
 		if ( $c <= 50 || ( $c > 50 && mt_rand( 0, (int)( $c / 50 ) ) == 1 ) ) {
 			require_once( ABSPATH . WPINC . '/http.php' );
 			$response = wp_remote_get( admin_url( 'upgrade.php?step=1' ), array( 'timeout' => 120, 'httpversion' => '1.1' ) );
Index: wp-admin/includes/ms.php
===================================================================
--- wp-admin/includes/ms.php	(revision 13693)
+++ wp-admin/includes/ms.php	(working copy)
@@ -161,6 +161,8 @@
 	// allow for commit transaction
 	do_action('deleted_user', $id);
 
+	delete_site_transient( 'user_count' );
+
 	return true;
 }
 
@@ -498,6 +500,8 @@
 			do_action( "make_ham_user", $id );
 	}
 
+	delete_site_transient( 'user_count' );
+
 	return $value;
 }
 
Index: wp-admin/ms-admin.php
===================================================================
--- wp-admin/ms-admin.php	(revision 13693)
+++ wp-admin/ms-admin.php	(working copy)
@@ -18,11 +18,11 @@
 	wp_die( __('You do not have permission to access this page.') );
 
 global $wpdb;
-$c_users = get_user_count();
-$c_blogs = get_blog_count();
+$c_users = ms_count_users();
+$c_blogs = ms_count_blogs();
 
-$user_text = sprintf( _n( '%s user', '%s users', $c_users ), number_format_i18n( $c_users ) );
-$blog_text = sprintf( _n( '%s site', '%s sites', $c_blogs ), number_format_i18n( $c_blogs ) );
+$user_text = sprintf( _n( '%s user', '%s users', $c_users->active ), number_format_i18n( $c_users->active ) );
+$blog_text = sprintf( _n( '%s site', '%s sites', $c_blogs->active ), number_format_i18n( $c_blogs->active ) );
 
 $sentence = sprintf( __( 'You have %1$s and %2$s.' ), $blog_text, $user_text );
 ?>
Index: wp-includes/ms-blogs.php
===================================================================
--- wp-includes/ms-blogs.php	(revision 13693)
+++ wp-includes/ms-blogs.php	(working copy)
@@ -502,6 +502,8 @@
 			do_action( "make_ham_blog", $blog_id );
 	}
 
+	delete_site_transient( 'blog_count' );
+
 	return $value;
 }
 
Index: wp-includes/ms-deprecated.php
===================================================================
--- wp-includes/ms-deprecated.php	(revision 13693)
+++ wp-includes/ms-deprecated.php	(working copy)
@@ -24,6 +24,34 @@
 }
 
 /**
+ * @since unknown
+ * @deprecated 3.0.0
+ * @deprecated Use ms_count_blogs()
+ * @see ms_count_blogs()
+ */
+function get_blog_count( $id = '' ) {
+	_deprecated_function( __FUNCTION__, '3.0', 'ms_count_blogs()' );
+
+	$count = ms_count_blogs( $id );
+
+	return $count->active;
+}
+
+/**
+ * @since unknown
+ * @deprecated 3.0.0
+ * @deprecated Use ms_count_users()
+ * @see ms_count_users()
+ */
+function get_user_count() {
+	_deprecated_function( __FUNCTION__, '3.0', 'ms_count_users()' );
+
+	$count = ms_count_users();
+
+	return $count->active;
+}
+
+/**
  * Determine if user is a site admin.
  *
  * Plugins should use is_multisite() instead of checking if this function exists
Index: wp-includes/ms-functions.php
===================================================================
--- wp-includes/ms-functions.php	(revision 13693)
+++ wp-includes/ms-functions.php	(working copy)
@@ -6,19 +6,11 @@
  */
 
 function get_sitestats() {
-	global $wpdb;
+	$count_blog =  ms_count_blogs();
+	$count_users = ms_count_users();
+	$stats['blogs'] = $count_blog->active;
+	$stats['users'] = $count_users->active;
 
-	$stats['blogs'] = get_blog_count();
-
-	$count_ts = get_site_option( 'user_count_ts' );
-	if ( time() - $count_ts > 3600 ) {
-		$count = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->users" );
-		update_site_option( 'user_count', $count );
-		update_site_option( 'user_count_ts', time() );
-	} else {
-		$count = get_site_option( 'user_count' );
-	}
-	$stats['users'] = $count;
 	return $stats;
 }
 
@@ -199,35 +191,97 @@
 	return array_slice( $most_active, 0, $num );
 }
 
-function get_user_count() {
+/**
+ * Retrieve total users 
+ *
+ * The properties of the returned object contain the 'spam' and 'deleted'
+ * users. Those properties contain the amount of users that match
+ * the status. The 'active' property contains the integer of users, which are not
+ * 'spam' and 'deleted'. The 'total' property contains the integer of total users.
+ *
+ * The user stats are cached and then retrieved, if they already exist in the
+ * cache.
+ *
+ * @since 3.0.0
+ *
+ * @return object User stats.
+ */
+function ms_count_users() {
 	global $wpdb;
 
-	$count_ts = get_site_option( "user_count_ts" );
-	if ( time() - $count_ts > 3600 ) {
-		$count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'") );
-		update_site_option( "user_count", $count );
-		update_site_option( "user_count_ts", time() );
+	$count = get_site_transient( 'user_count' );
+
+	if ( false !== $count )
+		return $count;
+
+	$count_users = $wpdb->get_results( "SELECT spam, deleted, COUNT(ID) as num_users FROM $wpdb->users GROUP BY spam, deleted", ARRAY_A );
+	$count['spam'] = $count['deleted'] = $count['total'] = $count['active'] = 0;
+
+	foreach ( (array) $count_users as $row ) {
+		$count['total'] += $row['num_users'];
+
+		if ( $row['spam'] == 1 )
+			$count['spam'] += $row['num_users'];
+		if ( $row['deleted'] == 1 )
+			$count['deleted'] += $row['num_users'];
+		if ( $row['spam'] != 1 && $row['deleted'] != 1 )
+			$count['active'] = $row['num_users'];
 	}
 
-	$count = get_site_option( "user_count" );
+	$count = (object) $count;
+	set_site_transient( 'user_count', $count );
 
 	return $count;
 }
 
-function get_blog_count( $id = 0 ) {
+/**
+ * Retrieve total blogs 
+ *
+ * The properties of the returned object contain the 'spam', 'deleted'
+ * and 'archived' blogs. Those properties contain the amount of blogs that match
+ * the status. The 'active' property contains the integer of blogs, which are not
+ * 'spam', 'deleted' and 'archived'. The 'total' property contains the integer of
+ * total blogs.
+ *
+ * The blog stats are cached and then retrieved, if they already exist in the
+ * cache.
+ *
+ * @since 3.0.0
+ *
+ * @param int $id Optional. Site ID.
+ * @return object Blog stats.
+ */
+function ms_count_blogs( $id = 0 ) {
 	global $wpdb;
 
 	if ( $id == 0 )
 		$id = $wpdb->siteid;
 
-	$count_ts = get_site_option( "blog_count_ts" );
-	if ( time() - $count_ts > 3600 ) {
-		$count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(blog_id) as c FROM $wpdb->blogs WHERE site_id = %d AND spam = '0' AND deleted = '0' and archived = '0'", $id) );
-		update_site_option( "blog_count", $count );
-		update_site_option( "blog_count_ts", time() );
+	$count = get_site_transient( 'blog_count' );
+
+	if ( false !== $count )
+		return $count;
+
+	$count_blogs = $wpdb->get_results( $wpdb->prepare( "SELECT spam, deleted, archived, mature, COUNT(blog_id) as num_blogs FROM $wpdb->blogs WHERE site_id = %d GROUP BY spam, deleted, archived, mature", $id ), ARRAY_A );
+	$count['spam'] = $count['archived'] = $count['deleted'] = $count['mature'] = $count['total'] = $count['active'] = 0;
+
+	foreach ( (array) $count_blogs as $row ) {
+		$count['total'] += $row['num_blogs'];
+
+		if ( $row['spam'] == 1 )
+			$count['spam'] += $row['num_blogs'];
+		if ( $row['archived'] == 1 )
+			$count['archived'] += $row['num_blogs'];
+		if ( $row['deleted'] == 1 )
+			$count['deleted'] += $row['num_blogs'];
+		if ( $row['mature'] == 1 )
+			$count['mature'] += $row['num_blogs'];
+		if ( $row['spam'] != 1 && $row['archived'] != 1 && $row['deleted'] != 1 && $row['mature'] != 1 )
+			$count['active'] = $row['num_blogs'];
 	}
 
-	$count = get_site_option( "blog_count" );
+	$count = (object) $count;
+	set_site_transient( 'blog_count', $count );
 
 	return $count;
 }
@@ -790,6 +844,8 @@
 
 	do_action( 'wpmu_new_user', $user_id );
 
+	delete_site_transient( 'user_count' );
+
 	return $user_id;
 }
 
