diff --git src/includes/core/actions.php src/includes/core/actions.php
index 18fa0bb..e56287d 100644
--- src/includes/core/actions.php
+++ src/includes/core/actions.php
@@ -255,7 +255,48 @@ add_action( 'bbp_unspammed_reply',  'bbp_update_reply_walker' );
 add_action( 'bbp_approved_reply',   'bbp_update_reply_walker' );
 add_action( 'bbp_unapproved_reply', 'bbp_update_reply_walker' );
 
-// Users topic & reply counts
+// Update forum topic/reply counts.
+add_action( 'bbp_new_reply',        'bbp_increase_forum_reply_count'        );
+add_action( 'bbp_new_topic',        'bbp_increase_forum_topic_count'        );
+add_action( 'bbp_trashed_reply',    'bbp_decrease_forum_reply_count'        );
+add_action( 'bbp_trashed_topic',    'bbp_decrease_forum_topic_count'        );
+add_action( 'bbp_trashed_topic',    'bbp_increase_forum_topic_count_hidden' );
+add_action( 'bbp_untrashed_reply',  'bbp_increase_forum_reply_count'        );
+add_action( 'bbp_untrashed_topic',  'bbp_increase_forum_topic_count'        );
+add_action( 'bbp_untrashed_topic',  'bbp_decrease_forum_topic_count_hidden' );
+add_action( 'bbp_spammed_reply',    'bbp_decrease_forum_reply_count'        );
+add_action( 'bbp_spammed_topic',    'bbp_decrease_forum_topic_count'        );
+add_action( 'bbp_spammed_topic',    'bbp_increase_forum_topic_count_hidden' );
+add_action( 'bbp_unspammed_reply',  'bbp_increase_forum_reply_count'        );
+add_action( 'bbp_unspammed_topic',  'bbp_increase_forum_topic_count'        );
+add_action( 'bbp_unspammed_topic',  'bbp_decrease_forum_topic_count_hidden' );
+add_action( 'bbp_approved_reply',   'bbp_increase_forum_reply_count'        );
+add_action( 'bbp_approved_topic',   'bbp_increase_forum_topic_count'        );
+add_action( 'bbp_approved_topic',   'bbp_decrease_forum_topic_count_hidden' );
+add_action( 'bbp_unapproved_reply', 'bbp_decrease_forum_reply_count'        );
+add_action( 'bbp_unapproved_topic', 'bbp_decrease_forum_topic_count'        );
+add_action( 'bbp_unapproved_topic', 'bbp_increase_forum_topic_count_hidden' );
+
+// Update forum reply counts for approved/unapproved topics.
+add_action( 'bbp_approved_topic',   'bbp_approved_unapproved_topic_update_forum_reply_count' );
+add_action( 'bbp_unapproved_topic', 'bbp_approved_unapproved_topic_update_forum_reply_count' );
+
+// Update topic reply counts.
+add_action( 'bbp_new_reply',        'bbp_increase_topic_reply_count'        );
+add_action( 'bbp_trashed_reply',    'bbp_decrease_topic_reply_count'        );
+add_action( 'bbp_trashed_reply',    'bbp_increase_topic_reply_count_hidden' );
+add_action( 'bbp_untrashed_reply',  'bbp_increase_topic_reply_count'        );
+add_action( 'bbp_untrashed_reply',  'bbp_decrease_topic_reply_count_hidden' );
+add_action( 'bbp_spammed_reply',    'bbp_decrease_topic_reply_count'        );
+add_action( 'bbp_spammed_reply',    'bbp_increase_topic_reply_count_hidden' );
+add_action( 'bbp_unspammed_reply',  'bbp_increase_topic_reply_count'        );
+add_action( 'bbp_unspammed_reply',  'bbp_decrease_topic_reply_count_hidden' );
+add_action( 'bbp_approved_reply',   'bbp_increase_topic_reply_count'        );
+add_action( 'bbp_approved_reply',   'bbp_decrease_topic_reply_count_hidden' );
+add_action( 'bbp_unapproved_reply', 'bbp_decrease_topic_reply_count'        );
+add_action( 'bbp_unapproved_reply', 'bbp_increase_topic_reply_count_hidden' );
+
+// Users topic & reply counts.
 add_action( 'bbp_new_topic',     'bbp_increase_user_topic_count' );
 add_action( 'bbp_new_reply',     'bbp_increase_user_reply_count' );
 add_action( 'bbp_untrash_topic', 'bbp_increase_user_topic_count' );
@@ -267,6 +308,10 @@ add_action( 'bbp_trash_reply',   'bbp_decrease_user_reply_count' );
 add_action( 'bbp_spam_topic',    'bbp_decrease_user_topic_count' );
 add_action( 'bbp_spam_reply',    'bbp_decrease_user_reply_count' );
 
+// Insert forum/topic/reply counts.
+add_action( 'bbp_insert_topic', 'bbp_insert_topic_update_counts', 10, 2 );
+add_action( 'bbp_insert_reply', 'bbp_insert_reply_update_counts', 10, 3 );
+
 // Topic status transition helpers for replies
 add_action( 'bbp_trash_topic',   'bbp_trash_topic_replies'   );
 add_action( 'bbp_untrash_topic', 'bbp_untrash_topic_replies' );
