diff --git a/internal/metrics/pilorama.go b/internal/metrics/pilorama.go
index c669275fe..82bd995d5 100644
--- a/internal/metrics/pilorama.go
+++ b/internal/metrics/pilorama.go
@@ -13,7 +13,7 @@ type PiloramaMetrics interface {
 	SetMode(shardID string, m mode.ComponentMode)
 	Close(shardID string)
 
-	AddMethodDuration(shardID string, method string, d time.Duration, success bool)
+	AddMethodDuration(shardID string, method string, d time.Duration, success bool, ioTag string)
 }
 
 func newPiloramaMetrics() *piloramaMetrics {
@@ -24,7 +24,7 @@ func newPiloramaMetrics() *piloramaMetrics {
 			Subsystem: piloramaSubSystem,
 			Name:      "request_duration_seconds",
 			Help:      "Accumulated Pilorama request process duration",
-		}, []string{shardIDLabel, successLabel, methodLabel}),
+		}, []string{shardIDLabel, successLabel, methodLabel, ioTagLabel}),
 	}
 }
 
@@ -37,11 +37,12 @@ func (m *piloramaMetrics) SetMode(shardID string, mode mode.ComponentMode) {
 	m.mode.SetMode(shardID, mode.String())
 }
 
-func (m *piloramaMetrics) AddMethodDuration(shardID string, method string, d time.Duration, success bool) {
+func (m *piloramaMetrics) AddMethodDuration(shardID string, method string, d time.Duration, success bool, ioTag string) {
 	m.reqDuration.With(prometheus.Labels{
 		shardIDLabel: shardID,
 		successLabel: strconv.FormatBool(success),
 		methodLabel:  method,
+		ioTagLabel:   ioTag,
 	}).Observe(d.Seconds())
 }
 
diff --git a/pkg/local_object_storage/metrics/pilorama.go b/pkg/local_object_storage/metrics/pilorama.go
index 050b769a0..d03e6207b 100644
--- a/pkg/local_object_storage/metrics/pilorama.go
+++ b/pkg/local_object_storage/metrics/pilorama.go
@@ -32,6 +32,6 @@ func (m *piloramaMetrics) Close() {
 	m.m.Close(m.shardID)
 }
 
-func (m *piloramaMetrics) AddMethodDuration(method string, d time.Duration, success bool) {
-	m.m.AddMethodDuration(m.shardID, method, d, success)
+func (m *piloramaMetrics) AddMethodDuration(method string, d time.Duration, success bool, ioTag string) {
+	m.m.AddMethodDuration(m.shardID, method, d, success, ioTag)
 }
diff --git a/pkg/local_object_storage/pilorama/boltdb.go b/pkg/local_object_storage/pilorama/boltdb.go
index 9d71d9fda..3f60d7f2d 100644
--- a/pkg/local_object_storage/pilorama/boltdb.go
+++ b/pkg/local_object_storage/pilorama/boltdb.go
@@ -14,6 +14,7 @@ import (
 	"sync"
 	"time"
 
+	"git.frostfs.info/TrueCloudLab/frostfs-node/internal/qos"
 	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
 	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
 	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
@@ -259,7 +260,7 @@ func (t *boltForest) TreeExists(ctx context.Context, cid cidSDK.ID, treeID strin
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeExists", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeExists", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeExists",
@@ -297,7 +298,7 @@ func (t *boltForest) TreeUpdateLastSyncHeight(ctx context.Context, cid cidSDK.ID
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeUpdateLastSyncHeight", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeUpdateLastSyncHeight", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeUpdateLastSyncHeight",
@@ -333,7 +334,7 @@ func (t *boltForest) TreeLastSyncHeight(ctx context.Context, cid cidSDK.ID, tree
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeLastSyncHeight", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeLastSyncHeight", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeLastSyncHeight",
@@ -371,7 +372,7 @@ func (t *boltForest) TreeAddByPath(ctx context.Context, d CIDDescriptor, treeID
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeAddByPath", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeAddByPath", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeAddByPath",
@@ -489,7 +490,7 @@ func (t *boltForest) TreeApply(ctx context.Context, cnr cidSDK.ID, treeID string
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeApply", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeApply", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeApply",
@@ -561,7 +562,7 @@ func (t *boltForest) TreeApplyBatch(ctx context.Context, cnr cidSDK.ID, treeID s
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeApplyBatch", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeApplyBatch", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeApplyBatch",
@@ -636,7 +637,7 @@ func (t *boltForest) TreeApplyStream(ctx context.Context, cnr cidSDK.ID, treeID
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeApplyStream", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeApplyStream", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeApplyStream",
@@ -937,7 +938,7 @@ func (t *boltForest) TreeGetByPath(ctx context.Context, cid cidSDK.ID, treeID st
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeGetByPath", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeGetByPath", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeGetByPath",
@@ -1017,7 +1018,7 @@ func (t *boltForest) TreeGetMeta(ctx context.Context, cid cidSDK.ID, treeID stri
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeGetMeta", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeGetMeta", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeGetMeta",
@@ -1083,7 +1084,7 @@ func (t *boltForest) TreeSortedByFilename(ctx context.Context, cid cidSDK.ID, tr
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeSortedByFilename", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeSortedByFilename", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeSortedByFilename",
@@ -1253,7 +1254,7 @@ func (t *boltForest) TreeGetChildren(ctx context.Context, cid cidSDK.ID, treeID
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeGetChildren", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeGetChildren", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeGetChildren",
@@ -1318,7 +1319,7 @@ func (t *boltForest) TreeList(ctx context.Context, cid cidSDK.ID) ([]string, err
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeList", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeList", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeList",
@@ -1367,7 +1368,7 @@ func (t *boltForest) TreeGetOpLog(ctx context.Context, cid cidSDK.ID, treeID str
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeGetOpLog", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeGetOpLog", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeGetOpLog",
@@ -1414,7 +1415,7 @@ func (t *boltForest) TreeDrop(ctx context.Context, cid cidSDK.ID, treeID string)
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeDrop", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeDrop", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeDrop",
@@ -1465,7 +1466,7 @@ func (t *boltForest) TreeListTrees(ctx context.Context, prm TreeListTreesPrm) (*
 		success   = false
 	)
 	defer func() {
-		t.metrics.AddMethodDuration("TreeListTrees", time.Since(startedAt), success)
+		t.metrics.AddMethodDuration("TreeListTrees", time.Since(startedAt), success, qos.IOTagStringFromContext(ctx))
 	}()
 
 	_, span := tracing.StartSpanFromContext(ctx, "boltForest.TreeListTrees")
diff --git a/pkg/local_object_storage/pilorama/metrics.go b/pkg/local_object_storage/pilorama/metrics.go
index 6ffc479e4..14b07bdcb 100644
--- a/pkg/local_object_storage/pilorama/metrics.go
+++ b/pkg/local_object_storage/pilorama/metrics.go
@@ -12,12 +12,12 @@ type Metrics interface {
 	SetMode(m mode.ComponentMode)
 	Close()
 
-	AddMethodDuration(method string, d time.Duration, success bool)
+	AddMethodDuration(method string, d time.Duration, success bool, ioTag string)
 }
 
 type noopMetrics struct{}
 
-func (m *noopMetrics) SetParentID(string)                            {}
-func (m *noopMetrics) SetMode(mode.ComponentMode)                    {}
-func (m *noopMetrics) Close()                                        {}
-func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {}
+func (m *noopMetrics) SetParentID(string)                                    {}
+func (m *noopMetrics) SetMode(mode.ComponentMode)                            {}
+func (m *noopMetrics) Close()                                                {}
+func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool, string) {}