Performance Overhead
Learn about how enabling Session Replay impacts the performance of your application.
If you're considering enabling Session Replay, it's important to first understand the potential performance impact to your app. While accurate metrics require realistic testing where you apply typical access patterns and correlate the results with your business metrics, to provide a baseline, we measured the overhead using the open-source Pocket Casts app.
You can learn more about the various performance overhead optimizations implemented in the iOS Replay SDK in the Replay Performance Overhead docs.
Important
On older iOS devices (iPhone 8 and earlier, or devices with equivalent hardware), Session Replay can cause visible scrolling stutter and dropped frames during UI animations. This is due to the screenshot capture process blocking the main thread.
Session Replay works by capturing screenshots of your app once per second. This capture process must run on the main thread because it accesses the view hierarchy. On modern devices (iPhone X and newer), this overhead is imperceptible. However, on older devices with less powerful processors, the time required to capture each screenshot can exceed the available frame budget, causing frames to be dropped.
What this looks like in practice:
- Scrolling may appear jerky or stuttery rather than smooth
- UI animations may skip frames
- Touch responsiveness may feel slightly delayed during the capture moment
Devices most affected:
- Older devices like iPhone 8 and earlier
- Older iPad models
Scenarios that increase the likelihood of stutter:
- Heavy or complex animations that already consume significant CPU time
- Screens with deeply nested view hierarchies
- Apps performing intensive background work on the main thread
When your app is already pushing the device's capabilities with animations or complex UI, the additional overhead from Session Replay's screenshot capture can tip the frame budget over the limit, causing visible stutter. This is especially true on older devices where the CPU has less headroom.
If your app targets these older devices and smooth scrolling or animation performance is critical, consider disabling Session Replay on low-end devices or using a lower sample rate.
The Pocket Casts app offers a diverse mix of components making it an ideal candidate for testing. Here's how the benchmarks were conducted:
- Configuration: Full masking was enabled, and optimized release builds were used.
- User Flow: The same flow was executed 10 times to ensure consistency.
- Real-World Representation: This approach closely mirrors performance in real-world scenarios.
The benchmarks were run on an iPhone 14 Pro.
Below are the results of the benchmarking tests, presented as median values to reflect typical overhead.
| Metric | Sentry SDK only | Sentry + Replay SDK |
|---|---|---|
| FPS | 55 fps | 53 fps |
| Memory | 102 MB | 121 MB |
| CPU | 4% | 13% |
| App Startup Time (Cold) | 1264.80 ms | 1265 ms |
| Main Thread Time | n/a | ~25ms per capture |
| Network Bandwidth | n/a | 10 KB/s of recording |
These benchmarks represent performance on modern devices (iPhone 14 Pro). On older devices like iPhone 8, the main thread time per capture can be higher, potentially causing visible frame drops during scrolling and animations. See Performance on Older Devices above.
Session Replay captures one screenshot per second. During each capture:
- Redaction phase: The SDK traverses the view hierarchy to identify elements requiring privacy masking (~6ms on iPhone 8)
- Render phase: The current view is rendered into a bitmap image (~25ms on iPhone 8 with View Renderer V2)
iOS displays at 60 FPS, giving each frame a budget of ~16.7ms. When the capture process exceeds this budget, frames are dropped. With View Renderer V2 (the default since SDK v8.50.0), the render phase takes approximately 25ms on older devices like iPhone 8, which can cause 1-2 frames to be dropped once per second during the capture moment.
While this overhead is minimal for most use cases, it can be noticeable during fast scrolling or complex animations on older devices.
To minimize the performance impact of the Replay SDK, consider the following options:
Lowering the quality of captured screenshots and videos can reduce CPU, memory, and network bandwidth usage:
SentrySDK.start(configureOptions: { options in
// Reduces screenshot compression quality and video bitrate to 50kbps
options.sessionReplay.quality = .low // defaults to .medium
})
If Session Replay causes performance issues on older devices, you can disable it specifically for those devices by checking the device model at runtime and setting the sample rates to zero:
SentrySDK.start(configureOptions: { options in
options.dsn = "___PUBLIC_DSN___"
if isLowEndDevice() {
options.sessionReplay.onErrorSampleRate = 0.0
options.sessionReplay.sessionSampleRate = 0.0
} else {
options.sessionReplay.onErrorSampleRate = 1.0
options.sessionReplay.sessionSampleRate = 0.1
}
})
You can use Sentry's device classification as a reference for determining which devices to consider low-end.
For additional performance gains at the cost of some rendering accuracy, you can enable fast view rendering:
SentrySDK.start(configureOptions: { options in
options.sessionReplay.enableFastViewRendering = true
})
Fast view rendering uses CALayer.render(in:) instead of UIView.drawHierarchy(in:afterScreenUpdates:). While faster, this can result in some UI elements (such as SF Symbols in tab bars) not appearing in the replay. Use this option only if the standard renderer causes unacceptable performance issues.
Starting with v8.50.0, View Renderer V2 is enabled by default. This renderer provides up to 5x faster screenshot capture compared to the original implementation, significantly reducing main thread blocking time and frame drops.
Performance comparison on iPhone 8:
| Renderer | Time per capture | Frames dropped per capture |
|---|---|---|
| V1 (old) | ~155ms | 9-10 frames |
| V2 (new) | ~25ms | 1-2 frames |
If you're using SDK version 8.47.0 to 8.49.x, you can enable View Renderer V2 early:
SentrySDK.start(configureOptions: { options in
options.sessionReplay.enableExperimentalViewRenderer = true
})
If you experience issues with View Renderer V2 and need to fall back to the original renderer:
SentrySDK.start(configureOptions: { options in
options.sessionReplay.enableViewRendererV2 = false
})
The original view renderer (V1) will be deprecated and removed in a future release.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").