diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py
index e7fec041802cc661b14617a8ebfec0864c738b39..d3d92d3a3bd3c24ba2f7cb3173b924a126c17fd9 100644
--- a/src/device/service/DeviceServiceServicerImpl.py
+++ b/src/device/service/DeviceServiceServicerImpl.py
@@ -38,7 +38,7 @@ LOGGER = logging.getLogger(__name__)
 METRICS_POOL = MetricsPool('Device', 'RPC')
 
 METRICS_POOL_DETAILS = MetricsPool('Device', 'exec_details', labels={
-    'step_name': '',
+    'driver': '', 'operation': '', 'step': '',
 })
 
 class DeviceServiceServicerImpl(DeviceServiceServicer):
@@ -51,11 +51,15 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
 
     @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
     def AddDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId:
+        t0 = time.time()
+
         device_uuid = request.device_id.device_uuid.uuid
 
         connection_config_rules = check_connect_rules(request.device_config)
         check_no_endpoints(request.device_endpoints)
 
+        t1 = time.time()
+
         context_client = ContextClient()
         device = get_device(context_client, device_uuid, rw_copy=True)
         if device is None:
@@ -73,10 +77,15 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
         # update device_uuid to honor UUID provided by Context
         device_uuid = device.device_id.device_uuid.uuid
 
+        t2 = time.time()
+
         self.mutex_queues.wait_my_turn(device_uuid)
+        t3 = time.time()
         try:
             driver : _Driver = get_driver(self.driver_instance_cache, device)
 
+            t4 = time.time()
+
             errors = []
 
             # Sub-devices and sub-links are exposed by intermediate controllers or represent mgmt links.
@@ -86,13 +95,23 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
             new_sub_links : Dict[str, Link] = dict()
 
             if len(device.device_endpoints) == 0:
+                t5 = time.time()
                 # created from request, populate endpoints using driver
                 errors.extend(populate_endpoints(
                     device, driver, self.monitoring_loops, new_sub_devices, new_sub_links))
+                t6 = time.time()
+                t_pop_endpoints = t6 - t5
+            else:
+                t_pop_endpoints = None
 
             if len(device.device_config.config_rules) == len(connection_config_rules):
                 # created from request, populate config rules using driver
+                t7 = time.time()
                 errors.extend(populate_config_rules(device, driver))
+                t8 = time.time()
+                t_pop_config_rules = t8 - t7
+            else:
+                t_pop_config_rules = None
 
             # TODO: populate components
 
@@ -100,22 +119,60 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
                 for error in errors: LOGGER.error(error)
                 raise OperationFailedException('AddDevice', extra_details=errors)
 
+            t9 = time.time()
+
             device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED
             device_id = context_client.SetDevice(device)
 
+            t10 = time.time()
+
             for sub_device in new_sub_devices.values():
                 context_client.SetDevice(sub_device)
 
+            t11 = time.time()
+
             for sub_links in new_sub_links.values():
                 context_client.SetLink(sub_links)
 
+            t12 = time.time()
+
             # Update endpoint monitoring resources with UUIDs
             device_with_uuids = get_device(
                 context_client, device_id.device_uuid.uuid, rw_copy=False, include_endpoints=True,
                 include_components=False, include_config_rules=False)
             populate_endpoint_monitoring_resources(device_with_uuids, self.monitoring_loops)
 
+            t13 = time.time()
+
             context_client.close()