diff --git src/includes/forums/functions.php src/includes/forums/functions.php
index a821d79..cbb1776 100644
--- src/includes/forums/functions.php
+++ src/includes/forums/functions.php
@@ -73,6 +73,15 @@ function bbp_insert_forum( $forum_data = array(), $forum_meta = array() ) {
 		'forum_id' => $forum_id,
 	) );
 
+	/**
+	 * Fires after forum has been inserted via `bbp_insert_forum`.
+	 *
+	 * @since 2.6.0 bbPress (rXXXX)
+	 *
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_insert_forum', (int) $forum_id );
+
 	// Return new forum ID
 	return $forum_id;
 }
@@ -1141,12 +1150,15 @@ function bbp_bump_forum_topic_count( $forum_id = 0, $difference = 1, $update_anc
 		if ( ! empty( $ancestors ) ) {
 			foreach ( (array) $ancestors as $parent_forum_id ) {
 
-				// Get forum counts
-				$parent_topic_count       = bbp_get_forum_topic_count( $parent_forum_id, false, true );
-				$parent_total_topic_count = bbp_get_forum_topic_count( $parent_forum_id, true,  true );
+				// Only update topic count when an ancestor is not a category.
+				if ( ! bbp_is_forum_category( $parent_forum_id ) ) {
+
+					$parent_topic_count = bbp_get_forum_topic_count( $parent_forum_id, false, true );
+					update_post_meta( $parent_forum_id, '_bbp_topic_count', (int) ( $parent_topic_count + $difference ) );
+				}
 
-				// Update counts
-				update_post_meta( $parent_forum_id, '_bbp_topic_count',       (int) ( $parent_topic_count       + $difference ) );
+				// Update the total topic count.
+				$parent_total_topic_count = bbp_get_forum_topic_count( $parent_forum_id, true,  true );
 				update_post_meta( $parent_forum_id, '_bbp_total_topic_count', (int) ( $parent_total_topic_count + $difference ) );
 			}
 		}
@@ -1158,6 +1170,67 @@ function bbp_bump_forum_topic_count( $forum_id = 0, $difference = 1, $update_anc
 }
 
 /**
+ * Increase the total topic count of a forum by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @uses bbp_get_forum_id() To get the forum id.
+ * @uses bbp_bump_forum_topic_count() To bump forum topic count.
+ *
+ * @return void
+ */
+function bbp_increase_forum_topic_count( $forum_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $forum_id ) ) {
+		return;
+	}
+
+	// If it's a topic, get the forum id.
+	if ( bbp_is_topic( $forum_id ) ) {
+		$topic_id = $forum_id;
+		$forum_id = bbp_get_topic_forum_id( $topic_id );
+
+		// If this is a new, unpublished, topic, increase hidden count and bail.
+		if ( 'bbp_new_topic' === current_filter() && ( ! bbp_is_topic_published( $topic_id ) && ! bbp_is_topic_closed( $topic_id ) ) ) {
+			bbp_increase_forum_topic_count_hidden( $forum_id );
+			return;
+		}
+	}
+
+	bbp_bump_forum_topic_count( $forum_id );
+}
+
+/**
+ * Decrease the total topic count of a forum by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @uses bbp_get_forum_id() To get the forum id.
+ * @uses bbp_bump_forum_topic_count() To bump forum topic count.
+ *
+ * @return void
+ */
+function bbp_decrease_forum_topic_count( $forum_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $forum_id ) ) {
+		return;
+	}
+
+	// If it's a topic, get the forum id.
+	if ( bbp_is_topic( $forum_id ) ) {
+		$forum_id = bbp_get_topic_forum_id( $forum_id );
+	}
+
+	bbp_bump_forum_topic_count( $forum_id, -1 );
+}
+
+/**
  * Bump the total hidden topic count of a forum
  *
  * @since 2.1.0 bbPress (r3825)
@@ -1191,6 +1264,60 @@ function bbp_bump_forum_topic_count_hidden( $forum_id = 0, $difference = 1 ) {
 }
 
 /**
+ * Increase the total hidden topic count of a forum by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @uses bbp_get_forum_id() To get the forum id.
+ * @uses bbp_bump_forum_topic_count_hidden() To bump forum hidden topic count.
+ *
+ * @return void
+ */
+function bbp_increase_forum_topic_count_hidden( $forum_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $forum_id ) ) {
+		return;
+	}
+
+	// If it's a topic, get the forum id.
+	if ( bbp_is_topic( $forum_id ) ) {
+		$forum_id = bbp_get_topic_forum_id( $forum_id );
+	}
+
+	bbp_bump_forum_topic_count_hidden( $forum_id );
+}
+
+/**
+ * Decrease the total hidden topic count of a forum by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @uses bbp_get_forum_id() To get the forum id.
+ * @uses bbp_bump_forum_topic_count_hidden() To bump forum hidden topic count.
+ *
+ * @return void
+ */
+function bbp_decrease_forum_topic_count_hidden( $forum_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $forum_id ) ) {
+		return;
+	}
+
+	// If it's a topic, get the forum id.
+	if ( bbp_is_topic( $forum_id ) ) {
+		$forum_id = bbp_get_topic_forum_id( $forum_id );
+	}
+
+	bbp_bump_forum_topic_count_hidden( $forum_id, -1 );
+}
+
+/**
  * Bump the total topic count of a forum
  *
  * @since 2.1.0 bbPress (r3825)
@@ -1232,12 +1359,15 @@ function bbp_bump_forum_reply_count( $forum_id = 0, $difference = 1, $update_anc
 		if ( ! empty( $ancestors ) ) {
 			foreach ( (array) $ancestors as $parent_forum_id ) {
 
-				// Get forum counts
-				$parent_topic_count       = bbp_get_forum_reply_count( $parent_forum_id, false, true );
-				$parent_total_reply_count = bbp_get_forum_reply_count( $parent_forum_id, true,  true );
+				// Only update reply count when an ancestor is not a category.
+				if ( ! bbp_is_forum_category( $parent_forum_id ) ) {
+
+					$parent_reply_count = bbp_get_forum_reply_count( $parent_forum_id, false, true );
+					update_post_meta( $parent_forum_id, '_bbp_reply_count', (int) ( $parent_reply_count + $difference ) );
+				}
 
-				// Update counts
-				update_post_meta( $parent_forum_id, '_bbp_reply_count',       (int) ( $parent_topic_count       + $difference ) );
+				// Update the total reply count.
+				$parent_total_reply_count = bbp_get_forum_reply_count( $parent_forum_id, true,  true );
 				update_post_meta( $parent_forum_id, '_bbp_total_reply_count', (int) ( $parent_total_reply_count + $difference ) );
 			}
 		}
@@ -1248,6 +1378,100 @@ function bbp_bump_forum_reply_count( $forum_id = 0, $difference = 1, $update_anc
 	return (int) apply_filters( 'bbp_bump_forum_reply_count', $forum_reply_count, $forum_id, $difference, $update_ancestors );
 }
 
+/**
+ * Increase the total reply count of a forum by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @uses bbp_get_forum_id() To get the forum id.
+ * @uses bbp_bump_forum_reply_count() To bump forum topic count.
+ *
+ * @return void
+ */
+function bbp_increase_forum_reply_count( $forum_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $forum_id ) ) {
+		return;
+	}
+
+	// If it's a reply, get the forum id.
+	if ( bbp_is_reply( $forum_id ) ) {
+		$reply_id = $forum_id;
+		$forum_id = bbp_get_reply_forum_id( $reply_id );
+
+		// Don't update if this is a new, unpublished, reply.
+		if ( 'bbp_new_reply' === current_filter() && ! bbp_is_reply_published( $reply_id ) ) {
+			return;
+		}
+	}
+
+	bbp_bump_forum_reply_count( $forum_id );
+}
+
+/**
+ * Decrease the total reply count of a forum by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $forum_id The forum id.
+ *
+ * @uses bbp_get_forum_id() To get the forum id.
+ * @uses bbp_bump_forum_reply_count() To bump forum topic count.
+ *
+ * @return void
+ */
+function bbp_decrease_forum_reply_count( $forum_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $forum_id ) ) {
+		return;
+	}
+
+	// If it's a reply, get the forum id.
+	if ( bbp_is_reply( $forum_id ) ) {
+		$forum_id = bbp_get_reply_forum_id( $forum_id );
+	}
+
+	bbp_bump_forum_reply_count( $forum_id, -1 );
+}
+
+/**
+ * Update forum reply counts when a topic is approved or unapproved.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @uses bbp_get_reply_post_type() To get the reply post type.
+ * @uses bbp_get_public_child_ids() To get the topic's public child ids.
+ * @uses bbp_get_topic_forum_id() To get the topic's forum id.
+ * @uses bbp_bump_forum_reply_count() To bump the forum reply count.
+ *
+ * @return void
+ */
+function bbp_approved_unapproved_topic_update_forum_reply_count( $topic_id = 0 ) {
+
+	// Bail early if we don't have a topic id.
+	if ( empty( $topic_id ) ) {
+		return;
+	}
+
+	// Get the topic's replies.
+	$replies = bbp_get_public_child_ids( $topic_id, bbp_get_reply_post_type() );
+	$count   = count( $replies );
+
+	// If we're unapproving, set count to negative.
+	if ( 'bbp_unapproved_topic' === current_filter() ) {
+		$count = -$count;
+	}
+
+	// Update counts.
+	bbp_bump_forum_reply_count( bbp_get_topic_forum_id( $topic_id ), $count );
+}
+
 /** Forum Updaters ************************************************************/
 
 /**
@@ -1732,10 +1956,14 @@ function bbp_update_forum( $args = array() ) {
 	}
 
 	// Counts
-	bbp_update_forum_subforum_count    ( $r['forum_id'] );
-	bbp_update_forum_reply_count       ( $r['forum_id'] );
-	bbp_update_forum_topic_count       ( $r['forum_id'] );
-	bbp_update_forum_topic_count_hidden( $r['forum_id'] );
+	bbp_update_forum_subforum_count( $r['forum_id'] );
+
+	// Only update topic count if we're deleting a topic, or in the dashboard.
+	if ( in_array( current_filter(), array( 'bbp_deleted_topic', 'save_post' ), true ) ) {
+		bbp_update_forum_reply_count(        $r['forum_id'] );
+		bbp_update_forum_topic_count(        $r['forum_id'] );
+		bbp_update_forum_topic_count_hidden( $r['forum_id'] );
+	}
 
 	// Update the parent forum if one was passed
 	if ( ! empty( $r['post_parent'] ) && is_numeric( $r['post_parent'] ) ) {
diff --git src/includes/replies/functions.php src/includes/replies/functions.php
index caabba0..36d9c2e 100644
--- src/includes/replies/functions.php
+++ src/includes/replies/functions.php
@@ -65,10 +65,52 @@ function bbp_insert_reply( $reply_data = array(), $reply_meta = array() ) {
 	// Update the reply and hierarchy
 	bbp_update_reply( $reply_id, $reply_meta['topic_id'], $reply_meta['forum_id'], array(), $reply_data['post_author'], false, $reply_meta['reply_to'] );
 
+	/**
+	 * Fires after reply has been inserted via `bbp_insert_reply`.
+	 *
+	 * @since 2.6.0 bbPress (rXXXX)
+	 *
+	 * @param int $reply_id The reply id.
+	 * @param int $topic_id The topic id.
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_insert_reply', (int) $reply_id, (int) $reply_meta['topic_id'], (int) $reply_meta['forum_id'] );
+
 	// Return new reply ID
 	return $reply_id;
 }
 
+/**
+ * Update counts after a reply is inserted via `bbp_insert_reply`.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $reply_id The reply id.
+ * @param int $topic_id The topic id.
+ * @param int $forum_id The forum id.
+ *
+ * @uses bbp_get_reply_status() To get the reply status.
+ * @uses bbp_get_public_status_id() To get the public status id.
+ * @uses bbp_increase_topic_reply_count() To bump the reply's topic reply count by 1.
+ * @uses bbp_increase_forum_reply_count() To bump the reply's forum reply count by 1.
+ * @uses bbp_increase_topic_reply_count_hidden() To bump the reply's topic reply
+ *                                               hidden count by 1.
+ *
+ * @return void
+ */
+function bbp_insert_reply_update_counts( $reply_id = 0, $topic_id = 0, $forum_id = 0 ) {
+
+	// If the reply is public, update the forum/topic reply counts.
+	if ( bbp_get_reply_status( $reply_id ) === bbp_get_public_status_id() ) {
+		bbp_increase_topic_reply_count( $topic_id );
+		bbp_increase_forum_reply_count( $forum_id );
+
+	// If the reply isn't public only update the topic reply hidden count.
+	} else {
+		bbp_increase_topic_reply_count_hidden( $topic_id );
+	}
+}
+
 /** Post Form Handlers ********************************************************/
 
 /**
@@ -977,9 +1019,13 @@ function bbp_update_reply_walker( $reply_id, $last_active_time = '', $forum_id =
 				bbp_update_topic_last_active_time( $ancestor, $topic_last_active_time );
 
 				// Counts
-				bbp_update_topic_voice_count       ( $ancestor );
-				bbp_update_topic_reply_count       ( $ancestor );
-				bbp_update_topic_reply_count_hidden( $ancestor );
+				bbp_update_topic_voice_count( $ancestor );
+
+				// Only update reply count if we're deleting a reply, or in the dashboard.
+				if ( in_array( current_filter(), array( 'bbp_deleted_reply', 'save_post' ), true ) ) {
+					bbp_update_topic_reply_count(        $ancestor );
+					bbp_update_topic_reply_count_hidden( $ancestor );
+				}
 
 			// Forum meta relating to most recent topic
 			} elseif ( bbp_is_forum( $ancestor ) ) {
@@ -1003,7 +1049,10 @@ function bbp_update_reply_walker( $reply_id, $last_active_time = '', $forum_id =
 				}
 
 				// Counts
-				bbp_update_forum_reply_count( $ancestor );
+				// Only update reply count if we're deleting a reply, or in the dashboard.
+				if ( in_array( current_filter(), array( 'bbp_deleted_reply', 'save_post' ), true ) ) {
+					bbp_update_forum_reply_count( $ancestor );
+				}
 			}
 		}
 	}
diff --git src/includes/topics/functions.php src/includes/topics/functions.php
index 5a762e5..1878eb4 100644
--- src/includes/topics/functions.php
+++ src/includes/topics/functions.php
@@ -70,6 +70,16 @@ function bbp_insert_topic( $topic_data = array(), $topic_meta = array() ) {
 	// Update the topic and hierarchy
 	bbp_update_topic( $topic_id, $topic_meta['forum_id'], array(), $topic_data['post_author'], false );
 
+	/**
+	 * Fires after topic has been inserted via `bbp_insert_topic`.
+	 *
+	 * @since 2.6.0 bbPress (rXXXX)
+	 *
+	 * @param int $topic_id The topic id.
+	 * @param int $forum_id The forum id.
+	 */
+	do_action( 'bbp_insert_topic', (int) $topic_id, (int) $topic_meta['forum_id'] );
+
 	// Return new topic ID
 	return $topic_id;
 }
