diff --git a/src/blueapi/service/model.py b/src/blueapi/service/model.py
index 91b13ab6c..23dd667a0 100644
--- a/src/blueapi/service/model.py
+++ b/src/blueapi/service/model.py
@@ -1,5 +1,6 @@
 from collections.abc import Iterable
 from typing import Any
+from uuid import UUID
 
 from bluesky.protocols import HasName
 from pydantic import Field
@@ -144,6 +145,10 @@ class EnvironmentResponse(BlueapiBaseModel):
     State of internal environment.
     """
 
+    environment_id: UUID = Field(
+        description="Unique ID for the environment instance, can be used to "
+        "differentiate between a new environment and old that has been torn down"
+    )
     initialized: bool = Field(description="blueapi context initialized")
     error_message: str | None = Field(
         default=None,
diff --git a/src/blueapi/service/runner.py b/src/blueapi/service/runner.py
index d8d957055..508ee3677 100644
--- a/src/blueapi/service/runner.py
+++ b/src/blueapi/service/runner.py
@@ -1,6 +1,7 @@
 import inspect
 import logging
 import signal
+import uuid
 from collections.abc import Callable
 from importlib import import_module
 from multiprocessing import Pool, set_start_method
@@ -57,6 +58,7 @@ def default_subprocess_factory():
         self._subprocess = None
         self._subprocess_factory = subprocess_factory or default_subprocess_factory
         self._state = EnvironmentResponse(
+            environment_id=uuid.uuid4(),
             initialized=False,
         )
 
@@ -69,12 +71,17 @@ def reload(self):
 
     @start_as_current_span(TRACER)
     def start(self):
+        new_environment_id = uuid.uuid4()
         try:
             self._subprocess = self._subprocess_factory()
             self.run(setup, self._config)
-            self._state = EnvironmentResponse(initialized=True)
+            self._state = EnvironmentResponse(
+                environment_id=new_environment_id,
+                initialized=True,
+            )
         except Exception as e:
             self._state = EnvironmentResponse(
+                environment_id=new_environment_id,
                 initialized=False,
                 error_message=str(e),
             )
@@ -82,17 +89,20 @@ def start(self):
 
     @start_as_current_span(TRACER)
     def stop(self):
+        existing_environment_id = self._state.environment_id
         try:
             self.run(teardown)
             if self._subprocess is not None:
                 self._subprocess.close()
                 self._subprocess.join()
             self._state = EnvironmentResponse(
+                environment_id=existing_environment_id,
                 initialized=False,
                 error_message=self._state.error_message,
             )
         except Exception as e:
             self._state = EnvironmentResponse(
+                environment_id=existing_environment_id,
                 initialized=False,
                 error_message=str(e),
             )