Embrace has officially acquired SpeedCurve! Together, we’re redefining the future of user-focused observability.

Learn more

What is Performance Tracing?

what-is-performance-tracing-blog-image

Understand Performance Tracing, its value, and how you can use it to improve the user experience in your mobile app.

Measuring app performance is challenging, and engineers frequently struggle to identify where areas of their app run slow or fail. Understanding every way your app causes user frustration is crucial for resolving issues that affect the user experience but don’t cause a crash or error.

For example, a relatively simple user action like tapping a button to upload a photo could trigger several services. There could be a service to upload the photo to your backend, a separate service for image manipulation like compressing or resizing, and another service for storing the result in your database.

If users complain that your app takes too long to upload their profile picture, how can you track down the specific service that’s causing this problem?

This is where Performance Tracing comes into play.

In this post, we’ll dive into the intricacies of Performance Tracing, shedding light on its key components, mechanics, and benefits.

What is Performance Tracing, Really?

Performance Tracing is the monitoring and analysis of various aspects of an app’s performance, which provides engineers visibility into custom operations. It allows you to track and monitor key parts of your app’s performance — everything from simple actions to complex user flows — which allows you to prioritize and resolve issues efficiently.

Through Performance Tracing tools, engineers can pinpoint the specific steps causing a delay in their app. For example, if you’ve built an e-commerce app, you might discover that users continually start the purchase process, but don’t reach completion.

You also note that the app isn’t crashing on this screen. To get to the bottom of the issue, you check your error logs and note that there are no failures being captured there either. What’s the next step?

In this instance, you’d need to know how long the process takes. Maybe completing a purchase is so slow that it’s causing users to give up and abandon their carts out of frustration. You need visibility into the cause of this slowdown, but what type of visibility do you need exactly?

This is where the ability to track specific areas of an app becomes advantageous. You may need to track the specific “add to cart” feature or the step where the user adds payment information. In the realm of Performance Tracing, this is known as a span.

On a more broad level, you might want to track the entire user checkout flow, including adding to cart, adding their payment information, billing and shipping addresses, coupons, etc. In the realm of Performance Tracing, this is a trace.

With the insight garnered from spans and traces, you can then troubleshoot the issue and improve the app’s responsiveness for the user.

Performance Tracing empowers engineers to create more efficient and enjoyable app experiences for users. Below, we’ll break down how.

What is a span?

A fundamental concept within Performance Tracing is the “span.” A span represents an operation or the “work” taking place on a service. It also allows for metadata like the span’s name, span ID, parent span ID, start and end timestamps, attributes, events, and status. 

Spans can take on a variety of forms. For example, a span might represent something as broad as fetching images as a user scrolls on an e-commerce app, or something as granular as the calling of a single function.

What is a trace?

A trace describes the end-to-end journey of one or more connected spans. While a span gives you the ability to track specific aspects of your user journey, a trace provides you with the overall picture of a user flow.

You can think of a trace as a tree of operations and a span as the branches within the tree. To have a trace, you must have at least one span underneath it but can contain more than one span.

Spans can become quite granular. If you have one large “parent” span, you may also have several “child” spans nested underneath this. A span can contain one or more spans within it, but it’s worthwhile to note that a span with no children is just a tree with one branch, so this can be considered a trace as well.

You can learn more about spans, traces, and Performance Tracing in action in this video:

How do traces and spans work?

Traces and spans have a parent-child relationship. A trace traverses the entire journey that many spans, together, take to finish a large operation that consists of smaller operations.

explanation-of-span

Spans also contain a parent-child relationship. Within one large “parent” span, there can be several “children” nested underneath.

explanation-spans-parent-child-spans

What’s an Example of Performance Tracing?

Now, let’s cover an example of Performance Tracing. 

A trace could represent the entire journey of a page loading with information you’ve requested, and the spans are the individual pieces of work that accomplish this task.

As shown in the image below, the browser’s work to load the page is one span, the backend’s work to process the JSON request is another span, and the database server’s work to fulfill your query is another span.

Within these three parent spans, there are child spans that represent smaller, more specific units of work being done to fulfill various elements of the request.

Performance Tracing vs. Distributed Tracing: What’s the difference?

Performance tracing is often mentioned alongside distributed tracing, and while the two are related, they serve different purposes and focus on different parts of an application’s architecture.

Performance tracing focuses on understanding how an application performs from the user’s perspective. The goal is to identify slowdowns, bottlenecks, or failures that impact the user experience, even when nothing crashes.

Distributed tracing, on the other hand, is primarily concerned with tracing requests as they move across multiple backend services. It is commonly used in microservices architectures to understand how requests flow between services, where latency is introduced, and how dependencies interact with one another.