@@ -1022,7 +1032,15 @@ function bbp_update_topic_walker( $topic_id, $last_active_time = '', $forum_id =
  * @uses update_post_meta() To update the old forum sticky meta
  * @uses bbp_stick_topic() To stick the topic in the new forum
  * @uses bbp_get_reply_post_type() To get the reply post type
- * @uses bbp_get_all_child_ids() To get the public child ids
+ * @uses bbp_get_all_child_ids() To get the all child ids.
+ * @uses bbp_get_public_child_ids() To get the all child ids.
+ * @uses get_post_field() To get the topic's post status.
+ * @uses bbp_get_public_status_id() To get the public status id.
+ * @uses bbp_decrease_forum_topic_count() To bump the forum topic count by -1.
+ * @uses bbp_bump_forum_reply_count() To bump the forum reply count.
+ * @uses bbp_increase_forum_topic_count() To bump the forum topic count by 1.
+ * @uses bbp_decrease_forum_topic_count_hidden() To bump the forum topic hidden count by -1.
+ * @uses bbp_increase_forum_topic_count_hidden() To bump the forum topic hidden count by 1.
  * @uses bbp_update_reply_forum_id() To update the reply forum id
  * @uses bbp_update_topic_forum_id() To update the topic forum id
  * @uses get_post_ancestors() To get the topic's ancestors
@@ -1100,6 +1118,31 @@ function bbp_move_topic_handler( $topic_id, $old_forum_id, $new_forum_id ) {
 	// Get topic ancestors
 	$old_forum_ancestors = array_values( array_unique( array_merge( array( $old_forum_id ), (array) get_post_ancestors( $old_forum_id ) ) ) );
 
+	// Get reply count.
+	$public_reply_count = count( bbp_get_public_child_ids( $topic_id, bbp_get_reply_post_type() ) );
+
+	// Topic status.
+	$topic_status = get_post_field( 'post_status', $topic_id );
+
+	// Update old/new forum counts.
+	if ( $topic_status === bbp_get_public_status_id() ) {
+
+		// Update old forum counts.
+		bbp_decrease_forum_topic_count( $old_forum_id );
+		bbp_bump_forum_reply_count( $old_forum_id, -$public_reply_count );
+
+		// Update new forum counts.
+		bbp_increase_forum_topic_count( $new_forum_id );
+		bbp_bump_forum_reply_count( $new_forum_id, $public_reply_count );
+	} else {
+
+		// Update old forum counts.
+		bbp_decrease_forum_topic_count_hidden( $old_forum_id );
+
+		// Update new forum counts.
+		bbp_increase_forum_topic_count_hidden( $new_forum_id );
+	}
+
 	// Loop through ancestors and update them
 	if ( ! empty( $old_forum_ancestors ) ) {
 		foreach ( $old_forum_ancestors as $ancestor ) {
@@ -2364,6 +2407,69 @@ function bbp_bump_topic_reply_count( $topic_id = 0, $difference = 1 ) {
 }
 
 /**
+ * Increase the total reply count of a topic by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @uses bbp_is_reply() To check if the passed topic id is a reply.
+ * @uses bbp_get_reply_topic_id() To get the topic id.
+ * @uses bbp_bump_topic_reply_count() To bump topic reply count.
+ *
+ * @return void
+ */
+function bbp_increase_topic_reply_count( $topic_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $topic_id ) ) {
+		return;
+	}
+
+	// If it's a reply, get the topic id.
+	if ( bbp_is_reply( $topic_id ) ) {
+		$reply_id = $topic_id;
+		$topic_id = bbp_get_reply_topic_id( $reply_id );
+
+		// If this is a new, unpublished, reply, update hidden count and bail.
+		if ( 'bbp_new_reply' === current_filter() && ! bbp_is_reply_published( $reply_id ) ) {
+			bbp_increase_topic_reply_count_hidden( $topic_id );
+			return;
+		}
+	}
+
+	bbp_bump_topic_reply_count( $topic_id );
+}
+
+/**
+ * Decrease the total reply count of a topic by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @uses bbp_is_reply() To check if the passed topic id is a reply.
+ * @uses bbp_get_reply_topic_id() To get the topic id.
+ * @uses bbp_bump_topic_reply_count() To bump topic reply count.
+ *
+ * @return void
+ */
+function bbp_decrease_topic_reply_count( $topic_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $topic_id ) ) {
+		return;
+	}
+
+	// If it's a reply, get the topic id.
+	if ( bbp_is_reply( $topic_id ) ) {
+		$topic_id = bbp_get_reply_topic_id( $topic_id );
+	}
+
+	bbp_bump_topic_reply_count( $topic_id, -1 );
+}
+
+/**
  * Bump the total hidden reply count of a topic
  *
  * @since 2.1.0 bbPress (r3825)
@@ -2396,6 +2502,90 @@ function bbp_bump_topic_reply_count_hidden( $topic_id = 0, $difference = 1 ) {
 	return (int) apply_filters( 'bbp_bump_topic_reply_count_hidden', $new_count, $topic_id, $difference );
 }
 
+/**
+ * Increase the total hidden reply count of a topic by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @uses bbp_is_reply() To check if the passed topic id is a reply.
+ * @uses bbp_get_reply_topic_id() To get the topic id.
+ * @uses bbp_bump_topic_reply_count_hidden() To bump topic hidden reply count.
+ *
+ * @return void
+ */
+function bbp_increase_topic_reply_count_hidden( $topic_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $topic_id ) ) {
+		return;
+	}
+
+	// If it's a reply, get the topic id.
+	if ( bbp_is_reply( $topic_id ) ) {
+		$topic_id = bbp_get_reply_topic_id( $topic_id );
+	}
+
+	bbp_bump_topic_reply_count_hidden( $topic_id );
+}
+
+/**
+ * Decrease the total hidden reply count of a topic by one.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $topic_id The topic id.
+ *
+ * @uses bbp_is_reply() To check if the passed topic id is a reply.
+ * @uses bbp_get_reply_topic_id() To get the topic id.
+ * @uses bbp_bump_topic_reply_count_hidden() To bump topic hidden reply count.
+ *
+ * @return void
+ */
+function bbp_decrease_topic_reply_count_hidden( $topic_id = 0 ) {
+
+	// Bail early if no id is passed.
+	if ( empty( $topic_id ) ) {
+		return;
+	}
+
+	// If it's a reply, get the topic id.
+	if ( bbp_is_reply( $topic_id ) ) {
+		$topic_id = bbp_get_reply_topic_id( $topic_id );
+	}
+
+	bbp_bump_topic_reply_count_hidden( $topic_id, -1 );
+}
+
+/**
+ * Update counts after a topic is inserted via `bbp_insert_topic`.
+ *
+ * @since 2.6.0 bbPress (rXXXX)
+ *
+ * @param int $reply_id The reply id.
+ * @param int $topic_id The topic id.
+ *
+ * @uses bbp_get_topic_status() To get the post status.
+ * @uses bbp_get_public_status_id() To get the public status id.
+ * @uses bbp_increase_forum_topic_count() To bump the topic's forum topic count by 1.
+ * @uses bbp_increase_forum_topic_count_hidden() To bump the topic's forum topic
+ *                                               hidden count by 1.
+ *
+ * @return void
+ */
+function bbp_insert_topic_update_counts( $topic_id = 0, $forum_id = 0 ) {
+
+	// If the topic is public, update the forum topic counts.
+	if ( bbp_get_topic_status( $topic_id ) === bbp_get_public_status_id() ) {
+		bbp_increase_forum_topic_count( $forum_id );
+
+	// If the topic isn't public only update the forum topic hidden count.
+	} else {
+		bbp_increase_forum_topic_count_hidden( $forum_id );
+	}
+}
+
 /** Topic Updaters ************************************************************/
 
 /**
diff --git tests/phpunit/includes/testcase.php tests/phpunit/includes/testcase.php
index 2cfe03a..db6abe7 100644
--- tests/phpunit/includes/testcase.php
+++ tests/phpunit/includes/testcase.php
@@ -3,6 +3,7 @@
 class BBP_UnitTestCase extends WP_UnitTestCase {
 
 	protected static $cached_SERVER_NAME = null;
+	protected static $bbp_hooks_saved = array();
 
 	/**
 	 * Fake WP mail globals, to avoid errors
diff --git tests/phpunit/testcases/forums/functions/counts.php tests/phpunit/testcases/forums/functions/counts.php
index dcc8bc3..a9776df 100644
--- tests/phpunit/testcases/forums/functions/counts.php
+++ tests/phpunit/testcases/forums/functions/counts.php
@@ -13,6 +13,8 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 	 * Generic function to test the forum counts with a new topic
 	 */
 	public function test_bbp_forum_new_topic_counts() {
+		remove_action( 'bbp_insert_topic', 'bbp_insert_topic_update_counts', 10 );
+
 		$f = $this->factory->forum->create();
 		$t1 = $this->factory->topic->create( array(
 			'post_parent' => $f,
@@ -23,15 +25,12 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 		) );
 		$u = $this->factory->user->create();
 
-		// Cheating here, but we need $_SERVER['SERVER_NAME'] to be set.
-		$this->setUp_wp_mail( false );
+		// Don't attempt to send an email. This is for speed and PHP errors.
+		remove_action( 'bbp_new_topic', 'bbp_notify_forum_subscribers', 11, 4 );
 
 		// Simulate the 'bbp_new_topic' action.
 		do_action( 'bbp_new_topic', $t1, $f, false, bbp_get_current_user_id(), $t1 );
 
-		// Reverse our changes.
-		$this->tearDown_wp_mail( false );
-
 		$count = bbp_get_forum_topic_count( $f, true, true );
 		$this->assertSame( 1, $count );
 
@@ -46,20 +45,18 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 			),
 		) );
 
