diff --git a/docs/ex_performance_metrics.md b/docs/ex_performance_metrics.md
new file mode 100644
index 0000000..d72626b
--- /dev/null
+++ b/docs/ex_performance_metrics.md
@@ -0,0 +1,80 @@
+# EX Performance metrics
+
+| Status | Last updated |
+|--|--|
+| In progress | December 22, 2025 |
+
+
+
+## Objective
+Crashes are already tracked on Sentry. Performance metrics are also useful health metrics to check. They can be tracked by Sentry too.
+
+This document specifies what metrics we track and how we measure them. It focuses on EX but it could be extended (and renamed) to track any matrix client app performance.
+
+## Sentry semantics
+As we use Sentry, we need to adopt its naming conventions for `Transaction(name: String, operation: String)` and `Span(operation: String, description: String)`.
+More information can be found in the Sentry documentation about [Transaction Name](https://docs.sentry.io/platforms/native/enriching-events/transaction-name/) and [Span Operations](https://develop.sentry.dev/sdk/performance/span-operations/).
+
+## UX metrics
+
+They are tracked using Sentry transactions. `Transaction.operation` is `ux` to reflect high-level, user journey metrics.
+
+| Metric (Sentry Transaction Name) | Description | Initial and final conditions | Tech metrics | Notes |
+| :---- | :---- | :---- | :---- | :---- |
+| Cached room list | Cold start until the cached room list is displayed | From:- The user is already logged in
- The app is not running in background
- The user taps on the app icon
To:- The room list is fully loaded from the permanent cache and displayed to the end user |
- First rooms displayed after login or restoration (**TBD**)
| The clock starts after the Sentry is initialised. |
+| Up-to-date room list | The app syncs and the room list becomes up-to-date | From:- The app was inactive in background and get debackgrounded
- Or the app just finished its cold start
To:- The room list service state becomes [`Running`](https://github.com/matrix-org/matrix-rust-sdk/blob/matrix-sdk-ui-0.14.0/bindings/matrix-sdk-ffi/src/sync_service.rs#L36)
- No more Syncing spinner | | The expected final conditions should be:
- The room list is updated
- Properly sorted
- Last messages are up-to-date
But we need more work to compute this metric. |
+| Notification to message | A notification was tapped and it opened a timeline | From:- The app is in background or active
- The notification is for a message in the main timeline
- The user taps on the notification
To:- The message is visible in the timeline
- The timeline around this message is fully loaded | | |
+| Open a room | Open a room and see loaded items in the timeline | From:
- User taps a room from the room list
To:- The timeline is fully loaded with first items loaded | | |
+| Send a message | Send to sent state in timeline | From:
- User hits the send button
To:- The timeline shows it as sent | | The `RoomSendQueueUpdate` enum in the SDK can be used for this: `NewLocalEvent` being returned means the event is in the send queue, `SentEvent` means we received it in the sync. We don't really know when it lands on the timeline, but the delay should be minimal. |
+
+## Additional data
+
+We need to add some data to the metrics so that we can better characterise them:
+
+| Data | Why is it useful? | Notes |
+| :---- | :---- | :---- |
+| Device information |
- To detect specific device problem, especially on the fragmented Android ecosystem
| It is provided by Sentry |
+| Homeserver | - To compare matrix.org and element.io homeservers speed
- To measure the impact of a slow homeserver
| **We use SHA-512 to compute the hash of the homeserver domain**, ie matrix.org or element.io. |
+| DB files size:- Crypto store
- State store
- Event cache store
- Media store
| - To check the impact of growing DB on speed performance
- To check disk space used by the app
| Expressed in MB. |
+
+We'd want to add this data too, but it's not possible at the moment given the info we have in the SDK:
+
+| Data | Why is it useful? | Notes |
+| :---- | :---- | :---- |
+| Account size | - To check the impact on speed performance
- To check the impact on \`/sync\` response size
| Expressed in number of joined rooms.**TODO**: Add the Rust SDK API for reference
**TODO**: We need to experiment the feasibility of this metric |
+| Catch-up /sync size | - To check network usage stays as low as possible
| The response size in kB of the first `/sync` request made during catch-up.**TODO**: Add the Rust SDK API for reference**TODO**: We need to experiment the feasibility of this metric |
+
+## Tech metrics
+
+They are tracked as Sentry spans. `Span.operation` follows the [Span Operations](https://develop.sentry.dev/sdk/performance/span-operations/) convention like `http.client`. `Span.description` is the metric name.
+
+| Metric (Sentry Span Description) | Category (Sentry Span Operation) | Description | Notes |
+| :---- | :---- | :---- | :---- |
+| Timeline load | `function` | `Room.timelineWithConfiguration` | |
+
+**TODO: Add more**
+
+
+## Future considerations
+Later, we could add the following UX metrics.
+
+### UX starting from outside of the app
+* Call answer to call
+* Permalink to message
+* Notification to threaded message
+* Notification to invite (room or space)
+
+And maybe all the variants:
+* Permalink to room
+* Permalink to space
+* Permalink to threaded message
+* Permalink to profile
+* Permalink to Element Call
+
+### UX inside the app
+* Make a call
+* QR code login
+* Open member list
+* Open a permalink (of all sorts)
+* Open a thread
+