diff --git a/config.yaml b/config.yaml
index 107ec8bd3b9ce98d895a025b2b2ee8dd8726f02e..ce8f9288c4f7b23d86d561ea0b03cb9dd400bbcf 100644
--- a/config.yaml
+++ b/config.yaml
@@ -33,3 +33,9 @@ cors:
   allow_credentials: true
 redis:
   url: redis://127.0.0.1:6379
+setup:
+  async_deactivation:
+    enabled: true
+    max_retries: 3
+    delay_ms: 200
+
diff --git a/internal/app/app.go b/internal/app/app.go
index 8cb4713e997049deb54d94fe29039dc9aaf15d37..3a7bcf4da8901152cd22a4ffc5281a909831e23e 100644
--- a/internal/app/app.go
+++ b/internal/app/app.go
@@ -61,7 +61,7 @@ func NewApp(conf *config.Config) *App {
 	ruleService := services.NewRuleService(ruleRepository, deviceService, logger)
 	setupService := services.NewSetupService(setupRepository, deviceService, ruleService, logger)
 	deviceControlService := services.NewDeviceControlService(setupService, deviceService, ruleService, conf.WatcherConfig, logger)
-	activeSetupService := services.NewActiveSetupService(setupService, deviceService, ruleService, deviceControlService, logger)
+	activeSetupService := services.NewActiveSetupService(setupService, deviceService, ruleService, deviceControlService, &conf.SetupConfig, logger)
 
 	err = activeSetupService.ReloadActiveSetup(ctx)
 	if err != nil {
diff --git a/internal/config/config.go b/internal/config/config.go
index 2acbc3f6bf14274db5e9bbda95522a300de25be7..015f247afa7020c4b928791b1baee6ec878fd139 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -31,6 +31,17 @@ type Config struct {
 	HTTPPort      int           `yaml:"http_port"`
 	DBPath        string        `yaml:"db_path"`
 	RedisConfig   RedisConfig   `yaml:"redis"`
+	SetupConfig   SetupConfig   `yaml:"setup"`
+}
+
+type SetupConfig struct {
+	SetupDeactivateConfig SetupDeactivateConfig `yaml:"async_deactivation"`
+}
+
+type SetupDeactivateConfig struct {
+	Enabled          bool `yaml:"enabled"`
+	MaxRetries       int  `yaml:"max_retries"`
+	DelayMillisecond int  `yaml:"delay_ms"`
 }
 
 func NewConfig(path string) (*Config, error) {
diff --git a/internal/services/active_setup_service.go b/internal/services/active_setup_service.go
index bfaa44f5b81b37c535222ee7b4c342a24612aa2e..cb12fa942d8d438d3762c47dbceb0daad1218343 100644
--- a/internal/services/active_setup_service.go
+++ b/internal/services/active_setup_service.go
@@ -4,9 +4,13 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"git.miem.hse.ru/hubman/configurator/internal/config"
 	"git.miem.hse.ru/hubman/configurator/internal/entity"
 	"git.miem.hse.ru/hubman/configurator/pkg/errs"
+	hubapi "git.miem.hse.ru/hubman/hubman-lib/api"
+	"github.com/google/uuid"
 	"go.uber.org/zap"
+	"time"
 )
 
 type ActiveSetupService struct {
@@ -14,6 +18,7 @@ type ActiveSetupService struct {
 	deviceService        *DeviceService
 	ruleService          *RuleService
 	deviceControlService *DeviceControlService
+	setupConfig          *config.SetupConfig
 	log                  *zap.Logger
 }
 
@@ -22,6 +27,7 @@ func NewActiveSetupService(
 	deviceService *DeviceService,
 	ruleService *RuleService,
 	deviceControlService *DeviceControlService,
+	setupConfig *config.SetupConfig,
 	log *zap.Logger,
 ) *ActiveSetupService {
 	return &ActiveSetupService{
@@ -29,6 +35,7 @@ func NewActiveSetupService(
 		deviceService:        deviceService,
 		ruleService:          ruleService,
 		deviceControlService: deviceControlService,
+		setupConfig:          setupConfig,
 		log:                  log,
 	}
 }
@@ -66,7 +73,19 @@ func (s *ActiveSetupService) ClearSetup(ctx context.Context, id int) error {
 		return err
 	}
 	err = s.deviceService.DeleteBySetupId(ctx, id)
-	return err
+	if err != nil {
+		return err
+	}
+
+	devices, err := s.deviceService.GetList(ctx, id)
+	if err != nil {
+		return err
+	}
+
+	if s.setupConfig.SetupDeactivateConfig.Enabled {
+		go s.clearDevicesRulesBindings(context.Background(), id, devices)
+	}
+	return nil
 }
 
 func (s *ActiveSetupService) DeleteDevice(ctx context.Context, setupId, deviceId int) error {
@@ -144,6 +163,15 @@ func (s *ActiveSetupService) DeactivateSetup(ctx context.Context, setupId int) (
 	if err != nil {
 		return nil, err
 	}
+	devices, err := s.deviceService.GetList(ctx, setupId)
+	if err != nil {
+		return nil, err
+	}
+
+	if s.setupConfig.SetupDeactivateConfig.Enabled {
+		go s.clearDevicesRulesBindings(context.Background(), setupId, devices)
+	}
+
 	err = s.ReloadActiveSetup(ctx)
 	if err != nil {
 		return nil, err
@@ -237,3 +265,79 @@ func (s *ActiveSetupService) Export(ctx context.Context, id int) (*entity.Export
 		Rules:   rules,
 	}, nil
 }
+
+func (s *ActiveSetupService) clearDevicesRulesBindings(ctx context.Context, setupId int, devices []*entity.Device) {
+	var err error
+
+	for _, dev := range devices {
+		nowTries := 0
+		for nowTries <= s.setupConfig.SetupDeactivateConfig.MaxRetries {
+			err = s.clearDevice(ctx, setupId, dev)
+			if err == nil {
+				break
+			}
+			nowTries++
+			time.Sleep(time.Duration(s.setupConfig.SetupDeactivateConfig.DelayMillisecond) * time.Millisecond)
+		}
+		if nowTries > s.setupConfig.SetupDeactivateConfig.MaxRetries {
+			s.log.Warn("max retries for clearing device exceeded", zap.Int("device_id", dev.Id), zap.Error(err))
+		}
+	}
+}
+
+func (s *ActiveSetupService) clearDevice(ctx context.Context, setupId int, dev *entity.Device) error {
+	client, err := s.deviceService.getClient(ctx, dev)
+	if err != nil {
+		s.log.Warn("can not get client for device", zap.Int("device_id", dev.Id), zap.Error(err))
+		return err
+	}
+
+	if dev.IsExecutor {
+		err = s.clearDeviceBindings(ctx, setupId, dev, client)
+		if err != nil {
+			s.log.Warn("error while clearing device bindings", zap.Error(err))
+			return err
+		}
+	}
+
+	if dev.IsManipulator {
+		err = s.clearDeviceRules(ctx, setupId, dev, client)
+		if err != nil {
+			s.log.Warn("error while clearing device rules", zap.Error(err))
+			return err
+		}
+	}
+	return nil
+}
+
+func (s *ActiveSetupService) clearDeviceBindings(ctx context.Context, setupId int, device *entity.Device, deviceClient *hubapi.ClientWithResponses) error {
+	newRequestId := uuid.New()
+
+	s.log.Info("try to put empty bindings to device", zap.Int("device_id", device.Id))
+	_, err := deviceClient.PutBindings(ctx, &hubapi.PutBindingsParams{XRequestID: &newRequestId}, []hubapi.Binding{})
+	if err != nil {
+		s.log.Warn("can not set empty bindings to device", zap.Int("device_id", device.Id))
+		return err
+	}
+
+	_, err = s.deviceService.Update(ctx, setupId, device.Id, &entity.UpdDevice{
+		BindingsRequestId: &newRequestId,
+	})
+	return err
+}
+
+func (s *ActiveSetupService) clearDeviceRules(ctx context.Context, setupId int, device *entity.Device, deviceClient *hubapi.ClientWithResponses) error {
+	newRequestId := uuid.New()
+
+	s.log.Info("try to put empty rules to device", zap.Int("device_id", device.Id))
+	_, err := deviceClient.PutRules(ctx, &hubapi.PutRulesParams{XRequestID: &newRequestId}, []hubapi.DeviceRule{})
+	if err != nil {
+		s.log.Warn("can not set empty rules to device", zap.Int("device_id", device.Id))
+		return err
+	}
+
+	_, err = s.deviceService.Update(ctx, setupId, device.Id, &entity.UpdDevice{
+		RulesRequestId: &newRequestId,
+	})
+	return err
+}