-		// Cheating here, but we need $_SERVER['SERVER_NAME'] to be set.
-		$this->setUp_wp_mail( false );
-
 		// Simulate the 'bbp_new_topic' action.
 		do_action( 'bbp_new_topic', $t2, $f, false, $u , $t2 );
 
-		// Reverse our changes.
-		$this->tearDown_wp_mail( false );
-
 		$count = bbp_get_forum_topic_count( $f, true, true );
 		$this->assertSame( 2, $count );
 
 		$count = bbp_get_forum_topic_count_hidden( $f, true, true );
 		$this->assertSame( 0, $count );
+
+		// Re-add removed actions.
+		add_action( 'bbp_insert_topic', 'bbp_insert_topic_update_counts', 10, 2 );
+		add_action( 'bbp_new_topic',    'bbp_notify_forum_subscribers',   11, 4 );
 	}
 
 	/**
@@ -253,6 +250,47 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 		$this->assertSame( '1', $count );
 	}
 
+ 	/**
+	 * @covers ::bbp_increase_forum_topic_count
+	 */
+	public function test_bbp_increase_forum_topic_count() {
+		$f = $this->factory->forum->create();
+
+		$count = bbp_get_forum_topic_count( $f );
+		$this->assertSame( '0', $count );
+
+		bbp_increase_forum_topic_count( $f );
+
+		$count = bbp_get_forum_topic_count( $f );
+		$this->assertSame( '1', $count );
+	}
+
+	/**
+	 * @covers ::bbp_decrease_forum_topic_count
+	 */
+	public function test_bbp_decrease_forum_topic_count() {
+		$f = $this->factory->forum->create();
+
+		$count = bbp_get_forum_topic_count( $f );
+		$this->assertSame( '0', $count );
+
+		$t = $this->factory->topic->create_many( 9, array(
+			'post_parent' => $f,
+		) );
+
+		bbp_update_forum_topic_count( $f );
+
+		$count = bbp_get_forum_topic_count( $f );
+		$this->assertSame( '9', $count );
+
+		bbp_update_forum_topic_count( $f );
+
+		bbp_decrease_forum_topic_count( $f );
+
+		$count = bbp_get_forum_topic_count( $f );
+		$this->assertSame( '8', $count );
+	}
+
 	/**
 	 * @covers ::bbp_bump_forum_topic_count_hidden
 	 */
