diff --git a/CHANGELOG.md b/CHANGELOG.md
index ced0633cdc..42d5b8978f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,8 +17,9 @@ Please mark all change in change log and use the ticket from JIRA.
 ## Feature
 - \#12 - Pure CPU version for Milvus
 - \#77 - Support table partition
-- \#226 - Experimental shards middleware for Milvus
 - \#127 - Support new Index type IVFPQ
+- \#226 - Experimental shards middleware for Milvus
+- \#346 - Support build index with multiple gpu
 
 ## Improvement
 - \#275 - Rename C++ SDK IndexType
diff --git a/core/conf/server_cpu_config.template b/core/conf/server_cpu_config.template
index 6c95126390..1a384f19a1 100644
--- a/core/conf/server_cpu_config.template
+++ b/core/conf/server_cpu_config.template
@@ -27,9 +27,7 @@ metric_config:
     port: 8080                      # port prometheus uses to fetch metrics, must in range [1025, 65534]
 
 cache_config:
-
-  cpu_cache_capacity: 16            # GB, CPU memory used for cache, must be a positive integer
-  cpu_cache_threshold: 0.85         # percentage of data that will be kept when cache cleanup is triggered, must be in range (0.0, 1.0]
+  cpu_cache_capacity: 16            # GB, size of CPU memory used for cache, must be a positive integer
   cache_insert_data: false          # whether to load inserted data into cache, must be a boolean
 
 engine_config:
@@ -37,7 +35,10 @@ engine_config:
                                     # if nq >= use_blas_threshold, use OpenBlas, slower with stable response times
   gpu_search_threshold: 1000        # threshold beyond which the search computation is executed on GPUs only
 
-resource_config:
-  search_resources:                 # define the device used for search computation
-    - cpu
-  index_build_device: cpu           # CPU used for building index
+gpu_resource_config:
+  enable_gpu: false                 # whether to enable GPU resources
+  cache_capacity: 4                 # GB, size of GPU memory per card used for cache, must be a positive integer
+  search_resources:                 # define the GPU devices used for search computation, must be in format gpux
+    - gpu0
+  build_index_resources:            # define the GPU devices used for index building, must be in format gpux
+    - gpu0
diff --git a/core/conf/server_gpu_config.template b/core/conf/server_gpu_config.template
index 154db5d134..9790c93491 100644
--- a/core/conf/server_gpu_config.template
+++ b/core/conf/server_gpu_config.template
@@ -27,10 +27,7 @@ metric_config:
     port: 8080                      # port prometheus uses to fetch metrics, must in range [1025, 65534]
 
 cache_config:
-  cpu_cache_capacity: 16            # GB, CPU memory used for cache, must be a positive integer
-  cpu_cache_threshold: 0.85         # percentage of data that will be kept when cache cleanup is triggered, must be in range (0.0, 1.0]
-  gpu_cache_capacity: 4             # GB, GPU memory used for cache, must be a positive integer
-  gpu_cache_threshold: 0.85         # percentage of data that will be kept when cache cleanup is triggered, must be in range (0.0, 1.0]
+  cpu_cache_capacity: 16            # GB, size of CPU memory used for cache, must be a positive integer
   cache_insert_data: false          # whether to load inserted data into cache, must be a boolean
 
 engine_config:
@@ -38,8 +35,10 @@ engine_config:
                                     # if nq >= use_blas_threshold, use OpenBlas, slower with stable response times
   gpu_search_threshold: 1000        # threshold beyond which the search computation is executed on GPUs only
 
-resource_config:
-  search_resources:                 # define the devices used for search computation, must be in format: cpu or gpux
-    - cpu
+gpu_resource_config:
+  enable_gpu: true                  # whether to enable GPU resources
+  cache_capacity: 4                 # GB, size of GPU memory per card used for cache, must be a positive integer
+  search_resources:                 # define the GPU devices used for search computation, must be in format gpux
+    - gpu0
+  build_index_resources:            # define the GPU devices used for index building, must be in format gpux
     - gpu0