+
+            t14 = time.time()
+
+            metrics_labels = dict(driver=driver.name, operation='add_device')
+
+            histogram_duration : Histogram = METRICS_POOL_DETAILS.get_or_create(
+                'AddDevice', MetricTypeEnum.HISTOGRAM_DURATION)
+            histogram_duration.labels(step='total'              , **metrics_labels).observe(t14-t0)
+            histogram_duration.labels(step='execution'          , **metrics_labels).observe(t14-t3)
+            histogram_duration.labels(step='endpoint_checks'    , **metrics_labels).observe(t1-t0)
+            histogram_duration.labels(step='get_device'         , **metrics_labels).observe(t2-t1)
+            histogram_duration.labels(step='wait_queue'         , **metrics_labels).observe(t3-t2)
+            histogram_duration.labels(step='get_driver'         , **metrics_labels).observe(t4-t3)
+            histogram_duration.labels(step='set_device'         , **metrics_labels).observe(t10-t9)
+            histogram_duration.labels(step='populate_monit_rsrc', **metrics_labels).observe(t13-t12)
+
+            if t_pop_endpoints is not None:
+                histogram_duration.labels(step='populate_endpoints', **metrics_labels).observe(t_pop_endpoints)
+
+            if t_pop_config_rules is not None:
+                histogram_duration.labels(step='populate_config_rules', **metrics_labels).observe(t_pop_config_rules)
+
+            if len(new_sub_devices) > 0:
+                histogram_duration.labels(step='set_sub_devices', **metrics_labels).observe(t11-t10)
+
+            if len(new_sub_links) > 0:
+                histogram_duration.labels(step='set_sub_links', **metrics_labels).observe(t12-t11)
+
             return device_id
         finally:
             self.mutex_queues.signal_done(device_uuid)
@@ -195,16 +252,18 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
 
             t9 = time.time()
 
+            metrics_labels = dict(driver=driver.name, operation='configure_device')
+
             histogram_duration : Histogram = METRICS_POOL_DETAILS.get_or_create(
                 'ConfigureDevice', MetricTypeEnum.HISTOGRAM_DURATION)
-            histogram_duration.labels(step_name='total'            ).observe(t9-t0)
-            histogram_duration.labels(step_name='wait_queue'       ).observe(t1-t0)
-            histogram_duration.labels(step_name='execution'        ).observe(t9-t1)
-            histogram_duration.labels(step_name='get_device'       ).observe(t3-t2)
-            histogram_duration.labels(step_name='split_rules'      ).observe(t5-t4)
-            histogram_duration.labels(step_name='configure_rules'  ).observe(t6-t5)
-            histogram_duration.labels(step_name='deconfigure_rules').observe(t7-t6)
-            histogram_duration.labels(step_name='set_device'       ).observe(t9-t8)
+            histogram_duration.labels(step='total'            , **metrics_labels).observe(t9-t0)
+            histogram_duration.labels(step='wait_queue'       , **metrics_labels).observe(t1-t0)
+            histogram_duration.labels(step='execution'        , **metrics_labels).observe(t9-t1)
+            histogram_duration.labels(step='get_device'       , **metrics_labels).observe(t3-t2)
+            histogram_duration.labels(step='split_rules'      , **metrics_labels).observe(t5-t4)
+            histogram_duration.labels(step='configure_rules'  , **metrics_labels).observe(t6-t5)
+            histogram_duration.labels(step='deconfigure_rules', **metrics_labels).observe(t7-t6)
+            histogram_duration.labels(step='set_device'       , **metrics_labels).observe(t9-t8)
 
             return device_id
         finally:
diff --git a/src/device/service/driver_api/_Driver.py b/src/device/service/driver_api/_Driver.py
index 947bc8570a941f8f666c87647d89c315b1bd202a..7adaec79dc99f9b7c836acaec886b0d5bda97fb8 100644
--- a/src/device/service/driver_api/_Driver.py
+++ b/src/device/service/driver_api/_Driver.py
@@ -27,7 +27,7 @@ RESOURCE_ACL = '__acl__'
 
 
 class _Driver:
-    def __init__(self, address: str, port: int, **settings) -> None:
+    def __init__(self, name : str, address: str, port: int, **settings) -> None:
         """ Initialize Driver.
             Parameters:
                 address : str
@@ -37,7 +37,22 @@ class _Driver:
                 **settings
                     Extra settings required by the driver.
         """