@@ -268,6 +306,50 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 		$this->assertSame( '1', $count );
 	}
 
+ 	/**
+	 * @covers ::bbp_increase_forum_topic_count_hidden
+	 */
+	public function test_bbp_increase_forum_topic_count_hidden() {
+		$f = $this->factory->forum->create();
+
+		$count = bbp_get_forum_topic_count_hidden( $f );
+		$this->assertSame( '0', $count );
+
+		bbp_increase_forum_topic_count_hidden( $f );
+
+		$count = bbp_get_forum_topic_count_hidden( $f );
+		$this->assertSame( '1', $count );
+	}
+
+	/**
+	 * @covers ::bbp_decrease_forum_topic_count_hidden
+	 */
+	public function test_bbp_decrease_forum_topic_count_hidden() {
+		$f = $this->factory->forum->create();
+
+		$count = bbp_get_forum_topic_count_hidden( $f );
+		$this->assertSame( '0', $count );
+
+		$t = $this->factory->topic->create_many( 9, array(
+			'post_parent' => $f,
+			'post_status' => bbp_get_spam_status_id(),
+			'topic_meta' => array(
+				'forum_id' => $f,
+				'spam_meta_status' => 'publish',
+			)
+		) );
+
+		bbp_update_forum_topic_count_hidden( $f );
+
+		$count = bbp_get_forum_topic_count_hidden( $f );
+		$this->assertSame( '9', $count );
+
+		bbp_decrease_forum_topic_count_hidden( $f );
+
+		$count = bbp_get_forum_topic_count_hidden( $f );
+		$this->assertSame( '8', $count );
+	}
+
 	/**
 	 * @covers ::bbp_bump_forum_reply_count
 	 */
