🔥🔥 btrace (AKA RheaTrace) is a high-performance Android & iOS tracing tool built on Perfetto. It not only times your methods but also reveals why they’re slow.
C++
2,548
63 commits
updated Jun 9, 2026
We are proud to announce the launch of btrace 3.0, introducing an industry-first high-performance synchronized sampling-based tracing solution. Additionally, the new version now provides comprehensive iOS tracing capabilities. We have also extended btrace to HarmonyOS, providing on-device SDK and command-line tooling to capture trace data and quickly locate performance issues for HarmonyOS apps.
Add dependencies in app/build.gradle file:
dependencies {
if (enable_btrace == 'true') {
implementation 'com.bytedance.btrace:rhea-inhouse:3.0.0'
} else {
implementation 'com.bytedance.btrace:rhea-inhouse-noop:3.0.0'
}
}
Add enable_btrace switch in the gradle.properties file:
# Turn on this switch when you want to build app that support tracing.
enable_btrace=false
Add initialization code in attachBaseContext() method of your Application:
public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// When rhea-inhouse-noop is used, RheaTrace3.init() has empty implementation.
RheaTrace3.init(base);
}
}
To use btrace 3.0, follow these instructions:
java -jar rhea-trace-shell.jar -a ${your_package_name} -t 10 -o output.pb -r sched
| Version | Release Date | jar | Release Notes |
|---|---|---|---|
| 3.0.0 | 2025-06-10 | rhea-trace-shell-3.0.0.jar | 3.0 first release |
| Parameter | Default Value | Description |
|---|---|---|
| -a $applicationName | N/A | Specifies the package name of your app |
| Parameter | Default Value | Description |
|---|---|---|
| -o $outputPath | ${applicationName}_yyyy_MM_dd_HH_mm_ss.pb | Specifies the path where the trace artifact is saved. By default, the value is autogenerated based on the tracing app package name and current timestamp. |
| -t $timeInSecond | 5 | Specifies the duration of the tracing, in seconds. Note that: On MacOS, interactive tracing mode will be activated if you don't specifying the tracing duration. On windows, tracing dration must be specified, because we don't support interactive tracing mode on Windows currently. |
| -m $mappingPath | Specifies the mapping file path for the abofuscated app. Note that: it's not the methodMapping file that was used in btrace 2.0, but the mapping file generated by proguard. There is no methodMapping file in btrace 3.0. | |
| -mode $mode | Decided at runtime. | btrace currently support two kinds of modes:
|
| -maxAppTraceBufferSize $size | 200000 | Specifies the maximum count of stacktraces that our buffer allows to save, previously saved stacktraces will be overwritten if the maximum limit is met. |
| -sampleInterval $ns | 1000000 | Specifies the minimum sampling backtracing interval in nanoseconds. |
| -waitTraceTimeout | 20 | Specifies the timeout seconds for waiting for tracing data writing to complete and being pulled to the PC. |
| -s $serial | Specifies the device connected by adb. | |
| -r | Automatically restarts the app to tracing the start up stage. | |
| --list | Displays a list of supported atrace categories for the device. |
| Problems | Advices | |
|---|---|---|
| 1 | We currently only support devices running Android 8.0 or higher. | Please use devices with Android 8.0 or higher. |
| 2 | Java object allocation monitoring is not yet adapted for devices with Android 15 and above. | If you need to inspect object memory allocation information or require more detailed tracing, please use devices with Android versions below 15. |
| 3 | Devices that do not support Perfetto (mostly systems before 8.1) cannot collect system information such as CPU scheduling. | Try with -mode simple. |
| 4 | 32-bit devices or applications cannot collect tracing data. | Please install and use 64-bit applications on 64-bit devices. |
Record trace data offline without Instruments to help find performance issue of your app.
Clone source code, and add the following lines to your Podfile:
pod 'BTrace', :subspecs => ['Core', 'Debug'], :path => 'xxx/btrace-iOS'
pod 'fishhook', :git => 'https://github.com/facebook/fishhook.git', :branch => 'main'
Install command line tool:
# using homebrew
brew install libusbmuxd
brew install poetry
# install from the BTraceTool directory
poetry install
Activate the virtual environment before executing commands.
# activate from the BTraceTool directory
poetry shell
# or
poetry env activate
Note that if '-l' is not specified, app must have been launched before recording.
python3 -m btrace record [-h] [-i DEVICE_ID] [-b BUNDLE_ID] [-o OUTPUT] [-t TIME_LIMIT] [-d DSYM_PATH] [-m] [-l] [-s]
| Option | Description |
|---|---|
| -h, --help | Show help |
| -i DEVICE_ID, --device_id DEVICE_ID | Device id. If not specified: · If only one device is connected to Mac, it will be chosen · If multiple devices are connected to Mac, prompt the user to make a selection |
| -b BUNDLE_ID --bundle_id BUNDLE_ID | Bundle id |
| -o OUTPUT --output OUTPUT | Output path. If not specified, data will be saved to '~/Desktop/btrace' |
| -t TIME_LIMIT --time_limit TIME_LIMIT | Limit recording time, default 3600s |
| -d DSYM_PATH --dsym_path DSYM_PATH | Dsym file path, or app path built by Xcode in debug mode. If specified,flamegraph will be displayed automatically after the recording ends |
| -m --main_thread_only | If given, only record main thread trace data |
| -l --launch | If given, app will be launched/relaunched, and start recording on app launch |
| -s --sys_symbol | If given, symbols in the system libraries will be parsed |
python3 -m btrace record -i xxx -b xxx -d /xxxDebug-iphoneos/xxx.app
python3 -m btrace record -i xxx -b xxx -d /xxxDebug-iphoneos/xxx.dSYM
ctrl + c
When should the 'parse' command used?
python3 -m btrace parse [-h] [-d DSYM_PATH] [-f] [-s] file_path
| Option | Description |
|---|---|
| -h, --help | Show help |
| -d DSYM_PATH, --dsym_path DSYM_PATH | Dsym file path, or app path built by Xcode in debug mode |
| -s, --sys_symbol | If given, symbols in the system libraries will be parsed |
| -f, --force | If given, force re-parsing trace data |
btrace parse -d /xxx.dSYM xxx.sqlite
btrace parse -d /xxx.app xxx.sqlite
Record trace data for HarmonyOS apps to help find performance issues.
Add the on-device SDK to your HarmonyOS project via ohpm:
ohpm install @bytedance/btrace
Initialize the offline server as early as possible during app startup:
import { OfflineServer } from '@bytedance/btrace'
OfflineServer.Init()
hdc tool is required to operate apps on the device. Add it to your PATH:export PATH="/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains:$PATH"
llvm-addr2line. Add it to your PATH:export PATH="/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/native/llvm/bin:$PATH"
harmony-trace-cli jar and place it under ~/.oh_trace_cli directory.Note: The download artifacts will be published with the official release. Please stay tuned.
Run the following command in the directory where harmony-trace-cli.jar is located:
java -jar harmony-trace-cli.jar -b ${your_bundle_name} -t 10
The above command starts tracing for the given bundle from its current foreground page, samples all threads for 10 seconds, saves the result to the current directory and automatically generates a flame graph.
ctrl + c
Stops the tracing and automatically exports the trace file from the app sandbox.
| Parameter | Default Value | Description |
|---|---|---|
| -b, --bundle_name $bundleName | N/A | Specifies the bundle name of your app. |
| Parameter | Default Value | Description |
|---|---|---|
| -h, --help | Show help. | |
| -k, --key $deviceKey | Specifies the device connected by hdc.
| |
| -o, --output_path $outputPath | ~/Desktop/ohtrace | Specifies the path where the trace artifact is saved. |
| -t, --time_limit $timeLimit | 60 | Specifies the maximum tracing duration in seconds. Tracing will stop automatically when the duration is reached. |
| -N, --native_path $nativePath | Absolute path to the directory containing native .so files for symbolication. | |
| -s, --source_mapping $sourceMapping | Absolute path to the sourceMap file. | |
| -n, --name_cache $nameCache | Absolute path to the NameCache file. | |
| -i, --sample_interval $sampleInterval | Sampling interval.
| |
| -H, --high_freq | Enable high-frequency sampling mode. | |
| -S, --buffer_size $bufferSize | Specifies how many call stack samples can be stored. | |
| -m, --main_only | Only collect call stacks of the main thread. | |
| -r, --restart | Launch / relaunch the app and start tracing from the launch stage. | |
| -sp, --skip_perfetto | Skip generating the flame graph via Perfetto after the trace is exported. | |
| -a, --all_symbol | Display all symbols including system symbols (system symbols are hidden by default). |
harmony-trace-cli command-line tool only supports macOS at the moment; Windows / Linux support will be added in future releases..so files via -N, --native_path, and the CLI tool will perform symbolication offline.If you are interested in the internal details of btrace 3.0, you can refer to the document: btrace 3.0 Internal Principle in Detail! .
We've made a lot of improvements in btrace 3.0, including better error prompts. There might still be some cases where the prompts aren't accurate enough or the messages aren't clear. If you run into any issues, just give us a shout in the Lark group below, and we'll do our best to help you out. We always appreciate any other feedback or suggestions you might have too, thanks you!