-        raise NotImplementedError()
+        self._name = name
+        self._address = address
+        self._port = port
+        self._settings = settings
+
+    @property
+    def name(self): return self._name
+
+    @property
+    def address(self): return self._address
+
+    @property
+    def port(self): return self._port
+
+    @property
+    def settings(self): return self._settings
 
     def Connect(self) -> bool:
         """ Connect to the Device.
diff --git a/src/device/service/drivers/emulated/EmulatedDriver.py b/src/device/service/drivers/emulated/EmulatedDriver.py
index 2acb288784d6da5b202f14c2534ee1a59486a20e..8f9453574a7333e599ea56158204627fcfdd3680 100644
--- a/src/device/service/drivers/emulated/EmulatedDriver.py
+++ b/src/device/service/drivers/emulated/EmulatedDriver.py
@@ -31,16 +31,18 @@ LOGGER = logging.getLogger(__name__)
 
 RE_GET_ENDPOINT_FROM_INTERFACE = re.compile(r'^\/interface\[([^\]]+)\].*')
 
-METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'emulated'})
+DRIVER_NAME = 'emulated'
+METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME})
 
 class EmulatedDriver(_Driver):
-    def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called
+    def __init__(self, address : str, port : int, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, port, **settings)
         self.__lock = threading.Lock()
         self.__initial = TreeNode('.')
         self.__running = TreeNode('.')
         self.__subscriptions = TreeNode('.')
 
-        endpoints = settings.get('endpoints', [])
+        endpoints = self.settings.get('endpoints', [])
         endpoint_resources = []
         for endpoint in endpoints:
             endpoint_resource = compose_resource_endpoint(endpoint)
diff --git a/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py b/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py
index 96dfd2c15f6b359e254a6d6a24dfe42a546833ce..9498dc84cc6991fd2295371842fa8508c961f1bc 100644
--- a/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py
+++ b/src/device/service/drivers/ietf_l2vpn/IetfL2VpnDriver.py
@@ -39,21 +39,23 @@ ALL_RESOURCE_KEYS = [
 
 SERVICE_TYPE = 'ELINE'
 
-METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'ietf_l2vpn'})
+DRIVER_NAME = 'ietf_l2vpn'
+METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME})
 
 class IetfL2VpnDriver(_Driver):
-    def __init__(self, address: str, port: int, **settings) -> None:    # pylint: disable=super-init-not-called
+    def __init__(self, address: str, port: int, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, port, **settings)
         self.__lock = threading.Lock()
         self.__started = threading.Event()
         self.__terminate = threading.Event()
-        username = settings.get('username')
-        password = settings.get('password')
-        scheme = settings.get('scheme', 'http')
-        wim = {'wim_url': '{:s}://{:s}:{:d}'.format(scheme, address, int(port))}
+        username = self.settings.get('username')
+        password = self.settings.get('password')
+        scheme = self.settings.get('scheme', 'http')
+        wim = {'wim_url': '{:s}://{:s}:{:d}'.format(scheme, self.address, int(self.port))}
         wim_account = {'user': username, 'password': password}
         # Mapping updated dynamically with each request
         config = {'mapping_not_needed': False, 'service_endpoint_mapping': []}
-        self.dac = TfsDebugApiClient(address, int(port), scheme=scheme, username=username, password=password)
+        self.dac = TfsDebugApiClient(self.address, int(self.port), scheme=scheme, username=username, password=password)
         self.wim = WimconnectorIETFL2VPN(wim, wim_account, config=config)
         self.conn_info = {} # internal database emulating OSM storage provided to WIM Connectors
 
diff --git a/src/device/service/drivers/microwave/IETFApiDriver.py b/src/device/service/drivers/microwave/IETFApiDriver.py
index fad7cd0736ec35c5675461af241b2e7de2295dac..a8ef9094652378df8d1f1a55868849316b7ec95b 100644
--- a/src/device/service/drivers/microwave/IETFApiDriver.py
+++ b/src/device/service/drivers/microwave/IETFApiDriver.py
@@ -23,20 +23,22 @@ from .Tools import create_connectivity_service, find_key, config_getter, delete_
 
 LOGGER = logging.getLogger(__name__)
 
-METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'microwave'})
+DRIVER_NAME = 'microwave'
+METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME})
 
 class IETFApiDriver(_Driver):
-    def __init__(self, address: str, port: int, **settings) -> None:    # pylint: disable=super-init-not-called
+    def __init__(self, address: str, port: int, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, port, **settings)
         self.__lock = threading.Lock()
         self.__started = threading.Event()
         self.__terminate = threading.Event()
-        username = settings.get('username')
-        password = settings.get('password')
+        username = self.settings.get('username')
+        password = self.settings.get('password')
         self.__auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None
-        scheme = settings.get('scheme', 'http')
-        self.__ietf_root = '{:s}://{:s}:{:d}'.format(scheme, address, int(port))
-        self.__timeout = int(settings.get('timeout', 120))
-        self.__node_ids = set(settings.get('node_ids', []))
+        scheme = self.settings.get('scheme', 'http')
+        self.__ietf_root = '{:s}://{:s}:{:d}'.format(scheme, self.address, int(self.port))
+        self.__timeout = int(self.settings.get('timeout', 120))
+        self.__node_ids = set(self.settings.get('node_ids', []))
 
     def Connect(self) -> bool:
         url = self.__ietf_root + '/nmswebs/restconf/data/ietf-network:networks'
diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index 2399b9ac01258a21a4da6a9aa0e5bc09ea851951..ac67c4ab0d314adb3ce2af0aaffeda18e67334fc 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -235,11 +235,13 @@ def edit_config(
             results = [e for _ in resources] # if commit fails, set exception in each resource
     return results
 
-METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'openconfig'})
+DRIVER_NAME = 'openconfig'
+METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME})
 
 class OpenConfigDriver(_Driver):
-    def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called
-        self.__logger = logging.getLogger('{:s}:[{:s}:{:s}]'.format(str(__name__), str(address), str(port)))
+    def __init__(self, address : str, port : int, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, port, **settings)
+        self.__logger = logging.getLogger('{:s}:[{:s}:{:s}]'.format(str(__name__), str(self.address), str(self.port)))
         self.__lock = threading.Lock()
         #self.__initial = TreeNode('.')
         #self.__running = TreeNode('.')
@@ -249,11 +251,11 @@ class OpenConfigDriver(_Driver):
         self.__scheduler = BackgroundScheduler(daemon=True) # scheduler used to emulate sampling events
         self.__scheduler.configure(
             jobstores = {'default': MemoryJobStore()},
-            executors = {'default': ThreadPoolExecutor(max_workers=1)},
+            executors = {'default': ThreadPoolExecutor(max_workers=1)}, # important! 1 = avoid concurrent requests
             job_defaults = {'coalesce': False, 'max_instances': 3},
             timezone=pytz.utc)
         self.__out_samples = queue.Queue()
-        self.__netconf_handler : NetconfSessionHandler = NetconfSessionHandler(address, port, **settings)
+        self.__netconf_handler = NetconfSessionHandler(self.address, self.port, **(self.settings))
         self.__samples_cache = SamplesCache(self.__netconf_handler, self.__logger)
 
     def Connect(self) -> bool:
diff --git a/src/device/service/drivers/p4/p4_driver.py b/src/device/service/drivers/p4/p4_driver.py
index de47f49c05b0f344999382883233a12eceb43c1b..49e6ed246b79c73d736d9fb91a6d4778cb08c90d 100644
--- a/src/device/service/drivers/p4/p4_driver.py
+++ b/src/device/service/drivers/p4/p4_driver.py
@@ -41,7 +41,8 @@ except ImportError:
 
 LOGGER = logging.getLogger(__name__)
 
-METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'p4'})
+DRIVER_NAME = 'p4'
+METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME})
 
 class P4Driver(_Driver):
     """
