diff --git a/pkg/services/control/convert.go b/pkg/services/control/convert.go
index 833288bb7..f7582dd68 100644
--- a/pkg/services/control/convert.go
+++ b/pkg/services/control/convert.go
@@ -200,3 +200,21 @@ func (w *flushCacheResponseWrapper) FromGRPCMessage(m grpc.Message) error {
 	w.FlushCacheResponse = r
 	return nil
 }
+
+type doctorResponseWrapper struct {
+	*DoctorResponse
+}
+
+func (w *doctorResponseWrapper) ToGRPCMessage() grpc.Message {
+	return w.DoctorResponse
+}
+
+func (w *doctorResponseWrapper) FromGRPCMessage(m grpc.Message) error {
+	r, ok := m.(*DoctorResponse)
+	if !ok {
+		return message.NewUnexpectedMessageType(m, (*DoctorResponse)(nil))
+	}
+
+	w.DoctorResponse = r
+	return nil
+}
diff --git a/pkg/services/control/rpc.go b/pkg/services/control/rpc.go
index 0779e177b..2676ea7a5 100644
--- a/pkg/services/control/rpc.go
+++ b/pkg/services/control/rpc.go
@@ -18,6 +18,7 @@ const (
 	rpcSynchronizeTree = "SynchronizeTree"
 	rpcEvacuateShard   = "EvacuateShard"
 	rpcFlushCache      = "FlushCache"
+	rpcDoctor          = "Doctor"
 )
 
 // HealthCheck executes ControlService.HealthCheck RPC.
@@ -191,3 +192,16 @@ func FlushCache(cli *client.Client, req *FlushCacheRequest, opts ...client.CallO
 
 	return wResp.FlushCacheResponse, nil
 }
+
+// Doctor executes ControlService.Doctor RPC.
+func Doctor(cli *client.Client, req *DoctorRequest, opts ...client.CallOption) (*DoctorResponse, error) {
+	wResp := &doctorResponseWrapper{new(DoctorResponse)}
+	wReq := &requestWrapper{m: req}
+
+	err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcDoctor), wReq, wResp, opts...)
+	if err != nil {
+		return nil, err
+	}
+
+	return wResp.DoctorResponse, nil
+}
diff --git a/pkg/services/control/server/doctor.go b/pkg/services/control/server/doctor.go
new file mode 100644
index 000000000..2c91d4c2b
--- /dev/null
+++ b/pkg/services/control/server/doctor.go
@@ -0,0 +1,37 @@
+package control
+
+import (
+	"context"
+
+	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/engine"
+	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+func (s *Server) Doctor(ctx context.Context, req *control.DoctorRequest) (*control.DoctorResponse, error) {
+	err := s.isValidRequest(req)
+	if err != nil {
+		return nil, status.Error(codes.PermissionDenied, err.Error())
+	}
+
+	if !req.Body.RemoveDuplicates {
+		return nil, status.Error(codes.InvalidArgument, "operation not specified")
+	}
+
+	var prm engine.RemoveDuplicatesPrm
+	prm.Concurrency = int(req.Body.Concurrency)
+
+	err = s.s.RemoveDuplicates(ctx, prm)
+	if err != nil {
+		return nil, status.Error(codes.Internal, err.Error())
+	}
+
+	resp := &control.DoctorResponse{Body: &control.DoctorResponse_Body{}}
+
+	err = SignMessage(s.key, resp)
+	if err != nil {
+		return nil, status.Error(codes.Internal, err.Error())
+	}
+	return resp, nil
+}
diff --git a/pkg/services/control/service.pb.go b/pkg/services/control/service.pb.go
index 78e7b0598..ca3e2770e 100644
Binary files a/pkg/services/control/service.pb.go and b/pkg/services/control/service.pb.go differ
diff --git a/pkg/services/control/service.proto b/pkg/services/control/service.proto
index 5a09a74a5..7c661e661 100644
--- a/pkg/services/control/service.proto
+++ b/pkg/services/control/service.proto
@@ -37,6 +37,9 @@ service ControlService {
 
     // FlushCache moves all data from one shard to the others.
     rpc FlushCache (FlushCacheRequest) returns (FlushCacheResponse);
+
+    // Doctor performs storage restructuring operations on engine.
+    rpc Doctor (DoctorRequest) returns (DoctorResponse);
 }
 
 // Health check request.
@@ -345,3 +348,28 @@ message FlushCacheResponse {
     Body body = 1;
     Signature signature = 2;
 }
+
+
+// Doctor request.
+message DoctorRequest {
+    // Request body structure.
+    message Body {
+        // Number of threads to use for the operation.
+        uint32 concurrency = 1;
+        // Flag to search engine for duplicate objects and leave only one copy.
+        bool remove_duplicates = 2;
+    }
+
+    Body body = 1;
+    Signature signature = 2;
+}
+
+// Doctor response.
+message DoctorResponse {
+    // Response body structure.
+    message Body {
+    }
+
+    Body body = 1;
+    Signature signature = 2;
+}
diff --git a/pkg/services/control/service_frostfs.pb.go b/pkg/services/control/service_frostfs.pb.go
index 5bb119090..0f50d5893 100644
Binary files a/pkg/services/control/service_frostfs.pb.go and b/pkg/services/control/service_frostfs.pb.go differ
diff --git a/pkg/services/control/service_grpc.pb.go b/pkg/services/control/service_grpc.pb.go
index 2cfddd7f5..4a4fbeac1 100644
Binary files a/pkg/services/control/service_grpc.pb.go and b/pkg/services/control/service_grpc.pb.go differ