@@ -283,6 +365,49 @@ class BBP_Tests_Forums_Functions_Counts extends BBP_UnitTestCase {
 		$this->assertSame( '1', $count );
 	}
 
+ 	/**
+	 * @covers ::bbp_increase_forum_reply_count
+	 */
+	public function test_bbp_increase_forum_reply_count() {
+		$f = $this->factory->forum->create();
+
+		$count = bbp_get_forum_reply_count( $f );
+		$this->assertSame( '0', $count );
+
+		bbp_increase_forum_reply_count( $f );
+
+		$count = bbp_get_forum_reply_count( $f );
+		$this->assertSame( '1', $count );
+	}
+
+	/**
+	 * @covers ::bbp_decrease_forum_reply_count
+	 */
+	public function test_bbp_decrease_forum_reply_count() {
+		$f = $this->factory->forum->create();
+
+		$count = bbp_get_forum_reply_count( $f );
+		$this->assertSame( '0', $count );
+
+		$t = $this->factory->topic->create( array(
+			'post_parent' => $f,
+		) );
+
+		$r = $this->factory->reply->create_many( 9, array(
+			'post_parent' => $t,
+		) );
+
+		bbp_update_forum_reply_count( $f );
+
+		$count = bbp_get_forum_reply_count( $f );
+		$this->assertSame( '9', $count );
+
+		bbp_decrease_forum_reply_count( $f );
+
+		$count = bbp_get_forum_reply_count( $f );
+		$this->assertSame( '8', $count );
+	}
+
 	/**
 	 * @covers ::bbp_update_forum_subforum_count
 	 */