diff --git a/src/device/service/drivers/transport_api/TransportApiDriver.py b/src/device/service/drivers/transport_api/TransportApiDriver.py
index 1991a34d0d797c48b6c2296435c0ebd0f3a8125a..98ed8e6aae613ea45519143c89e72af32f3b2620 100644
--- a/src/device/service/drivers/transport_api/TransportApiDriver.py
+++ b/src/device/service/drivers/transport_api/TransportApiDriver.py
@@ -23,19 +23,21 @@ from .Tools import create_connectivity_service, find_key, config_getter, delete_
 
 LOGGER = logging.getLogger(__name__)
 
-METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'transport_api'})
+DRIVER_NAME = 'transport_api'
+METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME})
 
 class TransportApiDriver(_Driver):
-    def __init__(self, address: str, port: int, **settings) -> None:    # pylint: disable=super-init-not-called
+    def __init__(self, address: str, port: int, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, port, **settings)
         self.__lock = threading.Lock()
         self.__started = threading.Event()
         self.__terminate = threading.Event()
-        username = settings.get('username')
-        password = settings.get('password')
+        username = self.settings.get('username')
+        password = self.settings.get('password')
         self.__auth = HTTPBasicAuth(username, password) if username is not None and password is not None else None
-        scheme = settings.get('scheme', 'http')
-        self.__tapi_root = '{:s}://{:s}:{:d}'.format(scheme, address, int(port))
-        self.__timeout = int(settings.get('timeout', 120))
+        scheme = self.settings.get('scheme', 'http')
+        self.__tapi_root = '{:s}://{:s}:{:d}'.format(scheme, self.address, int(self.port))
+        self.__timeout = int(self.settings.get('timeout', 120))
 
     def Connect(self) -> bool:
         url = self.__tapi_root + '/restconf/data/tapi-common:context'
