diff --git a/CHANGELOG.md b/CHANGELOG.md
index 566829ae1e2..14ca27bd9bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 ### Added
 
 - Add `Reset` method to `SpanRecorder` in `go.opentelemetry.io/otel/sdk/trace/tracetest`. (#5994)
+- Add `EnabledInstrument` interface in `go.opentelemetry.io/otel/sdk/metric/internal/x`.
+  This is an experimental interface that is implemented by synchronous instruments provided by `go.opentelemetry.io/otel/sdk/metric`.
+  Users can use it to avoid performing computationally expensive operations when recording measurements.
+  It does not fall within the scope of the OpenTelemetry Go versioning and stability [policy](./VERSIONING.md) and it may be changed in backwards incompatible ways or removed in feature releases. (#6016)
 
 ### Changed
 
diff --git a/sdk/metric/instrument.go b/sdk/metric/instrument.go
index 48b723a7b3b..c33e1a28cb4 100644
--- a/sdk/metric/instrument.go
+++ b/sdk/metric/instrument.go
@@ -16,6 +16,7 @@ import (
 	"go.opentelemetry.io/otel/metric/embedded"
 	"go.opentelemetry.io/otel/sdk/instrumentation"
 	"go.opentelemetry.io/otel/sdk/metric/internal/aggregate"
+	"go.opentelemetry.io/otel/sdk/metric/internal/x"
 )
 
 var zeroScope instrumentation.Scope
@@ -190,6 +191,7 @@ var (
 	_ metric.Int64UpDownCounter = (*int64Inst)(nil)
 	_ metric.Int64Histogram     = (*int64Inst)(nil)
 	_ metric.Int64Gauge         = (*int64Inst)(nil)
+	_ x.EnabledInstrument       = (*int64Inst)(nil)
 )
 
 func (i *int64Inst) Add(ctx context.Context, val int64, opts ...metric.AddOption) {
@@ -202,6 +204,10 @@ func (i *int64Inst) Record(ctx context.Context, val int64, opts ...metric.Record
 	i.aggregate(ctx, val, c.Attributes())
 }
 
+func (i *int64Inst) Enabled(_ context.Context) bool {
+	return len(i.measures) != 0
+}
+
 func (i *int64Inst) aggregate(ctx context.Context, val int64, s attribute.Set) { // nolint:revive  // okay to shadow pkg with method.
 	for _, in := range i.measures {
 		in(ctx, val, s)
@@ -222,6 +228,7 @@ var (
 	_ metric.Float64UpDownCounter = (*float64Inst)(nil)
 	_ metric.Float64Histogram     = (*float64Inst)(nil)
 	_ metric.Float64Gauge         = (*float64Inst)(nil)
+	_ x.EnabledInstrument         = (*float64Inst)(nil)
 )
 
 func (i *float64Inst) Add(ctx context.Context, val float64, opts ...metric.AddOption) {
@@ -234,6 +241,10 @@ func (i *float64Inst) Record(ctx context.Context, val float64, opts ...metric.Re
 	i.aggregate(ctx, val, c.Attributes())
 }
 
+func (i *float64Inst) Enabled(_ context.Context) bool {
+	return len(i.measures) != 0
+}
+
 func (i *float64Inst) aggregate(ctx context.Context, val float64, s attribute.Set) {
 	for _, in := range i.measures {
 		in(ctx, val, s)
diff --git a/sdk/metric/internal/x/README.md b/sdk/metric/internal/x/README.md
index aba69d65471..59f736b733f 100644
--- a/sdk/metric/internal/x/README.md
+++ b/sdk/metric/internal/x/README.md
@@ -10,6 +10,7 @@ See the [Compatibility and Stability](#compatibility-and-stability) section for
 
 - [Cardinality Limit](#cardinality-limit)
 - [Exemplars](#exemplars)
+- [Instrument Enabled](#instrument-enabled)
 
 ### Cardinality Limit
 
@@ -102,6 +103,24 @@ Revert to the default exemplar filter (`"trace_based"`)
 unset OTEL_METRICS_EXEMPLAR_FILTER
 ```
 
+### Instrument Enabled
+
+To help users avoid performing computationally expensive operations when recording measurements, synchronous instruments provide an `Enabled` method.
+
+#### Examples
+
+The following code shows an example of how to check if an instrument implements the `EnabledInstrument` interface before using the `Enabled` function to avoid doing an expensive computation:
+
+```go
+type enabledInstrument interface { Enabled(context.Context) bool }
+
+ctr, err := m.Int64Counter("expensive-counter")
+c, ok := ctr.(enabledInstrument)
+if !ok || c.Enabled(context.Background()) {
+    c.Add(expensiveComputation())
+}
+```
+
 ## Compatibility and Stability
 
 Experimental features do not fall within the scope of the OpenTelemetry Go versioning and stability [policy](../../../../VERSIONING.md).
diff --git a/sdk/metric/internal/x/x.go b/sdk/metric/internal/x/x.go
index 08919937068..a98606238ad 100644
--- a/sdk/metric/internal/x/x.go
+++ b/sdk/metric/internal/x/x.go
@@ -8,6 +8,7 @@
 package x // import "go.opentelemetry.io/otel/sdk/metric/internal/x"
 
 import (
+	"context"
 	"os"
 	"strconv"
 )
@@ -67,3 +68,14 @@ func (f Feature[T]) Enabled() bool {
 	_, ok := f.Lookup()
 	return ok
 }
+
+// EnabledInstrument informs whether the instrument is enabled.
+//
+// EnabledInstrument interface is implemented by synchronous instruments.
+type EnabledInstrument interface {
+	// Enabled returns whether the instrument will process measurements for the given context.
+	//
+	// This function can be used in places where measuring an instrument
+	// would result in computationally expensive operations.
+	Enabled(context.Context) bool
+}
diff --git a/sdk/metric/meter_test.go b/sdk/metric/meter_test.go
index 3d87e58f6c3..10f473a4ca6 100644
--- a/sdk/metric/meter_test.go
+++ b/sdk/metric/meter_test.go
@@ -24,6 +24,7 @@ import (
 	"go.opentelemetry.io/otel/metric"
 	"go.opentelemetry.io/otel/sdk/instrumentation"
 	"go.opentelemetry.io/otel/sdk/metric/exemplar"
+	"go.opentelemetry.io/otel/sdk/metric/internal/x"
 	"go.opentelemetry.io/otel/sdk/metric/metricdata"
 	"go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest"
 	"go.opentelemetry.io/otel/sdk/resource"
@@ -388,6 +389,9 @@ func TestMeterCreatesInstruments(t *testing.T) {
 				ctr, err := m.Int64Counter("sint")
 				assert.NoError(t, err)
 
+				c, ok := ctr.(x.EnabledInstrument)
+				require.True(t, ok)
+				assert.True(t, c.Enabled(context.Background()))
 				ctr.Add(ctx, 3)
 			},
 			want: metricdata.Metrics{
@@ -407,6 +411,9 @@ func TestMeterCreatesInstruments(t *testing.T) {
 				ctr, err := m.Int64UpDownCounter("sint")
 				assert.NoError(t, err)
 
+				c, ok := ctr.(x.EnabledInstrument)
+				require.True(t, ok)
+				assert.True(t, c.Enabled(context.Background()))
 				ctr.Add(ctx, 11)
 			},
 			want: metricdata.Metrics{
@@ -452,6 +459,9 @@ func TestMeterCreatesInstruments(t *testing.T) {
 				ctr, err := m.Float64Counter("sfloat")
 				assert.NoError(t, err)
 
+				c, ok := ctr.(x.EnabledInstrument)
+				require.True(t, ok)
+				assert.True(t, c.Enabled(context.Background()))
 				ctr.Add(ctx, 3)
 			},
 			want: metricdata.Metrics{
@@ -471,6 +481,9 @@ func TestMeterCreatesInstruments(t *testing.T) {
 				ctr, err := m.Float64UpDownCounter("sfloat")
 				assert.NoError(t, err)
 
+				c, ok := ctr.(x.EnabledInstrument)
+				require.True(t, ok)
+				assert.True(t, c.Enabled(context.Background()))
 				ctr.Add(ctx, 11)
 			},
 			want: metricdata.Metrics{
@@ -532,6 +545,78 @@ func TestMeterCreatesInstruments(t *testing.T) {
 	}
 }
 
+func TestMeterWithDropView(t *testing.T) {
+	dropView := NewView(
+		Instrument{Name: "*"},
+		Stream{Aggregation: AggregationDrop{}},
+	)
+	m := NewMeterProvider(WithView(dropView)).Meter(t.Name())
+
+	testCases := []struct {
+		name string
+		fn   func(*testing.T) (any, error)
+	}{
+		{
+			name: "Int64Counter",
+			fn: func(*testing.T) (any, error) {
+				return m.Int64Counter("sint")
+			},
+		},
+		{
+			name: "Int64UpDownCounter",
+			fn: func(*testing.T) (any, error) {
+				return m.Int64UpDownCounter("sint")
+			},
+		},
+		{
+			name: "Int64Gauge",
+			fn: func(*testing.T) (any, error) {
+				return m.Int64Gauge("sint")
+			},
+		},
+		{
+			name: "Int64Histogram",
+			fn: func(*testing.T) (any, error) {
+				return m.Int64Histogram("histogram")
+			},
+		},
+		{
+			name: "Float64Counter",
+			fn: func(*testing.T) (any, error) {
+				return m.Float64Counter("sfloat")
+			},
+		},
+		{
+			name: "Float64UpDownCounter",
+			fn: func(*testing.T) (any, error) {
+				return m.Float64UpDownCounter("sfloat")
+			},
+		},
+		{
+			name: "Float64Gauge",
+			fn: func(*testing.T) (any, error) {
+				return m.Float64Gauge("sfloat")
+			},
+		},
+		{
+			name: "Float64Histogram",
+			fn: func(*testing.T) (any, error) {
+				return m.Float64Histogram("histogram")
+			},
+		},
+	}
+
+	for _, tt := range testCases {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := tt.fn(t)
+			require.NoError(t, err)
+			c, ok := got.(x.EnabledInstrument)
+			require.True(t, ok)
+			assert.False(t, c.Enabled(context.Background()))
+		})
+	}
+}
+
 func TestMeterCreatesInstrumentsValidations(t *testing.T) {
 	testCases := []struct {
 		name string