385 followers · starred Jun 2025
123 followers · starred Oct 2023
82 followers · starred Apr 2024
149 followers · starred Dec 2021
🔥🔥 btrace (AKA RheaTrace) is a high-performance Android & iOS tracing tool built on Perfetto. It not only times your methods but also reveals why they’re slow.
C++
2,548
63 commits
updated Jun 9, 2026
We are proud to announce the launch of btrace 3.0, introducing an industry-first high-performance synchronized sampling-based tracing solution. Additionally, the new version now provides comprehensive iOS tracing capabilities. We have also extended btrace to HarmonyOS, providing on-device SDK and command-line tooling to capture trace data and quickly locate performance issues for HarmonyOS apps.
Add dependencies in app/build.gradle file:
dependencies {
if (enable_btrace == 'true') {
implementation 'com.bytedance.btrace:rhea-inhouse:3.0.0'
} else {
implementation 'com.bytedance.btrace:rhea-inhouse-noop:3.0.0'
}
}
Add enable_btrace switch in the gradle.properties file:
# Turn on this switch when you want to build app that support tracing.
enable_btrace=false
Add initialization code in attachBaseContext() method of your Application:
public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// When rhea-inhouse-noop is used, RheaTrace3.init() has empty implementation.
RheaTrace3.init(base);
}
}
To use btrace 3.0, follow these instructions:
java -jar rhea-trace-shell.jar -a ${your_package_name} -t 10 -o output.pb -r sched
| Version | Release Date | jar | Release Notes |
|---|---|---|---|
| 3.0.0 | 2025-06-10 | rhea-trace-shell-3.0.0.jar | 3.0 first release |
| Parameter | Default Value | Description |
|---|---|---|
| -a $applicationName | N/A | Specifies the package name of your app |
| Parameter | Default Value | Description |
|---|---|---|
| -o $outputPath | ${applicationName}_yyyy_MM_dd_HH_mm_ss.pb | Specifies the path where the trace artifact is saved. By default, the value is autogenerated based on the tracing app package name and current timestamp. |
| -t $timeInSecond | 5 | Specifies the duration of the tracing, in seconds. Note that: On MacOS, interactive tracing mode will be activated if you don't specifying the tracing duration. On windows, tracing dration must be specified, because we don't support interactive tracing mode on Windows currently. |
| -m $mappingPath | Specifies the mapping file path for the abofuscated app. Note that: it's not the methodMapping file that was used in btrace 2.0, but the mapping file generated by proguard. There is no methodMapping file in btrace 3.0. | |
| -mode $mode | Decided at runtime. | btrace currently support two kinds of modes:
|
| -maxAppTraceBufferSize $size | 200000 | Specifies the maximum count of stacktraces that our buffer allows to save, previously saved stacktraces will be overwritten if the maximum limit is met. |
| -sampleInterval $ns | 1000000 | Specifies the minimum sampling backtracing interval in nanoseconds. |
| -waitTraceTimeout | 20 | Specifies the timeout seconds for waiting for tracing data writing to complete and being pulled to the PC. |
| -s $serial | Specifies the device connected by adb. | |
| -r | Automatically restarts the app to tracing the start up stage. | |
| --list | Displays a list of supported atrace categories for the device. |
| Problems | Advices | |
|---|---|---|
| 1 | We currently only support devices running Android 8.0 or higher. | Please use devices with Android 8.0 or higher. |
| 2 | Java object allocation monitoring is not yet adapted for devices with Android 15 and above. | If you need to inspect object memory allocation information or require more detailed tracing, please use devices with Android versions below 15. |
| 3 | Devices that do not support Perfetto (mostly systems before 8.1) cannot collect system information such as CPU scheduling. | Try with -mode simple. |
| 4 | 32-bit devices or applications cannot collect tracing data. | Please install and use 64-bit applications on 64-bit devices. |
Record trace data offline without Instruments to help find performance issue of your app.
Clone source code, and add the following lines to your Podfile:
pod 'BTrace', :subspecs => ['Core', 'Debug'], :path => 'xxx/btrace-iOS'
pod 'fishhook', :git => 'https://github.com/facebook/fishhook.git', :branch => 'main'
Install command line tool:
# using homebrew
brew install libusbmuxd
brew install poetry
# install from the BTraceTool directory
poetry install
Activate the virtual environment before executing commands.
# activate from the BTraceTool directory
poetry shell
# or
poetry env activate
Note that if '-l' is not specified, app must have been launched before recording.
python3 -m btrace record [-h] [-i DEVICE_ID] [-b BUNDLE_ID] [-o OUTPUT] [-t TIME_LIMIT] [-d DSYM_PATH] [-m] [-l] [-s]
| Option | Description |
|---|---|
| -h, --help | Show help |
| -i DEVICE_ID, --device_id DEVICE_ID | Device id. If not specified: · If only one device is connected to Mac, it will be chosen · If multiple devices are connected to Mac, prompt the user to make a selection |
| -b BUNDLE_ID --bundle_id BUNDLE_ID | Bundle id |
| -o OUTPUT --output OUTPUT | Output path. If not specified, data will be saved to '~/Desktop/btrace' |
| -t TIME_LIMIT --time_limit TIME_LIMIT | Limit recording time, default 3600s |
| -d DSYM_PATH --dsym_path DSYM_PATH | Dsym file path, or app path built by Xcode in debug mode. If specified,flamegraph will be displayed automatically after the recording ends |
| -m --main_thread_only | If given, only record main thread trace data |
| -l --launch | If given, app will be launched/relaunched, and start recording on app launch |
| -s --sys_symbol | If given, symbols in the system libraries will be parsed |
python3 -m btrace record -i xxx -b xxx -d /xxxDebug-iphoneos/xxx.app
python3 -m btrace record -i xxx -b xxx -d /xxxDebug-iphoneos/xxx.dSYM
ctrl + c
When should the 'parse' command used?
python3 -m btrace parse [-h] [-d DSYM_PATH] [-f] [-s] file_path
| Option | Description |
|---|---|
| -h, --help | Show help |
| -d DSYM_PATH, --dsym_path DSYM_PATH | Dsym file path, or app path built by Xcode in debug mode |
| -s, --sys_symbol | If given, symbols in the system libraries will be parsed |
| -f, --force | If given, force re-parsing trace data |
btrace parse -d /xxx.dSYM xxx.sqlite
btrace parse -d /xxx.app xxx.sqlite
Record trace data for HarmonyOS apps to help find performance issues.
Add the on-device SDK to your HarmonyOS project via ohpm:
ohpm install @bytedance/btrace
Initialize the offline server as early as possible during app startup:
import { OfflineServer } from '@bytedance/btrace'
OfflineServer.Init()
hdc tool is required to operate apps on the device. Add it to your PATH:export PATH="/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains:$PATH"
llvm-addr2line. Add it to your PATH:export PATH="/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/native/llvm/bin:$PATH"
harmony-trace-cli jar and place it under ~/.oh_trace_cli directory.Note: The download artifacts will be published with the official release. Please stay tuned.
Run the following command in the directory where harmony-trace-cli.jar is located:
java -jar harmony-trace-cli.jar -b ${your_bundle_name} -t 10
The above command starts tracing for the given bundle from its current foreground page, samples all threads for 10 seconds, saves the result to the current directory and automatically generates a flame graph.
ctrl + c
Stops the tracing and automatically exports the trace file from the app sandbox.
| Parameter | Default Value | Description |
|---|---|---|
| -b, --bundle_name $bundleName | N/A | Specifies the bundle name of your app. |
| Parameter | Default Value | Description |
|---|---|---|
| -h, --help | Show help. | |
| -k, --key $deviceKey | Specifies the device connected by hdc.
| |
| -o, --output_path $outputPath | ~/Desktop/ohtrace | Specifies the path where the trace artifact is saved. |
| -t, --time_limit $timeLimit | 60 | Specifies the maximum tracing duration in seconds. Tracing will stop automatically when the duration is reached. |
| -N, --native_path $nativePath | Absolute path to the directory containing native .so files for symbolication. | |
| -s, --source_mapping $sourceMapping | Absolute path to the sourceMap file. | |
| -n, --name_cache $nameCache | Absolute path to the NameCache file. | |
| -i, --sample_interval $sampleInterval | Sampling interval.
| |
| -H, --high_freq | Enable high-frequency sampling mode. | |
| -S, --buffer_size $bufferSize | Specifies how many call stack samples can be stored. | |
| -m, --main_only | Only collect call stacks of the main thread. | |
| -r, --restart | Launch / relaunch the app and start tracing from the launch stage. | |
| -sp, --skip_perfetto | Skip generating the flame graph via Perfetto after the trace is exported. | |
| -a, --all_symbol | Display all symbols including system symbols (system symbols are hidden by default). |
harmony-trace-cli command-line tool only supports macOS at the moment; Windows / Linux support will be added in future releases..so files via -N, --native_path, and the CLI tool will perform symbolication offline.If you are interested in the internal details of btrace 3.0, you can refer to the document: btrace 3.0 Internal Principle in Detail! .
We've made a lot of improvements in btrace 3.0, including better error prompts. There might still be some cases where the prompts aren't accurate enough or the messages aren't clear. If you run into any issues, just give us a shout in the Lark group below, and we'll do our best to help you out. We always appreciate any other feedback or suggestions you might have too, thanks you!

385 followers · starred Jun 2025
123 followers · starred Oct 2023
82 followers · starred Apr 2024
149 followers · starred Dec 2021