-  index_build_device: gpu0          # CPU / GPU used for building index, must be in format: cpu or gpux
diff --git a/core/src/cache/GpuCacheMgr.cpp b/core/src/cache/GpuCacheMgr.cpp
index d862bc0393..72229527fa 100644
--- a/core/src/cache/GpuCacheMgr.cpp
+++ b/core/src/cache/GpuCacheMgr.cpp
@@ -37,7 +37,7 @@ GpuCacheMgr::GpuCacheMgr() {
     Status s;
 
     int64_t gpu_cache_cap;
-    s = config.GetCacheConfigGpuCacheCapacity(gpu_cache_cap);
+    s = config.GetGpuResourceConfigCacheCapacity(gpu_cache_cap);
     if (!s.ok()) {
         SERVER_LOG_ERROR << s.message();
     }
@@ -45,7 +45,7 @@ GpuCacheMgr::GpuCacheMgr() {
     cache_ = std::make_shared<Cache<DataObjPtr>>(cap, 1UL << 32);
 
     float gpu_mem_threshold;
-    s = config.GetCacheConfigGpuCacheThreshold(gpu_mem_threshold);
+    s = config.GetGpuResourceConfigCacheThreshold(gpu_mem_threshold);
     if (!s.ok()) {
         SERVER_LOG_ERROR << s.message();
     }
diff --git a/core/src/db/engine/ExecutionEngineImpl.cpp b/core/src/db/engine/ExecutionEngineImpl.cpp
index 3a2b940cec..4f2f542254 100644
--- a/core/src/db/engine/ExecutionEngineImpl.cpp
+++ b/core/src/db/engine/ExecutionEngineImpl.cpp
@@ -144,7 +144,14 @@ ExecutionEngineImpl::HybridLoad() const {
     }
 
     const std::string key = location_ + ".quantizer";
-    std::vector<uint64_t> gpus = scheduler::get_gpu_pool();
+
+    server::Config& config = server::Config::GetInstance();
+    std::vector<int32_t> gpus;
+    Status s = config.GetGpuResourceConfigSearchResources(gpus);
+    if (!s.ok()) {
+        ENGINE_LOG_ERROR << s.message();
+        return;
+    }
 
     // cache hit
     {
@@ -355,6 +362,7 @@ ExecutionEngineImpl::CopyToGpu(uint64_t device_id, bool hybrid) {
 
 Status
 ExecutionEngineImpl::CopyToIndexFileToGpu(uint64_t device_id) {
+    gpu_num_ = device_id;
     auto to_index_data = std::make_shared<ToIndexData>(PhysicalSize());
     cache::DataObjPtr obj = std::static_pointer_cast<cache::DataObj>(to_index_data);
     milvus::cache::GpuCacheMgr::GetInstance(device_id)->InsertItem(location_, obj);
@@ -578,12 +586,16 @@ ExecutionEngineImpl::GpuCache(uint64_t gpu_id) {
 Status
 ExecutionEngineImpl::Init() {
     server::Config& config = server::Config::GetInstance();
-    Status s = config.GetResourceConfigIndexBuildDevice(gpu_num_);
-    if (!s.ok()) {
-        return s;
+    std::vector<int32_t> gpu_ids;
+    Status s = config.GetGpuResourceConfigBuildIndexResources(gpu_ids);
+    for (auto id : gpu_ids) {
+        if (gpu_num_ == id) {
+            return Status::OK();
+        }
     }
 
-    return Status::OK();
+    std::string msg = "Invalid gpu_num";
+    return Status(SERVER_INVALID_ARGUMENT, msg);
 }
 
 }  // namespace engine
diff --git a/core/src/scheduler/JobMgr.cpp b/core/src/scheduler/JobMgr.cpp
index 794f6a0f37..8dd095a3fa 100644
--- a/core/src/scheduler/JobMgr.cpp
+++ b/core/src/scheduler/JobMgr.cpp
@@ -104,7 +104,7 @@ JobMgr::build_task(const JobPtr& job) {
 
 void
 JobMgr::calculate_path(const TaskPtr& task) {
-    if (task->type_ != TaskType::SearchTask) {
+    if (task->type_ != TaskType::SearchTask && task->type_ != TaskType::BuildIndexTask) {
         return;
     }
 
diff --git a/core/src/scheduler/SchedInst.cpp b/core/src/scheduler/SchedInst.cpp
index 9bd4df944f..867052ef5d 100644
--- a/core/src/scheduler/SchedInst.cpp
+++ b/core/src/scheduler/SchedInst.cpp
@@ -45,18 +45,6 @@ std::mutex BuildMgrInst::mutex_;
 
 void
 load_simple_config() {
-    server::Config& config = server::Config::GetInstance();
-    std::string mode;
-    config.GetResourceConfigMode(mode);
-    std::vector<std::string> pool;
-    config.GetResourceConfigSearchResources(pool);
-
-    // get resources
-    auto gpu_ids = get_gpu_pool();
-
-    int32_t build_gpu_id;
-    config.GetResourceConfigIndexBuildDevice(build_gpu_id);
-
     // create and connect
     ResMgrInst::GetInstance()->Add(ResourceFactory::Create("disk", "DISK", 0, true, false));
 
@@ -64,21 +52,40 @@ load_simple_config() {
     ResMgrInst::GetInstance()->Add(ResourceFactory::Create("cpu", "CPU", 0, true, true));
     ResMgrInst::GetInstance()->Connect("disk", "cpu", io);
 
+    // get resources
+#ifdef MILVUS_GPU_VERSION
+    server::Config& config = server::Config::GetInstance();
+    std::vector<int32_t> gpu_ids;
+    config.GetGpuResourceConfigSearchResources(gpu_ids);
+    std::vector<int32_t> build_gpu_ids;
+    config.GetGpuResourceConfigBuildIndexResources(build_gpu_ids);
     auto pcie = Connection("pcie", 12000);
-    bool find_build_gpu_id = false;
-    for (auto& gpu_id : gpu_ids) {
-        ResMgrInst::GetInstance()->Add(ResourceFactory::Create(std::to_string(gpu_id), "GPU", gpu_id, true, true));
-        ResMgrInst::GetInstance()->Connect("cpu", std::to_string(gpu_id), pcie);
-        if (build_gpu_id == gpu_id) {
-            find_build_gpu_id = true;
+
+    std::vector<int64_t> not_find_build_ids;
+    for (auto& build_id : build_gpu_ids) {
+        bool find_gpu_id = false;
+        for (auto& gpu_id : gpu_ids) {
+            if (gpu_id == build_id) {
+                find_gpu_id = true;
+                break;
+            }
+        }
+        if (not find_gpu_id) {
+            not_find_build_ids.emplace_back(build_id);
         }
     }
 
-    if (not find_build_gpu_id) {
-        ResMgrInst::GetInstance()->Add(
-            ResourceFactory::Create(std::to_string(build_gpu_id), "GPU", build_gpu_id, true, true));
-        ResMgrInst::GetInstance()->Connect("cpu", std::to_string(build_gpu_id), pcie);
+    for (auto& gpu_id : gpu_ids) {
+        ResMgrInst::GetInstance()->Add(ResourceFactory::Create(std::to_string(gpu_id), "GPU", gpu_id, true, true));
+        ResMgrInst::GetInstance()->Connect("cpu", std::to_string(gpu_id), pcie);
     }
+
+    for (auto& not_find_id : not_find_build_ids) {
+        ResMgrInst::GetInstance()->Add(
+            ResourceFactory::Create(std::to_string(not_find_id), "GPU", not_find_id, true, true));
+        ResMgrInst::GetInstance()->Connect("cpu", std::to_string(not_find_id), pcie);
+    }
+#endif
 }
 
 void
diff --git a/core/src/scheduler/SchedInst.h b/core/src/scheduler/SchedInst.h
index ad02d32081..44fea1b6d3 100644
--- a/core/src/scheduler/SchedInst.h
+++ b/core/src/scheduler/SchedInst.h
@@ -21,11 +21,12 @@
 #include "JobMgr.h"
 #include "ResourceMgr.h"
 #include "Scheduler.h"
+#include "Utils.h"
+#include "optimizer/BuildIndexPass.h"
 #include "optimizer/FallbackPass.h"
 #include "optimizer/HybridPass.h"
 #include "optimizer/LargeSQ8HPass.h"
 #include "optimizer/OnlyCPUPass.h"
-#include "optimizer/OnlyGPUPass.h"
 #include "optimizer/Optimizer.h"
 #include "server/Config.h"
 
@@ -98,21 +99,17 @@ class OptimizerInst {
         if (instance == nullptr) {
             std::lock_guard<std::mutex> lock(mutex_);
             if (instance == nullptr) {
-                server::Config& config = server::Config::GetInstance();
-                std::vector<std::string> search_resources;
-                bool has_cpu = false;
-                config.GetResourceConfigSearchResources(search_resources);
-                for (auto& resource : search_resources) {
-                    if (resource == "cpu") {
-                        has_cpu = true;
-                    }
-                }
-
                 std::vector<PassPtr> pass_list;
                 pass_list.push_back(std::make_shared<LargeSQ8HPass>());
                 pass_list.push_back(std::make_shared<HybridPass>());
+#ifdef MILVUS_CPU_VERSION
                 pass_list.push_back(std::make_shared<OnlyCPUPass>());
-                pass_list.push_back(std::make_shared<OnlyGPUPass>(has_cpu));
+#else
+                server::Config& config = server::Config::GetInstance();
+                std::vector<int32_t> build_resources;
+                config.GetGpuResourceConfigBuildIndexResources(build_resources);
+                pass_list.push_back(std::make_shared<BuildIndexPass>(build_resources));
+#endif
                 pass_list.push_back(std::make_shared<FallbackPass>());
                 instance = std::make_shared<Optimizer>(pass_list);
             }
diff --git a/core/src/scheduler/TaskCreator.cpp b/core/src/scheduler/TaskCreator.cpp
index 40cfa9aac6..3b7f6fd82e 100644
--- a/core/src/scheduler/TaskCreator.cpp
+++ b/core/src/scheduler/TaskCreator.cpp
@@ -70,8 +70,7 @@ TaskCreator::Create(const DeleteJobPtr& job) {
 std::vector<TaskPtr>
 TaskCreator::Create(const BuildIndexJobPtr& job) {
     std::vector<TaskPtr> tasks;
-    // TODO(yukun): remove "disk" hardcode here
-    ResourcePtr res_ptr = ResMgrInst::GetInstance()->GetResource("disk");
+    ResourcePtr res_ptr = ResMgrInst::GetInstance()->GetResource("cpu");
 
     for (auto& to_index_file : job->to_index_files()) {
         auto label = std::make_shared<SpecResLabel>(std::weak_ptr<Resource>(res_ptr));
diff --git a/core/src/scheduler/Utils.cpp b/core/src/scheduler/Utils.cpp
index 2fd573e47a..1be04ba80b 100644
--- a/core/src/scheduler/Utils.cpp
+++ b/core/src/scheduler/Utils.cpp
@@ -17,7 +17,6 @@
 
 #include "scheduler/Utils.h"
 #include "server/Config.h"
-#include "utils/Log.h"
 
 #ifdef MILVUS_GPU_VERSION
 #include <cuda_runtime.h>
@@ -46,42 +45,5 @@ get_num_gpu() {
     return n_devices;
 }
 
-std::vector<uint64_t>
-get_gpu_pool() {
-    std::vector<uint64_t> gpu_pool;
-
-    server::Config& config = server::Config::GetInstance();
-    std::vector<std::string> pool;
-    Status s = config.GetResourceConfigSearchResources(pool);
-    if (!s.ok()) {
-        SERVER_LOG_ERROR << s.message();
-    }
-
-    std::set<uint64_t> gpu_ids;
-
-    for (auto& resource : pool) {
-        if (resource == "cpu") {
-            continue;
-        } else {
-            if (resource.length() < 4 || resource.substr(0, 3) != "gpu") {
-                // error
-                exit(-1);
-            }
-            auto gpu_id = std::stoi(resource.substr(3));
-            if (gpu_id >= scheduler::get_num_gpu()) {
-                // error
-                exit(-1);
-            }
-            gpu_ids.insert(gpu_id);
-        }
-    }
-
-    for (auto& gpu_id : gpu_ids) {
-        gpu_pool.push_back(gpu_id);
-    }
-
-    return gpu_pool;
-}
-
 }  // namespace scheduler
 }  // namespace milvus
diff --git a/core/src/scheduler/Utils.h b/core/src/scheduler/Utils.h
index 24876eeb96..bf88cf0345 100644
--- a/core/src/scheduler/Utils.h
+++ b/core/src/scheduler/Utils.h
@@ -27,8 +27,5 @@ get_current_timestamp();
 uint64_t
 get_num_gpu();
 
-std::vector<uint64_t>
-get_gpu_pool();
-
 }  // namespace scheduler
 }  // namespace milvus
diff --git a/core/src/scheduler/action/PushTaskToNeighbour.cpp b/core/src/scheduler/action/PushTaskToNeighbour.cpp
index b8a4a1164b..9aed678937 100644
--- a/core/src/scheduler/action/PushTaskToNeighbour.cpp
+++ b/core/src/scheduler/action/PushTaskToNeighbour.cpp
@@ -138,73 +138,41 @@ Action::SpecifiedResourceLabelTaskScheduler(const ResourceMgrPtr& res_mgr, Resou
                                             std::shared_ptr<LoadCompletedEvent> event) {
     auto task_item = event->task_table_item_;
     auto task = event->task_table_item_->task;
-    if (resource->type() == ResourceType::DISK) {
-        // step 1: calculate shortest path per resource, from disk to compute resource
-        auto compute_resources = res_mgr->GetComputeResources();
-        std::vector<std::vector<std::string>> paths;
-        std::vector<uint64_t> transport_costs;
-        for (auto& res : compute_resources) {
-            std::vector<std::string> path;
-            uint64_t transport_cost = ShortestPath(resource, res, res_mgr, path);
-            transport_costs.push_back(transport_cost);
-            paths.emplace_back(path);
-        }
-        //        if (task->job_.lock()->type() == JobType::SEARCH) {
-        //            auto label = task->label();
-        //            auto spec_label = std::static_pointer_cast<SpecResLabel>(label);
-        //            if (spec_label->resource().lock()->type() == ResourceType::CPU) {
-        //                std::vector<std::string> spec_path;
-        //                spec_path.push_back(spec_label->resource().lock()->name());
-        //                spec_path.push_back(resource->name());
-        //                task->path() = Path(spec_path, spec_path.size() - 1);
-        //            } else {
-        //                // step 2: select min cost, cost(resource) = avg_cost * task_to_do + transport_cost
-        //                uint64_t min_cost = std::numeric_limits<uint64_t>::max();
-        //                uint64_t min_cost_idx = 0;
-        //                for (uint64_t i = 0; i < compute_resources.size(); ++i) {
-        //                    if (compute_resources[i]->TotalTasks() == 0) {
-        //                        min_cost_idx = i;
-        //                        break;
-        //                    }
-        //                    uint64_t cost = compute_resources[i]->TaskAvgCost() *
-        //                    compute_resources[i]->NumOfTaskToExec() +
-        //                                    transport_costs[i];
-        //                    if (min_cost > cost) {
-        //                        min_cost = cost;
-        //                        min_cost_idx = i;
-        //                    }
-        //                }
-        //
-        //                // step 3: set path in task
-        //                Path task_path(paths[min_cost_idx], paths[min_cost_idx].size() - 1);
-        //                task->path() = task_path;
-        //            }
-        //
-        //        } else
-        if (task->job_.lock()->type() == JobType::BUILD) {
-            // step2: Read device id in config
-            // get build index gpu resource
-            server::Config& config = server::Config::GetInstance();
-            int32_t build_index_gpu;
-            Status stat = config.GetResourceConfigIndexBuildDevice(build_index_gpu);
-
-            bool find_gpu_res = false;
-            if (res_mgr->GetResource(ResourceType::GPU, build_index_gpu) != nullptr) {
-                for (uint64_t i = 0; i < compute_resources.size(); ++i) {
-                    if (compute_resources[i]->name() ==
-                        res_mgr->GetResource(ResourceType::GPU, build_index_gpu)->name()) {
-                        find_gpu_res = true;
-                        Path task_path(paths[i], paths[i].size() - 1);
-                        task->path() = task_path;
-                        break;
-                    }
-                }
-            }
-            if (not find_gpu_res) {
-                task->path() = Path(paths[0], paths[0].size() - 1);
-            }
-        }
-    }
+    //    if (resource->type() == ResourceType::DISK) {
+    //        // step 1: calculate shortest path per resource, from disk to compute resource
+    //        auto compute_resources = res_mgr->GetComputeResources();
+    //        std::vector<std::vector<std::string>> paths;
+    //        std::vector<uint64_t> transport_costs;
+    //        for (auto& res : compute_resources) {
+    //            std::vector<std::string> path;
+    //            uint64_t transport_cost = ShortestPath(resource, res, res_mgr, path);
+    //            transport_costs.push_back(transport_cost);
+    //            paths.emplace_back(path);
+    //        }
+    //        if (task->job_.lock()->type() == JobType::BUILD) {
+    //            // step2: Read device id in config
+    //            // get build index gpu resource
+    //            server::Config& config = server::Config::GetInstance();
+    //            int32_t build_index_gpu;
+    //            Status stat = config.GetResourceConfigIndexBuildDevice(build_index_gpu);
+    //
+    //            bool find_gpu_res = false;
+    //            if (res_mgr->GetResource(ResourceType::GPU, build_index_gpu) != nullptr) {
+    //                for (uint64_t i = 0; i < compute_resources.size(); ++i) {
+    //                    if (compute_resources[i]->name() ==
+    //                        res_mgr->GetResource(ResourceType::GPU, build_index_gpu)->name()) {
+    //                        find_gpu_res = true;
+    //                        Path task_path(paths[i], paths[i].size() - 1);
+    //                        task->path() = task_path;
+    //                        break;
+    //                    }
+    //                }
+    //            }
+    //            if (not find_gpu_res) {
+    //                task->path() = Path(paths[0], paths[0].size() - 1);
+    //            }
+    //        }
+    //    }
 
     if (resource->name() == task->path().Last()) {
         resource->WakeupExecutor();
diff --git a/core/src/scheduler/optimizer/OnlyGPUPass.cpp b/core/src/scheduler/optimizer/BuildIndexPass.cpp
similarity index 58%
rename from core/src/scheduler/optimizer/OnlyGPUPass.cpp
rename to core/src/scheduler/optimizer/BuildIndexPass.cpp
index 69a8366bb2..4e7d5222e2 100644
--- a/core/src/scheduler/optimizer/OnlyGPUPass.cpp
+++ b/core/src/scheduler/optimizer/BuildIndexPass.cpp
@@ -15,43 +15,35 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#include "scheduler/optimizer/OnlyGPUPass.h"
+#include "scheduler/optimizer/BuildIndexPass.h"
 #include "scheduler/SchedInst.h"
 #include "scheduler/Utils.h"
-#include "scheduler/task/SearchTask.h"
 #include "scheduler/tasklabel/SpecResLabel.h"
 
 namespace milvus {
 namespace scheduler {
 
-OnlyGPUPass::OnlyGPUPass(bool has_cpu) : has_cpu_(has_cpu) {
+BuildIndexPass::BuildIndexPass(std::vector<int32_t>& build_gpu_ids) : build_gpu_ids_(build_gpu_ids) {
 }
 
 void
-OnlyGPUPass::Init() {
+BuildIndexPass::Init() {
 }
 
 bool
-OnlyGPUPass::Run(const TaskPtr& task) {
-    if (task->Type() != TaskType::SearchTask || has_cpu_)
+BuildIndexPass::Run(const TaskPtr& task) {
+    if (task->Type() != TaskType::BuildIndexTask)
         return false;
 
-    auto search_task = std::static_pointer_cast<XSearchTask>(task);
-    if (search_task->file_->engine_type_ != (int)engine::EngineType::FAISS_IVFSQ8 &&
-        search_task->file_->engine_type_ != (int)engine::EngineType::FAISS_IVFFLAT &&
-        search_task->file_->engine_type_ != (int)engine::EngineType::FAISS_IDMAP) {
-        return false;
-    }
-
-    auto gpu_id = get_gpu_pool();
-    if (gpu_id.empty())
+    if (build_gpu_ids_.empty())
         return false;
 
-    ResourcePtr res_ptr = ResMgrInst::GetInstance()->GetResource(ResourceType::GPU, gpu_id[specified_gpu_id_]);
+    ResourcePtr res_ptr;
+    res_ptr = ResMgrInst::GetInstance()->GetResource(ResourceType::GPU, build_gpu_ids_[specified_gpu_id_]);
     auto label = std::make_shared<SpecResLabel>(std::weak_ptr<Resource>(res_ptr));
     task->label() = label;
 
-    specified_gpu_id_ = specified_gpu_id_++ % gpu_id.size();
+    specified_gpu_id_ = (specified_gpu_id_ + 1) % build_gpu_ids_.size();
     return true;
 }
 
diff --git a/core/src/scheduler/optimizer/OnlyGPUPass.h b/core/src/scheduler/optimizer/BuildIndexPass.h
similarity index 86%
rename from core/src/scheduler/optimizer/OnlyGPUPass.h
rename to core/src/scheduler/optimizer/BuildIndexPass.h
index c7a83fea30..a3eb426527 100644
--- a/core/src/scheduler/optimizer/OnlyGPUPass.h
+++ b/core/src/scheduler/optimizer/BuildIndexPass.h
@@ -32,9 +32,9 @@
 namespace milvus {
 namespace scheduler {
 
-class OnlyGPUPass : public Pass {
+class BuildIndexPass : public Pass {
  public:
-    explicit OnlyGPUPass(bool has_cpu);
+    explicit BuildIndexPass(std::vector<int32_t>& build_gpu_id);
 
  public:
     void
@@ -45,10 +45,10 @@ class OnlyGPUPass : public Pass {
 
  private:
     uint64_t specified_gpu_id_ = 0;
-    bool has_cpu_ = false;
+    std::vector<int32_t> build_gpu_ids_;
 };
 
-using OnlyGPUPassPtr = std::shared_ptr<OnlyGPUPass>;
+using BuildIndexPassPtr = std::shared_ptr<BuildIndexPass>;
 
 }  // namespace scheduler
 }  // namespace milvus
diff --git a/core/src/scheduler/optimizer/LargeSQ8HPass.cpp b/core/src/scheduler/optimizer/LargeSQ8HPass.cpp
index 89bd85ec1f..dd58feb512 100644
--- a/core/src/scheduler/optimizer/LargeSQ8HPass.cpp
+++ b/core/src/scheduler/optimizer/LargeSQ8HPass.cpp
@@ -34,6 +34,7 @@ LargeSQ8HPass::Init() {
     if (!s.ok()) {
         threshold_ = std::numeric_limits<int32_t>::max();
     }
+    s = config.GetGpuResourceConfigSearchResources(gpus);
 }
 
 bool
@@ -55,7 +56,6 @@ LargeSQ8HPass::Run(const TaskPtr& task) {
         return false;
     }
 
-    std::vector<uint64_t> gpus = scheduler::get_gpu_pool();
     //    std::vector<int64_t> all_free_mem;
     //    for (auto& gpu : gpus) {
     //        auto cache = cache::GpuCacheMgr::GetInstance(gpu);
diff --git a/core/src/scheduler/optimizer/LargeSQ8HPass.h b/core/src/scheduler/optimizer/LargeSQ8HPass.h
index 1afd240c0f..c69fb12c64 100644
--- a/core/src/scheduler/optimizer/LargeSQ8HPass.h
+++ b/core/src/scheduler/optimizer/LargeSQ8HPass.h
@@ -47,6 +47,7 @@ class LargeSQ8HPass : public Pass {
  private:
     int32_t threshold_ = std::numeric_limits<int32_t>::max();
     int64_t count_ = 0;
+    std::vector<int32_t> gpus;
 };
 
 using LargeSQ8HPassPtr = std::shared_ptr<LargeSQ8HPass>;
diff --git a/core/src/scheduler/optimizer/OnlyCPUPass.cpp b/core/src/scheduler/optimizer/OnlyCPUPass.cpp
index 392ae7940b..8cd40092fb 100644
--- a/core/src/scheduler/optimizer/OnlyCPUPass.cpp
+++ b/core/src/scheduler/optimizer/OnlyCPUPass.cpp
@@ -38,10 +38,6 @@ OnlyCPUPass::Run(const TaskPtr& task) {
         return false;
     }
 
-    auto gpu_id = get_gpu_pool();
-    if (not gpu_id.empty())
-        return false;
-
     ResourcePtr res_ptr = ResMgrInst::GetInstance()->GetResource("cpu");
     auto label = std::make_shared<SpecResLabel>(std::weak_ptr<Resource>(res_ptr));
     task->label() = label;
diff --git a/core/src/server/Config.cpp b/core/src/server/Config.cpp
index f130e73a85..e3a48b6ae4 100644
--- a/core/src/server/Config.cpp
+++ b/core/src/server/Config.cpp
@@ -163,20 +163,6 @@ Config::ValidateConfig() {
         return s;
     }
 
-#ifdef MILVUS_GPU_VERSION
-    int64_t cache_gpu_cache_capacity;
-    s = GetCacheConfigGpuCacheCapacity(cache_gpu_cache_capacity);
-    if (!s.ok()) {
-        return s;
-    }
-
-    float cache_gpu_cache_threshold;
-    s = GetCacheConfigGpuCacheThreshold(cache_gpu_cache_threshold);
-    if (!s.ok()) {
-        return s;
-    }
-#endif
-
     bool cache_insert_data;
     s = GetCacheConfigCacheInsertData(cache_insert_data);
     if (!s.ok()) {
@@ -202,25 +188,39 @@ Config::ValidateConfig() {
         return s;
     }
 
-    /* resource config */
-    std::string resource_mode;
-    s = GetResourceConfigMode(resource_mode);
+    /* gpu resource config */
+#ifdef MILVUS_GPU_VERSION
+    bool resource_enable_gpu;
+    s = GetGpuResourceConfigEnableGpu(resource_enable_gpu);
     if (!s.ok()) {
         return s;
     }
 
-    std::vector<std::string> search_resources;
-    s = GetResourceConfigSearchResources(search_resources);
+    int64_t resource_cache_capacity;
+    s = GetGpuResourceConfigCacheCapacity(resource_cache_capacity);
     if (!s.ok()) {
         return s;
     }
 
-    int32_t resource_index_build_device;
-    s = GetResourceConfigIndexBuildDevice(resource_index_build_device);
+    float resource_cache_threshold;
+    s = GetGpuResourceConfigCacheThreshold(resource_cache_threshold);
     if (!s.ok()) {
         return s;
     }
 
+    std::vector<int32_t> search_resources;
+    s = GetGpuResourceConfigSearchResources(search_resources);
+    if (!s.ok()) {
+        return s;
+    }
+
+    std::vector<int32_t> index_build_resources;
+    s = GetGpuResourceConfigBuildIndexResources(index_build_resources);
+    if (!s.ok()) {
+        return s;
+    }
+#endif
+
     return Status::OK();
 }
 
@@ -307,18 +307,6 @@ Config::ResetDefaultConfig() {
         return s;
     }
 
-#ifdef MILVUS_GPU_VERSION
-    s = SetCacheConfigGpuCacheCapacity(CONFIG_CACHE_GPU_CACHE_CAPACITY_DEFAULT);
-    if (!s.ok()) {
-        return s;
-    }
-
-    s = SetCacheConfigGpuCacheThreshold(CONFIG_CACHE_GPU_CACHE_THRESHOLD_DEFAULT);
-    if (!s.ok()) {
-        return s;
-    }
-#endif
-
     s = SetCacheConfigCacheInsertData(CONFIG_CACHE_CACHE_INSERT_DATA_DEFAULT);
     if (!s.ok()) {
         return s;
@@ -340,22 +328,34 @@ Config::ResetDefaultConfig() {
         return s;
     }
 
-    /* resource config */
-    s = SetResourceConfigMode(CONFIG_RESOURCE_MODE_DEFAULT);
+    /* gpu resource config */
+#ifdef MILVUS_GPU_VERSION
+    s = SetGpuResourceConfigEnableGpu(CONFIG_GPU_RESOURCE_ENABLE_GPU_DEFAULT);
     if (!s.ok()) {
         return s;
     }
 
-    s = SetResourceConfigSearchResources(CONFIG_RESOURCE_SEARCH_RESOURCES_DEFAULT);
+    s = SetGpuResourceConfigCacheCapacity(CONFIG_GPU_RESOURCE_CACHE_CAPACITY_DEFAULT);
     if (!s.ok()) {
         return s;
     }
 
-    s = SetResourceConfigIndexBuildDevice(CONFIG_RESOURCE_INDEX_BUILD_DEVICE_DEFAULT);
+    s = SetGpuResourceConfigCacheThreshold(CONFIG_GPU_RESOURCE_CACHE_THRESHOLD_DEFAULT);
     if (!s.ok()) {
         return s;
     }
 
+    s = SetGpuResourceConfigSearchResources(CONFIG_GPU_RESOURCE_SEARCH_RESOURCES_DEFAULT);
+    if (!s.ok()) {
+        return s;
+    }
+
+    s = SetGpuResourceConfigBuildIndexResources(CONFIG_GPU_RESOURCE_BUILD_INDEX_RESOURCES_DEFAULT);
+    if (!s.ok()) {
+        return s;
+    }
+#endif
+
     return Status::OK();
 }
 
@@ -377,7 +377,7 @@ Config::PrintAll() {
     PrintConfigSection(CONFIG_CACHE);
     PrintConfigSection(CONFIG_METRIC);
     PrintConfigSection(CONFIG_ENGINE);
-    PrintConfigSection(CONFIG_RESOURCE);
+    PrintConfigSection(CONFIG_GPU_RESOURCE);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -591,52 +591,6 @@ Config::CheckCacheConfigCpuCacheThreshold(const std::string& value) {
     return Status::OK();
 }
 
-Status
-Config::CheckCacheConfigGpuCacheCapacity(const std::string& value) {
-    if (!ValidationUtil::ValidateStringIsNumber(value).ok()) {
-        std::string msg = "Invalid gpu cache capacity: " + value +
-                          ". Possible reason: cache_config.gpu_cache_capacity is not a positive integer.";
-        return Status(SERVER_INVALID_ARGUMENT, msg);
-    } else {
-        uint64_t gpu_cache_capacity = std::stoi(value) * GB;
-        int device_id;
-        Status s = GetResourceConfigIndexBuildDevice(device_id);
-        if (!s.ok()) {
-            return s;
-        }
-
-        size_t gpu_memory;
-        if (!ValidationUtil::GetGpuMemory(device_id, gpu_memory).ok()) {
-            std::string msg = "Fail to get GPU memory for GPU device: " + std::to_string(device_id);
-            return Status(SERVER_UNEXPECTED_ERROR, msg);
-        } else if (gpu_cache_capacity >= gpu_memory) {
-            std::string msg = "Invalid gpu cache capacity: " + value +
-                              ". Possible reason: cache_config.gpu_cache_capacity exceeds GPU memory.";
-            return Status(SERVER_INVALID_ARGUMENT, msg);
-        } else if (gpu_cache_capacity > (double)gpu_memory * 0.9) {
-            std::cerr << "Warning: gpu cache capacity value is too big" << std::endl;
-        }
-    }
-    return Status::OK();
-}
-
-Status
-Config::CheckCacheConfigGpuCacheThreshold(const std::string& value) {
-    if (!ValidationUtil::ValidateStringIsFloat(value).ok()) {
-        std::string msg = "Invalid gpu cache threshold: " + value +
-                          ". Possible reason: cache_config.gpu_cache_threshold is not in range (0.0, 1.0].";
-        return Status(SERVER_INVALID_ARGUMENT, msg);
-    } else {
-        float gpu_cache_threshold = std::stof(value);
-        if (gpu_cache_threshold <= 0.0 || gpu_cache_threshold >= 1.0) {
-            std::string msg = "Invalid gpu cache threshold: " + value +
-                              ". Possible reason: cache_config.gpu_cache_threshold is not in range (0.0, 1.0].";
-            return Status(SERVER_INVALID_ARGUMENT, msg);
-        }
-    }
-    return Status::OK();
-}
-
 Status
 Config::CheckCacheConfigCacheInsertData(const std::string& value) {
     if (!ValidationUtil::ValidateStringIsBool(value).ok()) {
@@ -687,56 +641,99 @@ Config::CheckEngineConfigGpuSearchThreshold(const std::string& value) {
 }
 
 Status
-Config::CheckResourceConfigMode(const std::string& value) {
-    if (value != "simple") {
-        std::string msg = "Invalid resource mode: " + value + ". Possible reason: resource_config.mode is invalid.";
+Config::CheckGpuResourceConfigEnableGpu(const std::string& value) {
+    if (!ValidationUtil::ValidateStringIsBool(value).ok()) {
+        std::string msg = "Invalid gpu resource config: " + value +
+                          ". Possible reason: gpu_resource_config.enable_gpu is not a boolean.";
         return Status(SERVER_INVALID_ARGUMENT, msg);
     }
     return Status::OK();
 }
 
 Status
-CheckResource(const std::string& value) {
+Config::CheckGpuResourceConfigCacheCapacity(const std::string& value) {
+    if (!ValidationUtil::ValidateStringIsNumber(value).ok()) {
+        std::string msg = "Invalid gpu cache capacity: " + value +
+                          ". Possible reason: gpu_resource_config.cache_capacity is not a positive integer.";
+        return Status(SERVER_INVALID_ARGUMENT, msg);
+    } else {
+        uint64_t gpu_cache_capacity = std::stoi(value) * GB;
+        std::vector<int32_t> gpu_ids;
+        Status s = GetGpuResourceConfigBuildIndexResources(gpu_ids);
+        if (!s.ok()) {
+            return s;
+        }
+
+        for (int32_t gpu_id : gpu_ids) {
+            size_t gpu_memory;
+            if (!ValidationUtil::GetGpuMemory(gpu_id, gpu_memory).ok()) {
+                std::string msg = "Fail to get GPU memory for GPU device: " + std::to_string(gpu_id);
+                return Status(SERVER_UNEXPECTED_ERROR, msg);
+            } else if (gpu_cache_capacity >= gpu_memory) {
+                std::string msg = "Invalid gpu cache capacity: " + value +
+                                  ". Possible reason: gpu_resource_config.cache_capacity exceeds GPU memory.";
+                return Status(SERVER_INVALID_ARGUMENT, msg);
+            } else if (gpu_cache_capacity > (double)gpu_memory * 0.9) {
+                std::cerr << "Warning: gpu cache capacity value is too big" << std::endl;
+            }
+        }
+    }
+    return Status::OK();
+}
+
+Status
+Config::CheckGpuResourceConfigCacheThreshold(const std::string& value) {
+    if (!ValidationUtil::ValidateStringIsFloat(value).ok()) {
+        std::string msg = "Invalid gpu cache threshold: " + value +
+                          ". Possible reason: gpu_resource_config.cache_threshold is not in range (0.0, 1.0].";
+        return Status(SERVER_INVALID_ARGUMENT, msg);
+    } else {
+        float gpu_cache_threshold = std::stof(value);
+        if (gpu_cache_threshold <= 0.0 || gpu_cache_threshold >= 1.0) {
+            std::string msg = "Invalid gpu cache threshold: " + value +
+                              ". Possible reason: gpu_resource_config.cache_threshold is not in range (0.0, 1.0].";
+            return Status(SERVER_INVALID_ARGUMENT, msg);
+        }
+    }
+    return Status::OK();
+}
+
+Status
+CheckGpuResource(const std::string& value) {
     std::string s = value;
     std::transform(s.begin(), s.end(), s.begin(), ::tolower);
 
-#ifdef MILVUS_CPU_VERSION
-    if (s != "cpu") {
-        return Status(SERVER_INVALID_ARGUMENT, "Invalid CPU resource: " + s);
-    }
-#else
-    const std::regex pat("cpu|gpu(\\d+)");
+    const std::regex pat("gpu(\\d+)");
     std::smatch m;
     if (!std::regex_match(s, m, pat)) {
-        std::string msg = "Invalid search resource: " + value +
-                          ". Possible reason: resource_config.search_resources is not in the format of cpux or gpux";
+        std::string msg = "Invalid gpu resource: " + value +
+                          ". Possible reason: gpu_resource_config is not in the format of cpux or gpux";
         return Status(SERVER_INVALID_ARGUMENT, msg);
     }
 
     if (s.compare(0, 3, "gpu") == 0) {
         int32_t gpu_index = std::stoi(s.substr(3));
         if (!ValidationUtil::ValidateGpuIndex(gpu_index).ok()) {
-            std::string msg = "Invalid search resource: " + value +
-                              ". Possible reason: resource_config.search_resources does not match your hardware.";
+            std::string msg = "Invalid gpu resource: " + value +
+                              ". Possible reason: gpu_resource_config does not match with the hardware.";
             return Status(SERVER_INVALID_ARGUMENT, msg);
         }
     }
-#endif
 
     return Status::OK();
 }
 
 Status
-Config::CheckResourceConfigSearchResources(const std::vector<std::string>& value) {
+Config::CheckGpuResourceConfigSearchResources(const std::vector<std::string>& value) {
     if (value.empty()) {
         std::string msg =
-            "Invalid search resource. "
-            "Possible reason: resource_config.search_resources is empty.";
+            "Invalid gpu search resource. "
+            "Possible reason: gpu_resource_config.search_resources is empty.";
         return Status(SERVER_INVALID_ARGUMENT, msg);
     }
 
     for (auto& resource : value) {
-        auto status = CheckResource(resource);
+        auto status = CheckGpuResource(resource);
         if (!status.ok()) {
             return Status(SERVER_INVALID_ARGUMENT, status.message());
         }
@@ -745,11 +742,21 @@ Config::CheckResourceConfigSearchResources(const std::vector<std::string>& value
 }
 
 Status
-Config::CheckResourceConfigIndexBuildDevice(const std::string& value) {
-    auto status = CheckResource(value);
-    if (!status.ok()) {
-        return Status(SERVER_INVALID_ARGUMENT, status.message());
+Config::CheckGpuResourceConfigBuildIndexResources(const std::vector<std::string>& value) {
+    if (value.empty()) {
+        std::string msg =
+            "Invalid gpu build index resource. "
+            "Possible reason: gpu_resource_config.build_index_resources is empty.";
+        return Status(SERVER_INVALID_ARGUMENT, msg);
     }
+
+    for (auto& resource : value) {
+        auto status = CheckGpuResource(resource);
+        if (!status.ok()) {
+            return Status(SERVER_INVALID_ARGUMENT, status.message());
+        }
+    }
+
     return Status::OK();
 }
 
@@ -855,7 +862,6 @@ Config::GetDBConfigArchiveDiskThreshold(int32_t& value) {
     if (!s.ok()) {
         return s;
     }
-
     value = std::stoi(str);
     return Status::OK();
 }
@@ -868,7 +874,6 @@ Config::GetDBConfigArchiveDaysThreshold(int32_t& value) {
     if (!s.ok()) {
         return s;
     }
-
     value = std::stoi(str);
     return Status::OK();
 }
@@ -880,7 +885,6 @@ Config::GetDBConfigInsertBufferSize(int32_t& value) {
     if (!s.ok()) {
         return s;
     }
-
     value = std::stoi(str);
     return Status::OK();
 }
@@ -898,7 +902,6 @@ Config::GetMetricConfigEnableMonitor(bool& value) {
     if (!s.ok()) {
         return s;
     }
-
     std::transform(str.begin(), str.end(), str.begin(), ::tolower);
     value = (str == "true" || str == "on" || str == "yes" || str == "1");
     return Status::OK();
@@ -924,7 +927,6 @@ Config::GetCacheConfigCpuCacheCapacity(int64_t& value) {
     if (!s.ok()) {
         return s;
     }
-
     value = std::stoi(str);
     return Status::OK();
 }
@@ -937,33 +939,6 @@ Config::GetCacheConfigCpuCacheThreshold(float& value) {
     if (!s.ok()) {
         return s;
     }
-
-    value = std::stof(str);
-    return Status::OK();
-}
-
-Status
-Config::GetCacheConfigGpuCacheCapacity(int64_t& value) {
-    std::string str =
-        GetConfigStr(CONFIG_CACHE, CONFIG_CACHE_GPU_CACHE_CAPACITY, CONFIG_CACHE_GPU_CACHE_CAPACITY_DEFAULT);
-    Status s = CheckCacheConfigGpuCacheCapacity(str);
-    if (!s.ok()) {
-        return s;
-    }
-
-    value = std::stoi(str);
-    return Status::OK();
-}
-
-Status
-Config::GetCacheConfigGpuCacheThreshold(float& value) {
-    std::string str =
-        GetConfigStr(CONFIG_CACHE, CONFIG_CACHE_GPU_CACHE_THRESHOLD, CONFIG_CACHE_GPU_CACHE_THRESHOLD_DEFAULT);
-    Status s = CheckCacheConfigGpuCacheThreshold(str);
-    if (!s.ok()) {
-        return s;
-    }
-
     value = std::stof(str);
     return Status::OK();
 }
@@ -976,7 +951,6 @@ Config::GetCacheConfigCacheInsertData(bool& value) {
     if (!s.ok()) {
         return s;
     }
-
     std::transform(str.begin(), str.end(), str.begin(), ::tolower);
     value = (str == "true" || str == "on" || str == "yes" || str == "1");
     return Status::OK();
@@ -990,7 +964,6 @@ Config::GetEngineConfigUseBlasThreshold(int32_t& value) {
     if (!s.ok()) {
         return s;
     }
-
     value = std::stoi(str);
     return Status::OK();
 }
@@ -1002,7 +975,6 @@ Config::GetEngineConfigOmpThreadNum(int32_t& value) {
     if (!s.ok()) {
         return s;
     }
-
     value = std::stoi(str);
     return Status::OK();
 }
@@ -1015,41 +987,113 @@ Config::GetEngineConfigGpuSearchThreshold(int32_t& value) {
     if (!s.ok()) {
         return s;
     }
-
     value = std::stoi(str);
     return Status::OK();
 }
 
 Status
-Config::GetResourceConfigMode(std::string& value) {
-    value = GetConfigStr(CONFIG_RESOURCE, CONFIG_RESOURCE_MODE, CONFIG_RESOURCE_MODE_DEFAULT);
-    return CheckResourceConfigMode(value);
-}
-
-Status
-Config::GetResourceConfigSearchResources(std::vector<std::string>& value) {
+Config::GetGpuResourceConfigEnableGpu(bool& value) {
     std::string str =
-        GetConfigSequenceStr(CONFIG_RESOURCE, CONFIG_RESOURCE_SEARCH_RESOURCES,
-                             CONFIG_RESOURCE_SEARCH_RESOURCES_DELIMITER, CONFIG_RESOURCE_SEARCH_RESOURCES_DEFAULT);
-    server::StringHelpFunctions::SplitStringByDelimeter(str, CONFIG_RESOURCE_SEARCH_RESOURCES_DELIMITER, value);
-    return CheckResourceConfigSearchResources(value);
-}
-
-Status
-Config::GetResourceConfigIndexBuildDevice(int32_t& value) {
-    std::string str =
-        GetConfigStr(CONFIG_RESOURCE, CONFIG_RESOURCE_INDEX_BUILD_DEVICE, CONFIG_RESOURCE_INDEX_BUILD_DEVICE_DEFAULT);
-    Status s = CheckResourceConfigIndexBuildDevice(str);
+        GetConfigStr(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_ENABLE_GPU, CONFIG_GPU_RESOURCE_ENABLE_GPU_DEFAULT);
+    Status s = CheckGpuResourceConfigEnableGpu(str);
     if (!s.ok()) {
         return s;
     }
+    std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+    value = (str == "true" || str == "on" || str == "yes" || str == "1");
+    return Status::OK();
+}
 
-    if (str == "cpu") {
-        value = CPU_DEVICE_ID;
-    } else {
-        value = std::stoi(str.substr(3));
+Status
+Config::GetGpuResourceConfigCacheCapacity(int64_t& value) {
+    bool enable_gpu = false;
+    Status s = GetGpuResourceConfigEnableGpu(enable_gpu);
+    if (!s.ok()) {
+        return s;
     }
+    if (!enable_gpu) {
+        std::string msg = "GPU not supported. Possible reason: gpu_resource_config.enable_gpu is set to false.";
+        return Status(SERVER_UNSUPPORTED_ERROR, msg);
+    }
+    std::string str = GetConfigStr(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_CACHE_CAPACITY,
+                                   CONFIG_GPU_RESOURCE_CACHE_CAPACITY_DEFAULT);
+    s = CheckGpuResourceConfigCacheCapacity(str);
+    if (!s.ok()) {
+        return s;
+    }
+    value = std::stoi(str);
+    return Status::OK();
+}
 
+Status
+Config::GetGpuResourceConfigCacheThreshold(float& value) {
+    bool enable_gpu = false;
+    Status s = GetGpuResourceConfigEnableGpu(enable_gpu);
+    if (!s.ok()) {
+        return s;
+    }
+    if (!enable_gpu) {
+        std::string msg = "GPU not supported. Possible reason: gpu_resource_config.enable_gpu is set to false.";
+        return Status(SERVER_UNSUPPORTED_ERROR, msg);
+    }
+    std::string str = GetConfigStr(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_CACHE_THRESHOLD,
+                                   CONFIG_GPU_RESOURCE_CACHE_THRESHOLD_DEFAULT);
+    s = CheckGpuResourceConfigCacheThreshold(str);
+    if (!s.ok()) {
+        return s;
+    }
+    value = std::stof(str);
+    return Status::OK();
+}
+
+Status
+Config::GetGpuResourceConfigSearchResources(std::vector<int32_t>& value) {
+    bool enable_gpu = false;
+    Status s = GetGpuResourceConfigEnableGpu(enable_gpu);
+    if (!s.ok()) {
+        return s;
+    }
+    if (!enable_gpu) {
+        std::string msg = "GPU not supported. Possible reason: gpu_resource_config.enable_gpu is set to false.";
+        return Status(SERVER_UNSUPPORTED_ERROR, msg);
+    }
+    std::string str = GetConfigSequenceStr(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_SEARCH_RESOURCES,
+                                           CONFIG_GPU_RESOURCE_DELIMITER, CONFIG_GPU_RESOURCE_SEARCH_RESOURCES_DEFAULT);
+    std::vector<std::string> res_vec;
+    server::StringHelpFunctions::SplitStringByDelimeter(str, CONFIG_GPU_RESOURCE_DELIMITER, res_vec);
+    s = CheckGpuResourceConfigSearchResources(res_vec);
+    if (!s.ok()) {
+        return s;
+    }
+    for (std::string& res : res_vec) {
+        value.push_back(std::stoi(res.substr(3)));
+    }
+    return Status::OK();
+}
+
+Status
+Config::GetGpuResourceConfigBuildIndexResources(std::vector<int32_t>& value) {
+    bool enable_gpu = false;
+    Status s = GetGpuResourceConfigEnableGpu(enable_gpu);
+    if (!s.ok()) {
+        return s;
+    }
+    if (!enable_gpu) {
+        std::string msg = "GPU not supported. Possible reason: gpu_resource_config.enable_gpu is set to false.";
+        return Status(SERVER_UNSUPPORTED_ERROR, msg);
+    }
+    std::string str =
+        GetConfigSequenceStr(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_BUILD_INDEX_RESOURCES,
+                             CONFIG_GPU_RESOURCE_DELIMITER, CONFIG_GPU_RESOURCE_BUILD_INDEX_RESOURCES_DEFAULT);
+    std::vector<std::string> res_vec;
+    server::StringHelpFunctions::SplitStringByDelimeter(str, CONFIG_GPU_RESOURCE_DELIMITER, res_vec);
+    s = CheckGpuResourceConfigBuildIndexResources(res_vec);
+    if (!s.ok()) {
+        return s;
+    }
+    for (std::string& res : res_vec) {
+        value.push_back(std::stoi(res.substr(3)));
+    }
     return Status::OK();
 }
 
@@ -1061,7 +1105,6 @@ Config::SetServerConfigAddress(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_ADDRESS, value);
     return Status::OK();
 }
@@ -1072,7 +1115,6 @@ Config::SetServerConfigPort(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_PORT, value);
     return Status::OK();
 }
@@ -1083,7 +1125,6 @@ Config::SetServerConfigDeployMode(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_DEPLOY_MODE, value);
     return Status::OK();
 }
@@ -1094,7 +1135,6 @@ Config::SetServerConfigTimeZone(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_TIME_ZONE, value);
     return Status::OK();
 }
@@ -1106,7 +1146,6 @@ Config::SetDBConfigPrimaryPath(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_DB, CONFIG_DB_PRIMARY_PATH, value);
     return Status::OK();
 }
@@ -1117,7 +1156,6 @@ Config::SetDBConfigSecondaryPath(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_DB, CONFIG_DB_SECONDARY_PATH, value);
     return Status::OK();
 }
@@ -1128,7 +1166,6 @@ Config::SetDBConfigBackendUrl(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_DB, CONFIG_DB_BACKEND_URL, value);
     return Status::OK();
 }
@@ -1139,7 +1176,6 @@ Config::SetDBConfigArchiveDiskThreshold(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_DB, CONFIG_DB_ARCHIVE_DISK_THRESHOLD, value);
     return Status::OK();
 }
@@ -1150,7 +1186,6 @@ Config::SetDBConfigArchiveDaysThreshold(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_DB, CONFIG_DB_ARCHIVE_DAYS_THRESHOLD, value);
     return Status::OK();
 }
@@ -1161,7 +1196,6 @@ Config::SetDBConfigInsertBufferSize(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_DB, CONFIG_DB_INSERT_BUFFER_SIZE, value);
     return Status::OK();
 }
@@ -1173,7 +1207,6 @@ Config::SetMetricConfigEnableMonitor(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_ENABLE_MONITOR, value);
     return Status::OK();
 }
@@ -1184,7 +1217,6 @@ Config::SetMetricConfigCollector(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_COLLECTOR, value);
     return Status::OK();
 }
@@ -1195,7 +1227,6 @@ Config::SetMetricConfigPrometheusPort(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_PROMETHEUS_PORT, value);
     return Status::OK();
 }
@@ -1207,7 +1238,6 @@ Config::SetCacheConfigCpuCacheCapacity(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CPU_CACHE_CAPACITY, value);
     return Status::OK();
 }
@@ -1218,40 +1248,16 @@ Config::SetCacheConfigCpuCacheThreshold(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CPU_CACHE_THRESHOLD, value);
     return Status::OK();
 }
 
-Status
-Config::SetCacheConfigGpuCacheCapacity(const std::string& value) {
-    Status s = CheckCacheConfigGpuCacheCapacity(value);
-    if (!s.ok()) {
-        return s;
-    }
-
-    SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_GPU_CACHE_CAPACITY, value);
-    return Status::OK();
-}
-
-Status
-Config::SetCacheConfigGpuCacheThreshold(const std::string& value) {
-    Status s = CheckCacheConfigGpuCacheThreshold(value);
-    if (!s.ok()) {
-        return s;
-    }
-
-    SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_GPU_CACHE_THRESHOLD, value);
-    return Status::OK();
-}
-
 Status
 Config::SetCacheConfigCacheInsertData(const std::string& value) {
     Status s = CheckCacheConfigCacheInsertData(value);
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CACHE_INSERT_DATA, value);
     return Status::OK();
 }
@@ -1263,7 +1269,6 @@ Config::SetEngineConfigUseBlasThreshold(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_ENGINE, CONFIG_ENGINE_USE_BLAS_THRESHOLD, value);
     return Status::OK();
 }
@@ -1274,7 +1279,6 @@ Config::SetEngineConfigOmpThreadNum(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_ENGINE, CONFIG_ENGINE_OMP_THREAD_NUM, value);
     return Status::OK();
 }
@@ -1285,47 +1289,64 @@ Config::SetEngineConfigGpuSearchThreshold(const std::string& value) {
     if (!s.ok()) {
         return s;
     }
-
     SetConfigValueInMem(CONFIG_ENGINE, CONFIG_ENGINE_GPU_SEARCH_THRESHOLD, value);
     return Status::OK();
 }
 
-/* resource config */
+/* gpu resource config */
 Status
-Config::SetResourceConfigMode(const std::string& value) {
-    Status s = CheckResourceConfigMode(value);
+Config::SetGpuResourceConfigEnableGpu(const std::string& value) {
+    Status s = CheckGpuResourceConfigEnableGpu(value);
     if (!s.ok()) {
         return s;
     }
-
-    SetConfigValueInMem(CONFIG_RESOURCE, CONFIG_RESOURCE_MODE, value);
+    SetConfigValueInMem(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_ENABLE_GPU, value);
     return Status::OK();
 }
 
 Status
-Config::SetResourceConfigSearchResources(const std::string& value) {
+Config::SetGpuResourceConfigCacheCapacity(const std::string& value) {
+    Status s = CheckGpuResourceConfigCacheCapacity(value);
+    if (!s.ok()) {
+        return s;
+    }
+    SetConfigValueInMem(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_CACHE_CAPACITY, value);
+    return Status::OK();
+}
+
+Status
+Config::SetGpuResourceConfigCacheThreshold(const std::string& value) {
+    Status s = CheckGpuResourceConfigCacheThreshold(value);
+    if (!s.ok()) {
+        return s;
+    }
+    SetConfigValueInMem(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_CACHE_THRESHOLD, value);
+    return Status::OK();
+}
+
+Status
+Config::SetGpuResourceConfigSearchResources(const std::string& value) {
     std::vector<std::string> res_vec;
-    server::StringHelpFunctions::SplitStringByDelimeter(value, CONFIG_RESOURCE_SEARCH_RESOURCES_DELIMITER, res_vec);
-
-    Status s = CheckResourceConfigSearchResources(res_vec);
+    server::StringHelpFunctions::SplitStringByDelimeter(value, CONFIG_GPU_RESOURCE_DELIMITER, res_vec);
+    Status s = CheckGpuResourceConfigSearchResources(res_vec);
     if (!s.ok()) {
         return s;
     }
-
-    SetConfigValueInMem(CONFIG_RESOURCE, CONFIG_RESOURCE_SEARCH_RESOURCES, value);
+    SetConfigValueInMem(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_SEARCH_RESOURCES, value);
     return Status::OK();
 }
 
 Status
-Config::SetResourceConfigIndexBuildDevice(const std::string& value) {
-    Status s = CheckResourceConfigIndexBuildDevice(value);
+Config::SetGpuResourceConfigBuildIndexResources(const std::string& value) {
+    std::vector<std::string> res_vec;
+    server::StringHelpFunctions::SplitStringByDelimeter(value, CONFIG_GPU_RESOURCE_DELIMITER, res_vec);
+    Status s = CheckGpuResourceConfigBuildIndexResources(res_vec);
     if (!s.ok()) {
         return s;
     }
-
-    SetConfigValueInMem(CONFIG_RESOURCE, CONFIG_RESOURCE_INDEX_BUILD_DEVICE, value);
+    SetConfigValueInMem(CONFIG_GPU_RESOURCE, CONFIG_GPU_RESOURCE_BUILD_INDEX_RESOURCES, value);
     return Status::OK();
-}
+}  // namespace server
 
 }  // namespace server
 }  // namespace milvus
diff --git a/core/src/server/Config.h b/core/src/server/Config.h
index 3ab0cd8053..0442ae0626 100644
--- a/core/src/server/Config.h
+++ b/core/src/server/Config.h
@@ -59,12 +59,8 @@ static const char* CONFIG_DB_PRELOAD_TABLE = "preload_table";
 static const char* CONFIG_CACHE = "cache_config";
 static const char* CONFIG_CACHE_CPU_CACHE_CAPACITY = "cpu_cache_capacity";
 static const char* CONFIG_CACHE_CPU_CACHE_CAPACITY_DEFAULT = "16";
-static const char* CONFIG_CACHE_GPU_CACHE_CAPACITY = "gpu_cache_capacity";
-static const char* CONFIG_CACHE_GPU_CACHE_CAPACITY_DEFAULT = "4";
-static const char* CONFIG_CACHE_CPU_CACHE_THRESHOLD = "cpu_mem_threshold";
+static const char* CONFIG_CACHE_CPU_CACHE_THRESHOLD = "cpu_cache_threshold";
 static const char* CONFIG_CACHE_CPU_CACHE_THRESHOLD_DEFAULT = "0.85";
-static const char* CONFIG_CACHE_GPU_CACHE_THRESHOLD = "gpu_mem_threshold";
-static const char* CONFIG_CACHE_GPU_CACHE_THRESHOLD_DEFAULT = "0.85";
 static const char* CONFIG_CACHE_CACHE_INSERT_DATA = "cache_insert_data";
 static const char* CONFIG_CACHE_CACHE_INSERT_DATA_DEFAULT = "false";
 
@@ -87,26 +83,23 @@ static const char* CONFIG_ENGINE_OMP_THREAD_NUM_DEFAULT = "0";
 static const char* CONFIG_ENGINE_GPU_SEARCH_THRESHOLD = "gpu_search_threshold";
 static const char* CONFIG_ENGINE_GPU_SEARCH_THRESHOLD_DEFAULT = "1000";
 
-/* resource config */
-static const char* CONFIG_RESOURCE = "resource_config";
-static const char* CONFIG_RESOURCE_MODE = "mode";
-static const char* CONFIG_RESOURCE_MODE_DEFAULT = "simple";
-static const char* CONFIG_RESOURCE_SEARCH_RESOURCES = "search_resources";
-static const char* CONFIG_RESOURCE_SEARCH_RESOURCES_DELIMITER = ",";
-
-#ifdef MILVUS_CPU_VERSION
-static const char* CONFIG_RESOURCE_SEARCH_RESOURCES_DEFAULT = "cpu";
+/* gpu resource config */
+static const char* CONFIG_GPU_RESOURCE = "gpu_resource_config";
+static const char* CONFIG_GPU_RESOURCE_ENABLE_GPU = "enable_gpu";
+#ifdef MILVUS_GPU_VERSION
+static const char* CONFIG_GPU_RESOURCE_ENABLE_GPU_DEFAULT = "true";
 #else
-static const char* CONFIG_RESOURCE_SEARCH_RESOURCES_DEFAULT = "cpu,gpu0";
+static const char* CONFIG_GPU_RESOURCE_ENABLE_GPU_DEFAULT = "false";
 #endif
-
-static const char* CONFIG_RESOURCE_INDEX_BUILD_DEVICE = "index_build_device";
-#ifdef MILVUS_CPU_VERSION
-static const char* CONFIG_RESOURCE_INDEX_BUILD_DEVICE_DEFAULT = "cpu";
-#else
-static const char* CONFIG_RESOURCE_INDEX_BUILD_DEVICE_DEFAULT = "gpu0";
-#endif
-const int32_t CPU_DEVICE_ID = -1;
+static const char* CONFIG_GPU_RESOURCE_CACHE_CAPACITY = "cache_capacity";
+static const char* CONFIG_GPU_RESOURCE_CACHE_CAPACITY_DEFAULT = "4";
+static const char* CONFIG_GPU_RESOURCE_CACHE_THRESHOLD = "cache_threshold";
+static const char* CONFIG_GPU_RESOURCE_CACHE_THRESHOLD_DEFAULT = "0.85";
+static const char* CONFIG_GPU_RESOURCE_DELIMITER = ",";
+static const char* CONFIG_GPU_RESOURCE_SEARCH_RESOURCES = "search_resources";
+static const char* CONFIG_GPU_RESOURCE_SEARCH_RESOURCES_DEFAULT = "gpu0";
+static const char* CONFIG_GPU_RESOURCE_BUILD_INDEX_RESOURCES = "build_index_resources";
+static const char* CONFIG_GPU_RESOURCE_BUILD_INDEX_RESOURCES_DEFAULT = "gpu0";
 
 class Config {
  public:
@@ -170,10 +163,6 @@ class Config {
     Status
     CheckCacheConfigCpuCacheThreshold(const std::string& value);
     Status
-    CheckCacheConfigGpuCacheCapacity(const std::string& value);
-    Status
-    CheckCacheConfigGpuCacheThreshold(const std::string& value);
-    Status
     CheckCacheConfigCacheInsertData(const std::string& value);
 
     /* engine config */
@@ -184,13 +173,17 @@ class Config {
     Status
     CheckEngineConfigGpuSearchThreshold(const std::string& value);
 
-    /* resource config */
+    /* gpu resource config */
     Status
-    CheckResourceConfigMode(const std::string& value);
+    CheckGpuResourceConfigEnableGpu(const std::string& value);
     Status
-    CheckResourceConfigSearchResources(const std::vector<std::string>& value);
+    CheckGpuResourceConfigCacheCapacity(const std::string& value);
     Status
-    CheckResourceConfigIndexBuildDevice(const std::string& value);
+    CheckGpuResourceConfigCacheThreshold(const std::string& value);
+    Status
+    CheckGpuResourceConfigSearchResources(const std::vector<std::string>& value);
+    Status
+    CheckGpuResourceConfigBuildIndexResources(const std::vector<std::string>& value);
 
     std::string
     GetConfigStr(const std::string& parent_key, const std::string& child_key, const std::string& default_value = "");
@@ -239,10 +232,6 @@ class Config {
     Status
     GetCacheConfigCpuCacheThreshold(float& value);
     Status
-    GetCacheConfigGpuCacheCapacity(int64_t& value);
-    Status
-    GetCacheConfigGpuCacheThreshold(float& value);
-    Status
     GetCacheConfigCacheInsertData(bool& value);
 
     /* engine config */
@@ -253,13 +242,17 @@ class Config {
     Status
     GetEngineConfigGpuSearchThreshold(int32_t& value);
 
-    /* resource config */
+    /* gpu resource config */
     Status
-    GetResourceConfigMode(std::string& value);
+    GetGpuResourceConfigEnableGpu(bool& value);
     Status
-    GetResourceConfigSearchResources(std::vector<std::string>& value);
+    GetGpuResourceConfigCacheCapacity(int64_t& value);
     Status
-    GetResourceConfigIndexBuildDevice(int32_t& value);
+    GetGpuResourceConfigCacheThreshold(float& value);
+    Status
+    GetGpuResourceConfigSearchResources(std::vector<int32_t>& value);
+    Status
+    GetGpuResourceConfigBuildIndexResources(std::vector<int32_t>& value);
 
  public:
     /* server config */
@@ -300,10 +293,6 @@ class Config {
     Status
     SetCacheConfigCpuCacheThreshold(const std::string& value);
     Status
-    SetCacheConfigGpuCacheCapacity(const std::string& value);
-    Status
-    SetCacheConfigGpuCacheThreshold(const std::string& value);
-    Status
     SetCacheConfigCacheInsertData(const std::string& value);
 
     /* engine config */
@@ -314,13 +303,17 @@ class Config {
     Status
     SetEngineConfigGpuSearchThreshold(const std::string& value);
 
-    /* resource config */
+    /* gpu resource config */
     Status
-    SetResourceConfigMode(const std::string& value);
+    SetGpuResourceConfigEnableGpu(const std::string& value);
     Status
-    SetResourceConfigSearchResources(const std::string& value);
+    SetGpuResourceConfigCacheCapacity(const std::string& value);
     Status
-    SetResourceConfigIndexBuildDevice(const std::string& value);
+    SetGpuResourceConfigCacheThreshold(const std::string& value);
+    Status
+    SetGpuResourceConfigSearchResources(const std::string& value);
+    Status
+    SetGpuResourceConfigBuildIndexResources(const std::string& value);
 
  private:
     std::unordered_map<std::string, std::unordered_map<std::string, std::string>> config_map_;
diff --git a/core/src/utils/ValidationUtil.cpp b/core/src/utils/ValidationUtil.cpp
index ec696ff3e0..080de77e17 100644
--- a/core/src/utils/ValidationUtil.cpp
+++ b/core/src/utils/ValidationUtil.cpp
@@ -182,7 +182,7 @@ ValidationUtil::ValidatePartitionTags(const std::vector<std::string>& partition_
 }
 
 Status
-ValidationUtil::ValidateGpuIndex(uint32_t gpu_index) {
+ValidationUtil::ValidateGpuIndex(int32_t gpu_index) {
 #ifdef MILVUS_GPU_VERSION
     int num_devices = 0;
     auto cuda_err = cudaGetDeviceCount(&num_devices);
@@ -203,7 +203,7 @@ ValidationUtil::ValidateGpuIndex(uint32_t gpu_index) {
 }
 
 Status
-ValidationUtil::GetGpuMemory(uint32_t gpu_index, size_t& memory) {
+ValidationUtil::GetGpuMemory(int32_t gpu_index, size_t& memory) {
 #ifdef MILVUS_GPU_VERSION
 
     cudaDeviceProp deviceProp;
diff --git a/core/src/utils/ValidationUtil.h b/core/src/utils/ValidationUtil.h
index 01801e295a..201ccef3bd 100644
--- a/core/src/utils/ValidationUtil.h
+++ b/core/src/utils/ValidationUtil.h
@@ -59,10 +59,10 @@ class ValidationUtil {
     ValidatePartitionTags(const std::vector<std::string>& partition_tags);
 
     static Status
-    ValidateGpuIndex(uint32_t gpu_index);
+    ValidateGpuIndex(int32_t gpu_index);
 
     static Status
-    GetGpuMemory(uint32_t gpu_index, size_t& memory);
+    GetGpuMemory(int32_t gpu_index, size_t& memory);
 
     static Status
     ValidateIpAddress(const std::string& ip_address);
diff --git a/core/src/wrapper/KnowhereResource.cpp b/core/src/wrapper/KnowhereResource.cpp
index 8ed19232e9..bf6675cafa 100644
--- a/core/src/wrapper/KnowhereResource.cpp
+++ b/core/src/wrapper/KnowhereResource.cpp
@@ -19,6 +19,8 @@
 #ifdef MILVUS_GPU_VERSION
 #include "knowhere/index/vector_index/helpers/FaissGpuResourceMgr.h"
 #endif
+
+#include "scheduler/Utils.h"
 #include "server/Config.h"
 
 #include <map>
@@ -35,7 +37,6 @@ constexpr int64_t M_BYTE = 1024 * 1024;
 Status
 KnowhereResource::Initialize() {
 #ifdef MILVUS_GPU_VERSION
-
     struct GpuResourceSetting {
         int64_t pinned_memory = 300 * M_BYTE;
         int64_t temp_memory = 300 * M_BYTE;
@@ -47,27 +48,22 @@ KnowhereResource::Initialize() {
 
     // get build index gpu resource
     server::Config& config = server::Config::GetInstance();
-
-    int32_t build_index_gpu;
-    s = config.GetResourceConfigIndexBuildDevice(build_index_gpu);
+    std::vector<int32_t> build_index_gpus;
+    s = config.GetGpuResourceConfigBuildIndexResources(build_index_gpus);
     if (!s.ok())
         return s;
 
-    gpu_resources.insert(std::make_pair(build_index_gpu, GpuResourceSetting()));
+    for (auto gpu_id : build_index_gpus) {
+        gpu_resources.insert(std::make_pair(gpu_id, GpuResourceSetting()));
+    }
 
     // get search gpu resource
-    std::vector<std::string> pool;
-    s = config.GetResourceConfigSearchResources(pool);
+    std::vector<int32_t> search_gpus;
+    s = config.GetGpuResourceConfigSearchResources(search_gpus);
     if (!s.ok())
         return s;
 
-    std::set<uint64_t> gpu_ids;
-    for (auto& resource : pool) {
-        if (resource.length() < 4 || resource.substr(0, 3) != "gpu") {
-            // invalid
-            continue;
-        }
-        auto gpu_id = std::stoi(resource.substr(3));
+    for (auto& gpu_id : search_gpus) {
         gpu_resources.insert(std::make_pair(gpu_id, GpuResourceSetting()));
     }
 
diff --git a/core/unittest/db/utils.cpp b/core/unittest/db/utils.cpp
index bcf1462ecd..afa1d39006 100644
--- a/core/unittest/db/utils.cpp
+++ b/core/unittest/db/utils.cpp
@@ -159,6 +159,10 @@ DBTest::SetUp() {
     auto default_conn = milvus::scheduler::Connection("IO", 500.0);
     auto PCIE = milvus::scheduler::Connection("IO", 11000.0);
     res_mgr->Connect("disk", "cpu", default_conn);
+#ifdef MILVUS_GPU_VERSION
+    res_mgr->Add(milvus::scheduler::ResourceFactory::Create("0", "GPU", 0, true, true));
+    res_mgr->Connect("cpu", "0", PCIE);
+#endif
     res_mgr->Start();
     milvus::scheduler::SchedInst::GetInstance()->Start();
 
diff --git a/core/unittest/server/test_config.cpp b/core/unittest/server/test_config.cpp
index 637273732d..6ba7f19160 100644
--- a/core/unittest/server/test_config.cpp
+++ b/core/unittest/server/test_config.cpp
@@ -216,21 +216,6 @@ TEST_F(ConfigTest, SERVER_CONFIG_VALID_TEST) {
     s = config.GetCacheConfigCpuCacheThreshold(float_val);
     ASSERT_TRUE(float_val == cache_cpu_cache_threshold);
 
-#ifdef MILVUS_GPU_VERSION
-    int64_t cache_gpu_cache_capacity = 1;
-    s = config.SetCacheConfigGpuCacheCapacity(std::to_string(cache_gpu_cache_capacity));
-    ASSERT_TRUE(s.ok());
-    s = config.GetCacheConfigGpuCacheCapacity(int64_val);
-    ASSERT_TRUE(s.ok());
-    ASSERT_TRUE(int64_val == cache_gpu_cache_capacity);
-
-    float cache_gpu_cache_threshold = 0.2;
-    s = config.SetCacheConfigGpuCacheThreshold(std::to_string(cache_gpu_cache_threshold));
-    ASSERT_TRUE(s.ok());
-    s = config.GetCacheConfigGpuCacheThreshold(float_val);
-    ASSERT_TRUE(float_val == cache_gpu_cache_threshold);
-#endif
-
     bool cache_insert_data = true;
     s = config.SetCacheConfigCacheInsertData(std::to_string(cache_insert_data));
     ASSERT_TRUE(s.ok());
@@ -259,42 +244,54 @@ TEST_F(ConfigTest, SERVER_CONFIG_VALID_TEST) {
     ASSERT_TRUE(s.ok());
     ASSERT_TRUE(int32_val == engine_gpu_search_threshold);
 
-    /* resource config */
-    std::string resource_mode = "simple";
-    s = config.SetResourceConfigMode(resource_mode);
+    /* gpu resource config */
+    bool resource_enable_gpu = true;
+    s = config.SetGpuResourceConfigEnableGpu(std::to_string(resource_enable_gpu));
     ASSERT_TRUE(s.ok());
-    s = config.GetResourceConfigMode(str_val);
+    s = config.GetGpuResourceConfigEnableGpu(bool_val);
     ASSERT_TRUE(s.ok());
-    ASSERT_TRUE(str_val == resource_mode);
+    ASSERT_TRUE(bool_val == resource_enable_gpu);
 
-#ifdef MILVUS_CPU_VERSION
-    std::vector<std::string> search_resources = {"cpu"};
-#else
-    std::vector<std::string> search_resources = {"cpu", "gpu0"};
-#endif
-    std::vector<std::string> res_vec;
-    std::string res_str;
-    milvus::server::StringHelpFunctions::MergeStringWithDelimeter(
-        search_resources, milvus::server::CONFIG_RESOURCE_SEARCH_RESOURCES_DELIMITER, res_str);
-    s = config.SetResourceConfigSearchResources(res_str);
+#ifdef MILVUS_GPU_VERSION
+    int64_t gpu_cache_capacity = 1;
+    s = config.SetGpuResourceConfigCacheCapacity(std::to_string(gpu_cache_capacity));
     ASSERT_TRUE(s.ok());
-    s = config.GetResourceConfigSearchResources(res_vec);
+    s = config.GetGpuResourceConfigCacheCapacity(int64_val);
+    ASSERT_TRUE(s.ok());
+    ASSERT_TRUE(int64_val == gpu_cache_capacity);
+
+    float gpu_cache_threshold = 0.2;
+    s = config.SetGpuResourceConfigCacheThreshold(std::to_string(gpu_cache_threshold));
+    ASSERT_TRUE(s.ok());
+    s = config.GetGpuResourceConfigCacheThreshold(float_val);
+    ASSERT_TRUE(float_val == gpu_cache_threshold);
+
+    std::vector<std::string> search_resources = {"gpu0"};
+    std::vector<int32_t> search_res_vec;
+    std::string search_res_str;
+    milvus::server::StringHelpFunctions::MergeStringWithDelimeter(
+        search_resources, milvus::server::CONFIG_GPU_RESOURCE_DELIMITER, search_res_str);
+    s = config.SetGpuResourceConfigSearchResources(search_res_str);
+    ASSERT_TRUE(s.ok());
+    s = config.GetGpuResourceConfigSearchResources(search_res_vec);
     ASSERT_TRUE(s.ok());
     for (size_t i = 0; i < search_resources.size(); i++) {
-        ASSERT_TRUE(search_resources[i] == res_vec[i]);
+        ASSERT_TRUE(std::stoi(search_resources[i].substr(3)) == search_res_vec[i]);
     }
 
-#ifdef MILVUS_CPU_VERSION
-    int32_t resource_index_build_device = milvus::server::CPU_DEVICE_ID;
-    s = config.SetResourceConfigIndexBuildDevice("cpu");
-#else
-    int32_t resource_index_build_device = 0;
-    s = config.SetResourceConfigIndexBuildDevice("gpu" + std::to_string(resource_index_build_device));
+    std::vector<std::string> build_index_resources = {"gpu0"};
+    std::vector<int32_t> build_index_res_vec;
+    std::string build_index_res_str;
+    milvus::server::StringHelpFunctions::MergeStringWithDelimeter(
+        build_index_resources, milvus::server::CONFIG_GPU_RESOURCE_DELIMITER, build_index_res_str);
+    s = config.SetGpuResourceConfigBuildIndexResources(build_index_res_str);
+    ASSERT_TRUE(s.ok());
+    s = config.GetGpuResourceConfigBuildIndexResources(build_index_res_vec);
+    ASSERT_TRUE(s.ok());
+    for (size_t i = 0; i < build_index_resources.size(); i++) {
+        ASSERT_TRUE(std::stoi(build_index_resources[i].substr(3)) == build_index_res_vec[i]);
+    }
 #endif
-    ASSERT_TRUE(s.ok());
-    s = config.GetResourceConfigIndexBuildDevice(int32_val);
-    ASSERT_TRUE(s.ok());
-    ASSERT_TRUE(int32_val == resource_index_build_device);
 }
 
 TEST_F(ConfigTest, SERVER_CONFIG_INVALID_TEST) {
@@ -381,18 +378,6 @@ TEST_F(ConfigTest, SERVER_CONFIG_INVALID_TEST) {
     s = config.SetCacheConfigCpuCacheThreshold("1.0");
     ASSERT_FALSE(s.ok());
 
-#ifdef MILVUS_GPU_VERSION
-    s = config.SetCacheConfigGpuCacheCapacity("a");
-    ASSERT_FALSE(s.ok());
-    s = config.SetCacheConfigGpuCacheCapacity("128");
-    ASSERT_FALSE(s.ok());
-
-    s = config.SetCacheConfigGpuCacheThreshold("a");
-    ASSERT_FALSE(s.ok());
-    s = config.SetCacheConfigGpuCacheThreshold("1.0");
-    ASSERT_FALSE(s.ok());
-#endif
-
     s = config.SetCacheConfigCacheInsertData("N");
     ASSERT_FALSE(s.ok());
 
@@ -408,20 +393,29 @@ TEST_F(ConfigTest, SERVER_CONFIG_INVALID_TEST) {
     s = config.SetEngineConfigGpuSearchThreshold("-1");
     ASSERT_FALSE(s.ok());
 
-    /* resource config */
-    s = config.SetResourceConfigMode("default");
+    /* gpu resource config */
+    s = config.SetGpuResourceConfigEnableGpu("ok");
     ASSERT_FALSE(s.ok());
 
-    s = config.SetResourceConfigSearchResources("gpu10");
+#ifdef MILVUS_GPU_VERSION
+    s = config.SetGpuResourceConfigCacheCapacity("a");
+    ASSERT_FALSE(s.ok());
+    s = config.SetGpuResourceConfigCacheCapacity("128");
     ASSERT_FALSE(s.ok());
 
-    s = config.SetResourceConfigSearchResources("cpu");
-    ASSERT_TRUE(s.ok());
+    s = config.SetGpuResourceConfigCacheThreshold("a");
+    ASSERT_FALSE(s.ok());
+    s = config.SetGpuResourceConfigCacheThreshold("1.0");
+    ASSERT_FALSE(s.ok());
 
-    s = config.SetResourceConfigIndexBuildDevice("gup2");
+    s = config.SetGpuResourceConfigSearchResources("gpu10");
     ASSERT_FALSE(s.ok());
-    s = config.SetResourceConfigIndexBuildDevice("gpu16");
+
+    s = config.SetGpuResourceConfigBuildIndexResources("gup2");
     ASSERT_FALSE(s.ok());
+    s = config.SetGpuResourceConfigBuildIndexResources("gpu16");
+    ASSERT_FALSE(s.ok());
+#endif
 }
 
 TEST_F(ConfigTest, SERVER_CONFIG_TEST) {
@@ -438,4 +432,3 @@ TEST_F(ConfigTest, SERVER_CONFIG_TEST) {
     s = config.ResetDefaultConfig();
     ASSERT_TRUE(s.ok());
 }
-
diff --git a/core/unittest/server/test_rpc.cpp b/core/unittest/server/test_rpc.cpp
index 3377d7bd25..34d4b0ad3a 100644
--- a/core/unittest/server/test_rpc.cpp
+++ b/core/unittest/server/test_rpc.cpp
@@ -85,7 +85,6 @@ class RpcHandlerTest : public testing::Test {
         //        DBWrapper::GetInstance().GetInstance().StartService();
         //        DBWrapper::GetInstance().GetInstance().StopService();
 
-        milvus::server::Config::GetInstance().SetResourceConfigMode("single");
         milvus::server::DBWrapper::GetInstance().StartService();
 
         // initialize handler, create table