diff --git tests/phpunit/testcases/topics/functions/counts.php tests/phpunit/testcases/topics/functions/counts.php
index c040874..c5ffc88 100644
--- tests/phpunit/testcases/topics/functions/counts.php
+++ tests/phpunit/testcases/topics/functions/counts.php
@@ -13,6 +13,8 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 	 * Generic function to test the topics counts with a new reply
 	 */
 	public function test_bbp_topic_new_reply_counts() {
+		remove_action( 'bbp_insert_reply', 'bbp_insert_reply_update_counts', 10 );
+
 		$f = $this->factory->forum->create();
 		$t = $this->factory->topic->create( array(
 			'post_parent' => $f,
@@ -31,15 +33,12 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 		) );
 		$u = $this->factory->user->create();
 
-		// Cheating here, but we need $_SERVER['SERVER_NAME'] to be set.
-		$this->setUp_wp_mail( false );
+		// Don't attempt to send an email. This is for speed and PHP errors.
+		remove_action( 'bbp_new_reply', 'bbp_notify_subscribers', 11, 5 );
 
 		// Simulate the 'bbp_new_reply' action.
 		do_action( 'bbp_new_reply', $r1, $t, $f, false, bbp_get_current_user_id() );
 
-		// Reverse our changes.
-		$this->tearDown_wp_mail( false );
-
 		$count = bbp_get_topic_reply_count( $t, true );
 		$this->assertSame( 1, $count );
 
@@ -58,15 +57,9 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 			),
 		) );
 
