diff --git a/docs/platforms/unreal/configuration/app-hangs/index.mdx b/docs/platforms/unreal/configuration/app-hangs/index.mdx
index ab86271b5e0c8d..732950ba266881 100644
--- a/docs/platforms/unreal/configuration/app-hangs/index.mdx
+++ b/docs/platforms/unreal/configuration/app-hangs/index.mdx
@@ -4,18 +4,25 @@ sidebar_order: 11
description: "Learn how to detect and report application hangs in your Unreal Engine game."
---
-Application hang errors are triggered when a thread monitored by Unreal Engine's heartbeat system becomes unresponsive for longer than a configurable timeout. The Unreal SDK reports hang errors as Sentry events.
+Application hang errors are triggered when a monitored thread becomes unresponsive for longer than a configurable timeout. The Unreal SDK reports hang errors as Sentry events.
Trying to play an unresponsive game is extremely frustrating for users. There are many reasons why an app may become unresponsive, such as long-running computations on the game thread, infinite loops, deadlocks, and so on. With app hang tracking you can detect and fix them.
+The SDK can detect hangs in one of two ways:
+
+- **Engine watcher** (default) — hooks into Unreal Engine's built-in `FThreadHeartBeat` system.
+- **Native watchdog** — uses the sentry-native SDK's built-in app-hang detector.
+
-This feature is available on Windows and Linux only. On macOS and iOS, the Cocoa SDK provides its own app hang detection. On Android, the Java SDK provides its own ANR detection.
+The engine watcher is available on Windows and Linux. The native watchdog is available on Windows, Linux, and macOS (which needs the native backend). On macOS and iOS, the Cocoa SDK provides its own app hang detection. On Android, the Java SDK provides its own ANR detection.
## How It Works
+### Engine Watcher (Default)
+
The SDK hooks into Unreal Engine's built-in `FThreadHeartBeat` system, which monitors threads that participate in the engine's heartbeat (game thread, render thread, audio thread, etc.):
1. The engine runs a background thread that periodically checks whether monitored threads are still sending heartbeats.
@@ -24,16 +31,33 @@ The SDK hooks into Unreal Engine's built-in `FThreadHeartBeat` system, which mon
4. If the thread is still unresponsive when the timeout expires, the SDK captures a hang event with the stuck thread's stack trace and sends it to Sentry.
5. If the thread recovers before the timeout, the hang is not reported.
-The hang event includes:
-- Event level: `error`
-- Exception type: `App Hanging`
-- Exception value: `Application not responding`
-- Mechanism type: `AppHang`
-- Stack trace of the hung thread
+This mechanism requires additional engine configuration — see [Engine Watcher Setup](#engine-watcher-setup).
+
+### Native Watchdog
+
+When UseNativeHangTracking is enabled, hangs are detected by the sentry-native SDK's built-in app-hang watchdog instead:
+
+1. After initialization, the SDK registers a lightweight heartbeat on the game thread that fires once per frame (`FCoreDelegates::OnEndFrame`). The first tick latches the game thread as the monitored thread, and each subsequent frame refreshes the heartbeat.
+2. sentry-native runs a watchdog thread that monitors how long it has been since the last heartbeat.
+3. If the game thread doesn't report a heartbeat within the configured hang timeout, the watchdog captures a hang event with the game thread's stack trace and sends it to Sentry.
+4. Detection resumes automatically once the thread becomes responsive again.
+
+Unlike the engine watcher, this mechanism doesn't depend on the engine's heartbeat configuration.
+
+## Configuration
+
+App hang tracking is disabled by default. To enable it, navigate to **Project Settings > Plugins > Sentry > General > Native** and toggle **Enable hang tracking**.
+
+Alternatively, add the following to your project's configuration file:
-## Prerequisites
+```ini {filename:DefaultEngine.ini}
+[/Script/Sentry.SentrySettings]
+EnableHangTracking=True
+```
-The engine's heartbeat monitor thread must be enabled for hang tracking to work. By default, `HangDuration` in `[Core.System]` is set to `0`, which disables the heartbeat monitor. Set it to a value greater than `0` in your project's `DefaultEngine.ini`:
+### Engine Watcher Setup
+
+The engine watcher relies on Unreal Engine's heartbeat monitor thread, which is disabled by default — `HangDuration` in `[Core.System]` is set to `0`. Set it to a value greater than `0` in your project's `DefaultEngine.ini` to enable the monitor:
```ini {filename:DefaultEngine.ini}
[Core.System]
@@ -42,20 +66,23 @@ HangDuration=25
`HangDuration` is the threshold (in seconds) after which the engine reports a hang to the [Crash Reporter Client](/platforms/unreal/configuration/crash-reporter/crash-reporter-client/). The Sentry SDK's hang tracking coexists with the engine's mechanism — the SDK hooks into the heartbeat system independently and captures its own events based on the hang timeout you configure.
-## Configuration
+This setup isn't required for the native watchdog.
-App hang tracking is disabled by default. To enable it, navigate to **Project Settings > Plugins > Sentry > General > Native** and toggle **Enable hang tracking**.
+### Native App Hang Detection
-Alternatively, add the following to your project's configuration file:
+To detect hangs with the sentry-native SDK's app-hang watchdog instead of the engine watcher, also toggle **Use native hang tracking** under **Project Settings > Plugins > Sentry > General > Native**, or add it to the configuration file:
```ini {filename:DefaultEngine.ini}
[/Script/Sentry.SentrySettings]
EnableHangTracking=True
+UseNativeHangTracking=True
```
+On macOS, this option requires the native backend.
+
### Hang Timeout
-The hang timeout controls how long a thread must be unresponsive before a hang event is captured. The default is 5 seconds, with a minimum of 1 second.
+The hang timeout controls how long the thread must be unresponsive before a hang event is captured. The default is 5 seconds, with a minimum of 1 second.
You can adjust it in **Project Settings > Plugins > Sentry > General > Native > Hang timeout (seconds)**, or via the configuration file:
@@ -64,11 +91,11 @@ You can adjust it in **Project Settings > Plugins > Sentry > General > Native >
HangTimeoutDuration=5.0
```
-If the configured timeout is shorter than the engine's `StuckDuration`, it will be automatically adjusted upward to match, since the SDK can only start tracking after the engine reports a thread as stuck.
+With the engine watcher, if the configured timeout is shorter than the engine's `StuckDuration`, it will be automatically adjusted upward to match, since the SDK can only start tracking after the engine reports a thread as stuck.
## Filtering Hang Events
-You can filter or modify hang events using the `BeforeSend` callback. The `USentryEvent` class provides an `IsAnr()` method that returns `true` for hang events (exception type `App Hanging`):
+You can filter or modify hang events using the `BeforeSend` callback. The `USentryEvent` class provides an `IsAnr()` method that returns `true` for hang events captured by either detection mechanism:
```cpp
UCLASS()
@@ -90,8 +117,9 @@ public:
## Limitations
-- **Packaged builds only**: Hang tracking does not work in the editor or in debug build configurations. The engine's `USE_HANG_DETECTION` macro must be enabled, which is only the case in packaged non-debug builds.
-- **No early-startup detection**: Hangs that occur before `FEngineLoop::Tick()` starts (e.g. during `GameInstance::Init()`) are not detected, because threads must have sent at least one heartbeat before they can be monitored.
-- **Requires engine configuration**: The `HangDuration` setting in `[Core.System]` must be set to a value greater than `0`. Without it, the engine's heartbeat monitor thread doesn't run.
-- **One thread at a time**: If multiple threads become stuck simultaneously, only one hang is reported per episode. The engine's `FThreadHeartBeat` reports one stuck thread at a time, so additional stuck threads are only detected after the first one recovers.
-- **Not supported on macOS with native backend**: Hang tracking is not available when using the native backend on macOS.
+- **Packaged builds only (engine watcher)**: The engine watcher does not work in the editor or in debug build configurations. The engine's `USE_HANG_DETECTION` macro must be enabled, which is only the case in packaged non-debug builds. The native watchdog is not subject to this restriction.
+- **No early-startup detection**: Hangs that occur before `FEngineLoop::Tick()` starts (e.g. during `GameInstance::Init()`) are not detected, because the monitored thread must report at least one heartbeat before it can be watched.
+- **Requires engine configuration (engine watcher)**: The `HangDuration` setting in `[Core.System]` must be set to a value greater than `0`. Without it, the engine's heartbeat monitor thread doesn't run. The native watchdog doesn't require this.
+- **One thread at a time (engine watcher)**: If multiple threads become stuck simultaneously, only one hang is reported per episode. The engine's `FThreadHeartBeat` reports one stuck thread at a time, so additional stuck threads are only detected after the first one recovers.
+- **Game thread only (native watchdog)**: The native watchdog monitors the game thread.
+- **macOS requires the native backend**: On macOS, hang tracking is only available through the native watchdog with the native backend enabled. The engine watcher is not available on macOS.
diff --git a/docs/platforms/unreal/configuration/options.mdx b/docs/platforms/unreal/configuration/options.mdx
index 744411e57b05a4..ba4ebb96437fe8 100644
--- a/docs/platforms/unreal/configuration/options.mdx
+++ b/docs/platforms/unreal/configuration/options.mdx
@@ -189,7 +189,7 @@ See Native Backend
-This feature is experimental and under active development. Supported on Windows and Linux only.
+This feature is experimental and under active development. Supported on Windows, Linux, and macOS.
@@ -225,13 +225,13 @@ This feature is supported on Windows and Linux only.
-Tracks application hangs (unresponsive threads) using Unreal Engine's built-in `FThreadHeartBeat`. When enabled, the SDK launches a watchdog thread that monitors engine heartbeat delegates and captures a hang event if a thread remains unresponsive for longer than the configured timeout.
+Tracks application hangs (unresponsive game thread) and captures a hang event when the thread stays unresponsive for longer than the configured timeout. By default, detection uses Unreal Engine's built-in `FThreadHeartBeat` watcher; enable to use the sentry-native SDK's app-hang detector instead.
This option is turned off by default.
-This feature is available on Windows and Linux only, and only works in packaged non-debug builds. See App Hangs for setup details and prerequisites.
+The default engine-based detection is available on Windows and Linux only, and only works in packaged non-debug builds. See App Hangs for setup details and prerequisites.
@@ -239,12 +239,26 @@ This feature is available on Windows and Linux only, and only works in packaged
-Duration in seconds that a thread must be unresponsive before a hang event is captured. The minimum value is `1.0` second. If set below the engine's `StuckDuration` (default 1 second), it is automatically adjusted upward.
+Duration in seconds that a thread must be unresponsive before a hang event is captured. The minimum value is `1.0` second. With the engine-based detector, if set below the engine's `StuckDuration` (default 1 second), it is automatically adjusted upward.
Only takes effect when is enabled.
+
+
+Detects hangs using the sentry-native SDK's built-in app-hang watchdog instead of Unreal Engine's `FThreadHeartBeat` watcher. It doesn't depend on the engine's heartbeat configuration.
+
+Only takes effect when is enabled.
+
+
+
+This feature is available on Windows, Linux, and macOS. On macOS it requires the native backend. See App Hangs for details.
+
+
+
+
+
## Hooks
These options can be used to hook the SDK in various ways to customize the reporting of events.