return rc;
 }
 
+#define SRCH_STACK_SIZE        16
+
+static void search_stack_free( void *key, void *data)
+{
+       ch_free(data);
+}
+
+static void *search_stack(
+       BackendDB *be,
+       Operation *op
+)
+{
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+       void *ret = NULL;
+
+       if ( op->o_threadctx ) {
+               ldap_pvt_thread_pool_getkey( op->o_threadctx, search_stack,
+                       &ret, NULL );
+       } else {
+               ret = bdb->bi_search_stack;
+       }
+
+       if ( !ret ) {
+               ret = ch_malloc( SRCH_STACK_SIZE * BDB_IDL_UM_SIZE * sizeof( ID ) );
+               if ( op->o_threadctx ) {
+                       ldap_pvt_thread_pool_setkey( op->o_threadctx, search_stack,
+                               ret, search_stack_free );
+               } else {
+                       bdb->bi_search_stack = ret;
+               }
+       }
+       return ret;
+}
+
 static int search_candidates(
        BackendDB *be,
        Operation *op,
 #endif
 
        /* Allocate IDL stack, plus 1 more for former tmp */
-       stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
+       if ( depth+1 > SRCH_STACK_SIZE ) {
+               stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
+       } else {
+               stack = search_stack( be, op );
+       }
 
        rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
 
-       ch_free( stack );
+       if ( depth+1 > SRCH_STACK_SIZE ) {
+               ch_free( stack );
+       }
 
        if( rc ) {
 #ifdef NEW_LOGGING