-		// Cheating here, but we need $_SERVER['SERVER_NAME'] to be set.
-		$this->setUp_wp_mail( false );
-
 		// Simulate the 'bbp_new_topic' action.
 		do_action( 'bbp_new_reply', $r2, $t, $f, false, $u );
 
-		// Reverse our changes.
-		$this->tearDown_wp_mail( false );
-
 		$count = bbp_get_topic_reply_count( $t, true );
 		$this->assertSame( 2, $count );
 
@@ -75,6 +68,11 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 
 		$count = bbp_get_topic_voice_count( $t, true );
 		$this->assertSame( 2, $count );
+
+		// Re-add removed actions.
+		add_action( 'bbp_insert_reply', 'bbp_insert_reply_update_counts', 10, 2 );
+		add_action( 'bbp_new_reply',    'bbp_notify_subscribers',         11, 5 );
+
 	}
 
 	/**
@@ -340,6 +338,42 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 		$this->assertSame( '4', $count );
 	}
 
+ 	/**
+	 * @covers ::bbp_increase_topic_reply_count
+	 */
+	public function test_bbp_increase_topic_reply_count() {
+		$t = $this->factory->topic->create();
+
+		$count = bbp_get_topic_reply_count( $t );
+		$this->assertSame( '0', $count );
+
+		bbp_increase_topic_reply_count( $t );
+
+		$count = bbp_get_topic_reply_count( $t );
+		$this->assertSame( '1', $count );
+	}
+
+	/**
+	 * @covers ::bbp_decrease_topic_reply_count
+	 */
+	public function test_bbp_decrease_topic_reply_count() {
+		$t = $this->factory->topic->create();
+
+		$count = bbp_get_topic_reply_count( $t );
+		$this->assertSame( '0', $count );
+
+		// Set the count manually to 9
+		bbp_update_topic_reply_count( $t, 9 );
+
+		$count = bbp_get_topic_reply_count( $t );
+		$this->assertSame( '9', $count );
+
+		bbp_decrease_topic_reply_count( $t );
+
+		$count = bbp_get_topic_reply_count( $t );
+		$this->assertSame( '8', $count );
+	}
+
 	/**
 	 * @covers ::bbp_bump_topic_reply_count_hidden
 	 */
@@ -358,6 +392,42 @@ class BBP_Tests_Topics_Functions_Counts extends BBP_UnitTestCase {
 		$this->assertSame( '4', $count );
 	}
 
+ 	/**
+	 * @covers ::bbp_increase_topic_reply_count_hidden
+	 */
+	public function test_bbp_increase_topic_reply_count_hidden() {
+		$t = $this->factory->topic->create();
+
+		$count = bbp_get_topic_reply_count_hidden( $t );
+		$this->assertSame( '0', $count );
+
+		bbp_increase_topic_reply_count_hidden( $t );
+
+		$count = bbp_get_topic_reply_count_hidden( $t );
+		$this->assertSame( '1', $count );
+	}
+
+	/**
+	 * @covers ::bbp_decrease_topic_reply_count_hidden
+	 */
+	public function test_bbp_decrease_topic_reply_count_hidden() {
+		$t = $this->factory->topic->create();
+
+		$count = bbp_get_topic_reply_count_hidden( $t );
+		$this->assertSame( '0', $count );
+
+		// Set the count manually to 9
+		bbp_update_topic_reply_count_hidden( $t, 9 );
+
+		$count = bbp_get_topic_reply_count_hidden( $t );
+		$this->assertSame( '9', $count );
+
+		bbp_decrease_topic_reply_count_hidden( $t );
+
+		$count = bbp_get_topic_reply_count_hidden( $t );
+		$this->assertSame( '8', $count );
+	}
+
 	/**
 	 * @covers ::bbp_update_topic_reply_count
 	 */
diff --git tests/phpunit/testcases/topics/functions/topic.php tests/phpunit/testcases/topics/functions/topic.php
index 5b191fb..f26840d 100644
--- tests/phpunit/testcases/topics/functions/topic.php
+++ tests/phpunit/testcases/topics/functions/topic.php
@@ -181,6 +181,11 @@ class BBP_Tests_Topics_Functions_Topic extends BBP_UnitTestCase {
 		$this->assertSame( $new_forum_id, bbp_get_reply_forum_id( $reply_id ) );
 		$this->assertSame( $topic_id, bbp_get_reply_topic_id( $reply_id ) );
 
+		// Old Topic/Reply Counts
+		$this->assertSame( 0, bbp_get_forum_topic_count( $old_forum_id, true, true ) );
+		$this->assertSame( 0, bbp_get_forum_reply_count( $old_forum_id, true, true ) );
+
+
 		// Retore the user
 		$this->set_current_user( $this->old_current_user );
 	}
