diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java
index 2502722f85..db8814a91b 100644
--- a/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java
+++ b/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java
@@ -16,6 +16,7 @@
 import io.sentry.android.core.performance.ActivityLifecycleTimeSpan;
 import io.sentry.android.core.performance.AppStartMetrics;
 import io.sentry.android.core.performance.TimeSpan;
+import io.sentry.protocol.App;
 import io.sentry.protocol.MeasurementValue;
 import io.sentry.protocol.SentryId;
 import io.sentry.protocol.SentrySpan;
@@ -79,26 +80,37 @@ public SentryEvent process(@NotNull SentryEvent event, @NotNull Hint hint) {
 
     // the app start measurement is only sent once and only if the transaction has
     // the app.start span, which is automatically created by the SDK.
-    if (!sentStartMeasurement && hasAppStartSpan(transaction)) {
-      final @NotNull TimeSpan appStartTimeSpan =
-          AppStartMetrics.getInstance().getAppStartTimeSpanWithFallback(options);
-      final long appStartUpDurationMs = appStartTimeSpan.getDurationMs();
-
-      // if appStartUpDurationMs is 0, metrics are not ready to be sent
-      if (appStartUpDurationMs != 0) {
-        final MeasurementValue value =
-            new MeasurementValue(
-                (float) appStartUpDurationMs, MeasurementUnit.Duration.MILLISECOND.apiName());
-
-        final String appStartKey =
-            AppStartMetrics.getInstance().getAppStartType() == AppStartMetrics.AppStartType.COLD
-                ? MeasurementValue.KEY_APP_START_COLD
-                : MeasurementValue.KEY_APP_START_WARM;
-
-        transaction.getMeasurements().put(appStartKey, value);
+    if (hasAppStartSpan(transaction)) {
+      if (!sentStartMeasurement) {
+        final @NotNull TimeSpan appStartTimeSpan =
+            AppStartMetrics.getInstance().getAppStartTimeSpanWithFallback(options);
+        final long appStartUpDurationMs = appStartTimeSpan.getDurationMs();
+
+        // if appStartUpDurationMs is 0, metrics are not ready to be sent
+        if (appStartUpDurationMs != 0) {
+          final MeasurementValue value =
+              new MeasurementValue(
+                  (float) appStartUpDurationMs, MeasurementUnit.Duration.MILLISECOND.apiName());
+
+          final String appStartKey =
+              AppStartMetrics.getInstance().getAppStartType() == AppStartMetrics.AppStartType.COLD
+                  ? MeasurementValue.KEY_APP_START_COLD
+                  : MeasurementValue.KEY_APP_START_WARM;
+
+          transaction.getMeasurements().put(appStartKey, value);
+
+          attachColdAppStartSpans(AppStartMetrics.getInstance(), transaction);
+          sentStartMeasurement = true;
+        }
+      }
 
-        attachColdAppStartSpans(AppStartMetrics.getInstance(), transaction);
-        sentStartMeasurement = true;
+      final @Nullable App appContext = transaction.getContexts().getApp();
+      if (appContext != null) {
+        final String appStartType =
+            AppStartMetrics.getInstance().getAppStartType() == AppStartMetrics.AppStartType.COLD
+                ? "cold"
+                : "warm";
+        appContext.setStartType(appStartType);
       }
     }
 
diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt
index 4c23691e63..dce5cb3998 100644
--- a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt
+++ b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt
@@ -16,6 +16,7 @@ import io.sentry.android.core.ActivityLifecycleIntegration.UI_LOAD_OP
 import io.sentry.android.core.performance.ActivityLifecycleTimeSpan
 import io.sentry.android.core.performance.AppStartMetrics
 import io.sentry.android.core.performance.AppStartMetrics.AppStartType
+import io.sentry.protocol.App
 import io.sentry.protocol.MeasurementValue
 import io.sentry.protocol.SentrySpan
 import io.sentry.protocol.SentryTransaction
@@ -27,6 +28,7 @@ import kotlin.test.BeforeTest
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertFalse
+import kotlin.test.assertNull
 import kotlin.test.assertTrue
 
 @RunWith(AndroidJUnit4::class)
@@ -464,6 +466,66 @@ class PerformanceAndroidEventProcessorTest {
         }
     }
 
+    @Test
+    fun `does not set start_type field for txns without app start span`() {
+        // given some cold app start metrics
+        // where class loaded happened way before app start
+        setAppStart(fixture.options, coldStart = true)
+
+        val sut = fixture.getSut(enablePerformanceV2 = true)
+        val context = TransactionContext("Activity", UI_LOAD_OP)
+        val tracer = SentryTracer(context, fixture.hub)
+        var tr = SentryTransaction(tracer)
+        // usually set by DefaultAndroidEventProcessor
+        tr.contexts.setApp(App())
+
+        // when the processor attaches the app start spans
+        tr = sut.process(tr, Hint())
+
+        // start_type should not be set
+        assertNull(tr.contexts.app!!.startType)
+    }
+
+    @Test
+    fun `sets start_type field for app context`() {
+        // given some cold app start metrics
+        // where class loaded happened way before app start
+        setAppStart(fixture.options, coldStart = true)
+
+        val sut = fixture.getSut(enablePerformanceV2 = true)
+        val context = TransactionContext("Activity", UI_LOAD_OP)
+        val tracer = SentryTracer(context, fixture.hub)
+        var tr = SentryTransaction(tracer)
+        // usually set by DefaultAndroidEventProcessor
+        tr.contexts.setApp(App())
+
+        val appStartSpan = SentrySpan(
+            0.0,
+            1.0,
+            tr.contexts.trace!!.traceId,
+            SpanId(),
+            null,
+            APP_START_COLD,
+            "App Start",
+            SpanStatus.OK,
+            null,
+            emptyMap(),
+            emptyMap(),
+            null,
+            null
+        )
+        tr.spans.add(appStartSpan)
+
+        // when the processor attaches the app start spans
+        tr = sut.process(tr, Hint())
+
+        // start_type should be set
+        assertEquals(
+            "cold",
+            tr.contexts.app!!.startType
+        )
+    }
+
     private fun setAppStart(options: SentryAndroidOptions, coldStart: Boolean = true) {
         AppStartMetrics.getInstance().apply {
             appStartType = when (coldStart) {
diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api
index 84fa3a4751..827bd1a955 100644
--- a/sentry/api/sentry.api
+++ b/sentry/api/sentry.api
@@ -3643,6 +3643,7 @@ public final class io/sentry/protocol/App : io/sentry/JsonSerializable, io/sentr
 	public fun getDeviceAppHash ()Ljava/lang/String;
 	public fun getInForeground ()Ljava/lang/Boolean;
 	public fun getPermissions ()Ljava/util/Map;
+	public fun getStartType ()Ljava/lang/String;
 	public fun getUnknown ()Ljava/util/Map;
 	public fun getViewNames ()Ljava/util/List;
 	public fun hashCode ()I
@@ -3656,6 +3657,7 @@ public final class io/sentry/protocol/App : io/sentry/JsonSerializable, io/sentr
 	public fun setDeviceAppHash (Ljava/lang/String;)V
 	public fun setInForeground (Ljava/lang/Boolean;)V
 	public fun setPermissions (Ljava/util/Map;)V
+	public fun setStartType (Ljava/lang/String;)V
 	public fun setUnknown (Ljava/util/Map;)V
 	public fun setViewNames (Ljava/util/List;)V
 }
@@ -3676,6 +3678,7 @@ public final class io/sentry/protocol/App$JsonKeys {
 	public static final field BUILD_TYPE Ljava/lang/String;
 	public static final field DEVICE_APP_HASH Ljava/lang/String;
 	public static final field IN_FOREGROUND Ljava/lang/String;
+	public static final field START_TYPE Ljava/lang/String;
 	public static final field VIEW_NAMES Ljava/lang/String;
 	public fun <init> ()V
 }
diff --git a/sentry/src/main/java/io/sentry/protocol/App.java b/sentry/src/main/java/io/sentry/protocol/App.java
index b7b41638db..bec57d22f3 100644
--- a/sentry/src/main/java/io/sentry/protocol/App.java
+++ b/sentry/src/main/java/io/sentry/protocol/App.java
@@ -40,8 +40,10 @@ public final class App implements JsonUnknown, JsonSerializable {
   private @Nullable String appBuild;
   /** Application permissions in the form of "permission_name" : "granted|not_granted" */
   private @Nullable Map<String, String> permissions;
-  /** The list of the visibile UI screens * */
+  /** The list of the visible UI screens * */
   private @Nullable List<String> viewNames;
+  /** the app start type */
+  private @Nullable String startType;
   /**
    * A flag indicating whether the app is in foreground or not. An app is in foreground when it's
    * visible to the user.
@@ -61,6 +63,7 @@ public App() {}
     this.permissions = CollectionUtils.newConcurrentHashMap(app.permissions);
     this.inForeground = app.inForeground;
     this.viewNames = CollectionUtils.newArrayList(app.viewNames);
+    this.startType = app.startType;
     this.unknown = CollectionUtils.newConcurrentHashMap(app.unknown);
   }
 
@@ -151,6 +154,15 @@ public void setViewNames(final @Nullable List<String> viewNames) {
     this.viewNames = viewNames;
   }
 
+  @Nullable
+  public String getStartType() {
+    return startType;
+  }
+
+  public void setStartType(final @Nullable String startType) {
+    this.startType = startType;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
@@ -165,7 +177,8 @@ public boolean equals(Object o) {
         && Objects.equals(appBuild, app.appBuild)
         && Objects.equals(permissions, app.permissions)
         && Objects.equals(inForeground, app.inForeground)
-        && Objects.equals(viewNames, app.viewNames);
+        && Objects.equals(viewNames, app.viewNames)
+        && Objects.equals(startType, app.startType);
   }
 
   @Override
@@ -180,7 +193,8 @@ public int hashCode() {
         appBuild,
         permissions,
         inForeground,
-        viewNames);
+        viewNames,
+        startType);
   }
 
   // region json
@@ -207,6 +221,7 @@ public static final class JsonKeys {
     public static final String APP_PERMISSIONS = "permissions";
     public static final String IN_FOREGROUND = "in_foreground";
     public static final String VIEW_NAMES = "view_names";
+    public static final String START_TYPE = "start_type";
   }
 
   @Override
@@ -243,6 +258,9 @@ public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger
     if (viewNames != null) {
       writer.name(JsonKeys.VIEW_NAMES).value(logger, viewNames);
     }
+    if (startType != null) {
+      writer.name(JsonKeys.START_TYPE).value(startType);
+    }
     if (unknown != null) {
       for (String key : unknown.keySet()) {
         Object value = unknown.get(key);
@@ -298,6 +316,9 @@ public static final class Deserializer implements JsonDeserializer<App> {
               app.setViewNames(viewNames);
             }
             break;
+          case JsonKeys.START_TYPE:
+            app.startType = reader.nextStringOrNull();
+            break;
           default:
             if (unknown == null) {
               unknown = new ConcurrentHashMap<>();
diff --git a/sentry/src/test/java/io/sentry/protocol/AppSerializationTest.kt b/sentry/src/test/java/io/sentry/protocol/AppSerializationTest.kt
index c39f93643a..85716fe913 100644
--- a/sentry/src/test/java/io/sentry/protocol/AppSerializationTest.kt
+++ b/sentry/src/test/java/io/sentry/protocol/AppSerializationTest.kt
@@ -31,6 +31,7 @@ class AppSerializationTest {
             )
             inForeground = true
             viewNames = listOf("MainActivity", "SidebarActivity")
+            startType = "cold"
         }
     }
     private val fixture = Fixture()
diff --git a/sentry/src/test/java/io/sentry/protocol/AppTest.kt b/sentry/src/test/java/io/sentry/protocol/AppTest.kt
index 3f51594fff..5c36f148c0 100644
--- a/sentry/src/test/java/io/sentry/protocol/AppTest.kt
+++ b/sentry/src/test/java/io/sentry/protocol/AppTest.kt
@@ -21,6 +21,7 @@ class AppTest {
         app.permissions = mapOf(Pair("internet", "granted"))
         app.viewNames = listOf("MainActivity")
         app.inForeground = true
+        app.startType = "cold"
         val unknown = mapOf(Pair("unknown", "unknown"))
         app.unknown = unknown
 
@@ -49,6 +50,7 @@ class AppTest {
         app.permissions = mapOf(Pair("internet", "granted"))
         app.viewNames = listOf("MainActivity")
         app.inForeground = true
+        app.startType = "cold"
         val unknown = mapOf(Pair("unknown", "unknown"))
         app.unknown = unknown
 
@@ -67,6 +69,7 @@ class AppTest {
         assertEquals(listOf("MainActivity"), clone.viewNames)
 
         assertEquals(true, clone.inForeground)
+        assertEquals("cold", clone.startType)
         assertNotNull(clone.unknown) {
             assertEquals("unknown", it["unknown"])
         }
diff --git a/sentry/src/test/resources/json/app.json b/sentry/src/test/resources/json/app.json
index e835258efa..76eab3b545 100644
--- a/sentry/src/test/resources/json/app.json
+++ b/sentry/src/test/resources/json/app.json
@@ -12,5 +12,6 @@
       "CAMERA": "granted"
     },
     "in_foreground": true,
-    "view_names": ["MainActivity", "SidebarActivity"]
+    "view_names": ["MainActivity", "SidebarActivity"],
+    "start_type": "cold"
 }
diff --git a/sentry/src/test/resources/json/contexts.json b/sentry/src/test/resources/json/contexts.json
index 97f06e0be6..574bb01921 100644
--- a/sentry/src/test/resources/json/contexts.json
+++ b/sentry/src/test/resources/json/contexts.json
@@ -14,7 +14,8 @@
       "CAMERA": "granted"
     },
     "in_foreground": true,
-    "view_names": ["MainActivity", "SidebarActivity"]
+    "view_names": ["MainActivity", "SidebarActivity"],
+    "start_type": "cold"
   },
   "browser":
   {