diff --git a/src/device/service/drivers/xr/XrDriver.py b/src/device/service/drivers/xr/XrDriver.py
index c1471a8136b0e5cd7791e019bb0bdafd2252f591..46269ff8904a0e20dbcb08202220412e64cb6283 100644
--- a/src/device/service/drivers/xr/XrDriver.py
+++ b/src/device/service/drivers/xr/XrDriver.py
@@ -33,21 +33,23 @@ urllib3.disable_warnings()
 
 LOGGER = logging.getLogger(__name__)
 
-METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': 'xr'})
+DRIVER_NAME = 'xr'
+METRICS_POOL = MetricsPool('Device', 'Driver', labels={'driver': DRIVER_NAME})
 
 class XrDriver(_Driver):
-    def __init__(self, address: str, port: int, **settings) -> None:    # pylint: disable=super-init-not-called
+    def __init__(self, address: str, port: int, **settings) -> None:
+        super().__init__(DRIVER_NAME, address, port, **settings)
         self.__lock = threading.Lock()
         self.__started = threading.Event()
         self.__terminate = threading.Event()
-        self.__timeout = int(settings.get('timeout', 120))
-        self.__cm_address = address
+        self.__timeout = int(self.settings.get('timeout', 120))
+        self.__cm_address = self.address
         # Mandatory key, an exception will get thrown if missing
-        self.__hub_module_name = settings["hub_module_name"]
+        self.__hub_module_name = self.settings["hub_module_name"]
 
         tls_verify = False # Currently using self signed certificates
-        username = settings.get("username", "xr-user-1")
-        password = settings.get("password", "xr-user-1")
+        username = self.settings.get("username", "xr-user-1")
+        password = self.settings.get("password", "xr-user-1")
 
         # Options are:
         #    disabled --> just import endpoints as usual
@@ -55,7 +57,7 @@ class XrDriver(_Driver):
         #                 (a remotely-controlled transport domain might exist between them)
         #    topology --> imports sub-devices and links connecting them.
         #                 (not supported by XR driver)
-        self.__import_topology = get_import_topology(settings, default=ImportTopologyEnum.DISABLED)
+        self.__import_topology = get_import_topology(self.settings, default=ImportTopologyEnum.DISABLED)
 
         # Options are:
         #    asynchronous --> operation considered complete when IPM responds with suitable status code,
@@ -64,12 +66,12 @@ class XrDriver(_Driver):
         #    lifecycle    --> operation is considered successfull once IPM has completed pluggaable configuration
         #                     or failed in it. This is typically unsuitable for production use
         #                     (as some optics may be transiently unreachable), but is convenient for demos and testin.
-        consistency_mode = ConsistencyMode.from_str(settings.get("consistency-mode", "asynchronous"))
+        consistency_mode = ConsistencyMode.from_str(self.settings.get("consistency-mode", "asynchronous"))
 
-        self.__cm_connection = CmConnection(address, int(port), username, password, self.__timeout, tls_verify = tls_verify, consistency_mode=consistency_mode)
+        self.__cm_connection = CmConnection(self.address, int(self.port), username, password, self.__timeout, tls_verify = tls_verify, consistency_mode=consistency_mode)
         self.__constellation = None
 
-        LOGGER.info(f"XrDriver instantiated, cm {address}:{port}, consistency mode {str(consistency_mode)}, {settings=}")
+        LOGGER.info(f"XrDriver instantiated, cm {self.address}:{self.port}, consistency mode {str(consistency_mode)}, {self.settings=}")
 
     def __str__(self):
         return f"{self.__hub_module_name}@{self.__cm_address}"