diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
index 91bd47a2aa237f9ead93acf4f2311b6aaecb4fc9..5f4a463e27df1a1bbde43f315d6d04998ac3a71e 100644
--- a/servers/slapd/connection.c
+++ b/servers/slapd/connection.c
@@ -909,12 +909,19 @@ void connection_done( Connection *c )
  * calls the appropriate stub to handle it.
  */
 
+#define INCR_OP(var,index) \
+	do { \
+		ldap_pvt_thread_mutex_lock( &num_ops_mutex ); \
+		(var)[(index)]++; \
+		ldap_pvt_thread_mutex_unlock( &num_ops_mutex ); \
+	} while (0)
+
 static void *
 connection_operation( void *arg_v )
 {
 	int rc;
 	struct co_arg	*arg = arg_v;
-	ber_tag_t tag = arg->co_op->o_tag;
+	ber_tag_t tag = arg->co_op->o_tag, oldtag = tag;
 	Connection *conn = arg->co_conn;
 
 	ldap_pvt_thread_mutex_lock( &num_ops_mutex );
@@ -939,42 +946,52 @@ connection_operation( void *arg_v )
 
 	switch ( tag ) {
 	case LDAP_REQ_BIND:
+		INCR_OP(num_ops_initiated_, SLAP_OP_BIND);
 		rc = do_bind( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_UNBIND:
+		INCR_OP(num_ops_initiated_, SLAP_OP_UNBIND);
 		rc = do_unbind( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_ADD:
+		INCR_OP(num_ops_initiated_, SLAP_OP_ADD);
 		rc = do_add( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_DELETE:
+		INCR_OP(num_ops_initiated_, SLAP_OP_DELETE);
 		rc = do_delete( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_MODRDN:
+		INCR_OP(num_ops_initiated_, SLAP_OP_MODRDN);
 		rc = do_modrdn( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_MODIFY:
+		INCR_OP(num_ops_initiated_, SLAP_OP_MODIFY);
 		rc = do_modify( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_COMPARE:
+		INCR_OP(num_ops_initiated_, SLAP_OP_COMPARE);
 		rc = do_compare( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_SEARCH:
+		INCR_OP(num_ops_initiated_, SLAP_OP_SEARCH);
 		rc = do_search( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_ABANDON:
+		INCR_OP(num_ops_initiated_, SLAP_OP_ABANDON);
 		rc = do_abandon( conn, arg->co_op );
 		break;
 
 	case LDAP_REQ_EXTENDED:
+		INCR_OP(num_ops_initiated_, SLAP_OP_EXTENDED);
 		rc = do_extended( conn, arg->co_op );
 		break;
 
@@ -994,11 +1011,44 @@ connection_operation( void *arg_v )
 		break;
 	}
 
+	oldtag = tag;
 	if( rc == SLAPD_DISCONNECT ) tag = LBER_ERROR;
 
 operations_error:
 	ldap_pvt_thread_mutex_lock( &num_ops_mutex );
 	num_ops_completed++;
+	switch (oldtag) {
+	case LDAP_REQ_BIND:
+		num_ops_completed_[SLAP_OP_BIND]++;
+		break;
+	case LDAP_REQ_UNBIND:
+		num_ops_completed_[SLAP_OP_UNBIND]++;
+		break;
+	case LDAP_REQ_ADD:
+		num_ops_completed_[SLAP_OP_ADD]++;
+		break;
+	case LDAP_REQ_DELETE:
+		num_ops_completed_[SLAP_OP_DELETE]++;
+		break;
+	case LDAP_REQ_MODRDN:
+		num_ops_completed_[SLAP_OP_MODRDN]++;
+		break;
+	case LDAP_REQ_MODIFY:
+		num_ops_completed_[SLAP_OP_MODIFY]++;
+		break;
+	case LDAP_REQ_COMPARE:
+		num_ops_completed_[SLAP_OP_COMPARE]++;
+		break;
+	case LDAP_REQ_SEARCH:
+		num_ops_completed_[SLAP_OP_SEARCH]++;
+		break;
+	case LDAP_REQ_ABANDON:
+		num_ops_completed_[SLAP_OP_ABANDON]++;
+		break;
+	case LDAP_REQ_EXTENDED:
+		num_ops_completed_[SLAP_OP_EXTENDED]++;
+		break;
+	}
 	ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
 
 	ldap_pvt_thread_mutex_lock( &conn->c_mutex );
diff --git a/servers/slapd/init.c b/servers/slapd/init.c
index 983dae921496162d9a44078dec9563c808cb04f5..91482efc29a3d5dae606578d758bf1f45de92384 100644
--- a/servers/slapd/init.c
+++ b/servers/slapd/init.c
@@ -43,8 +43,10 @@ ldap_pvt_thread_mutex_t	gmtime_mutex;
 ldap_pvt_thread_mutex_t	passwd_mutex;
 #endif
 
-unsigned long			num_ops_initiated;
-unsigned long			num_ops_completed;
+unsigned long			num_ops_initiated = 0;
+unsigned long			num_ops_initiated_[SLAP_OP_LAST];
+unsigned long			num_ops_completed = 0;
+unsigned long			num_ops_completed_[SLAP_OP_LAST];
 ldap_pvt_thread_mutex_t	num_ops_mutex;
 
 unsigned long			num_entries_sent;
@@ -111,6 +113,14 @@ slap_init( int mode, const char *name )
 			ldap_pvt_thread_mutex_init( &num_ops_mutex );
 			ldap_pvt_thread_mutex_init( &num_sent_mutex );
 
+			{
+				int i;
+				for ( i = 0; i < SLAP_OP_LAST; i++ ) {
+					num_ops_initiated_[ i ] = 0;
+					num_ops_completed_[ i ] = 0;
+				}
+			}
+
 			ldap_pvt_thread_mutex_init( &gmtime_mutex );
 #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
 			ldap_pvt_thread_mutex_init( &passwd_mutex );
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 41cd090c6857ca2054a95d578030d34b5e1c3dc9..ba544ad56e787b6a45bac8fde305a5c996978ae9 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -1015,7 +1015,9 @@ LDAP_SLAPD_V (unsigned long)		num_refs_sent;
 
 LDAP_SLAPD_V (ldap_pvt_thread_mutex_t)	num_ops_mutex;
 LDAP_SLAPD_V (unsigned long)		num_ops_completed;
+LDAP_SLAPD_V (unsigned long)		num_ops_completed_[SLAP_OP_LAST];
 LDAP_SLAPD_V (unsigned long)		num_ops_initiated;
+LDAP_SLAPD_V (unsigned long)		num_ops_initiated_[SLAP_OP_LAST];
 
 LDAP_SLAPD_V (char *)		slapd_pid_file;
 LDAP_SLAPD_V (char *)		slapd_args_file;
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index 3ff6e17f10e4f6afebda4f60bffb059711a296ca..8d03483c63c4022745475fb228f4be420670034a 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -1599,6 +1599,23 @@ typedef struct slap_listener {
 #define sl_addr	sl_sa.sa_in_addr
 } Listener;
 
+/*
+ * Operation indices
+ */
+enum {
+	SLAP_OP_BIND = 0,
+	SLAP_OP_UNBIND,
+	SLAP_OP_ADD,
+	SLAP_OP_DELETE,
+	SLAP_OP_MODRDN,
+	SLAP_OP_MODIFY,
+	SLAP_OP_COMPARE,
+	SLAP_OP_SEARCH,
+	SLAP_OP_ABANDON,
+	SLAP_OP_EXTENDED,
+	SLAP_OP_LAST
+};
+
 LDAP_END_DECL
 
 #include "proto-slap.h"