While both approaches use similar concepts like spans and traces, they differ in scope. Performance tracing emphasizes client-side visibility and user flows, while distributed tracing emphasizes service-to-service communication on the backend. In many cases, the two can complement each other: Performance tracing helps explain what the user experiences, while distributed tracing helps explain what happens behind the scenes.

spans-page-load-JSON-query

What are the benefits of Performance Tracing?

There are many benefits of Performance Tracing. Let’s run through a few below. With Performance Tracing, you’re able to:

Measure what matters most

You aren’t limited to pre-built measurements or generic performance metrics. Performance Tracing allows you to instrument spans and traces around the parts of your app that are most important to your users, such as login flows, checkout flows, payments, image uploads, or onboarding.

By focusing on these critical user flows, you can better understand how long key actions take to complete and how performance changes over time or across releases.

Analyze performance at a granular level

Because spans and traces have a parent-child relationship, Performance Tracing makes it possible to break down complex workflows into smaller units of work. This lets you see how individual steps contribute to the overall performance of a flow.

For example, you can determine whether a slowdown is caused by a network request, a backend dependency, or work happening on the client itself. You can also track success and failure rates for specific spans and attach custom attributes for deeper analysis.

Resolve issues with precision

When users experience slow or unreliable behavior, Performance Tracing helps you quickly pinpoint where the problem is occurring. Instead of relying on logs or attempting to reproduce issues manually, engineers can use traces to see exactly which operation caused a delay or failed.

This level of precision reduces the time it takes to identify root causes and makes it easier to fix performance issues before they impact more users.

Identify areas for optimization

Not all performance problems result in crashes or errors. Some of the most frustrating user experiences come from flows that technically work but take too long to complete. Performance Tracing helps uncover these slower areas within key workflows, even when nothing outright fails.

By identifying and optimizing these areas, teams can improve responsiveness, maintain app quality, and keep users engaged.

Pinpoint app performance issues with Embrace

Embrace is a data-driven toolset designed to make the job of a mobile engineer easier. We use automated data collection and a unified platform to reduce the time and effort of searching for insight across disparate tooling. 

With Embrace, engineers can identify, prioritize, and solve problems in their apps with greater ease.

Embrace’s Performance Tracing empowers engineering teams to monitor crucial sections of their apps with precision. It does this by allowing you to create custom traces and spans for key areas in your app. 

At a high level, you can quickly see the timing of your traces with P50, P90, P95, and P99 measurements alongside the ability to review the completion and failure percentages, as shown in the image below.

performance-tracing-mock-up-in-Embrace-dashboard

Let’s say you notice a trace has experienced a slowdown or an increase in failure rate and you’d like to dig in further to investigate. You can click any trace and dive into a more detailed view.

Performance-Tracing-Trace-Instance-mock-up-in-dashboard

Above, you can see the Trace Instance page which shows each span within a given trace and the details of each segment of the span. Outside of this timeline shown above, this page also includes the span ID, name, outcome, duration, device model, start time, end time, and more.

You can also filter to review traces based on any attribute you create. The attributes created are key-value pairs. For example, one attribute, or key, could be the user ID and the value would be the user’s unique ID or user number. 

You also have the option to filter based on events. This is something you can instrument in a span when you’re setting it up in your code. An event could be the change in a variable’s value or even a point where an authentication milestone is successful. These filtering capabilities allow you to drill down to the exact mobile experiences you’re interested in. 

It’s worthwhile to note that Embrace traces differ from “distributed tracing” because we capture the client side of things, or what’s happening in the app. If you’re looking to achieve distributed tracing with Embrace, then you can do this by connecting Embrace to other observability tools

To learn more about Performance Tracing and experience it firsthand, you can try Embrace for free today.

Embrace Want to learn how tracing can optimize an app's performance?

Learn what tracing is, its differences in mobile and backend, and find out how it can help you optimize your mobile app performance.

Read more
Related Content

Understanding Java’s garbage collection

Learn how Java’s garbage collection works to manage memory efficiently, prevent leaks, and optimize app performance across modern, scalable applications.

Key Android performance monitoring metrics

Learn the essential Android performance metrics—startup time, UI rendering, crashes, ANRs, network speed, and resource usage—to improve app speed and stability.

Analyze, monitor, and alert on child spans with new Embrace capabilities

Embrace now supports custom aggregates using child spans, not just root spans. This includes creating custom metrics, custom dashboards, and alerts based on nested child spans, giving engineers the capability to do ultra-granular analysis and examine small (yet critical) operations in detail.