# ANN: ProfilePerfetto.jl – Easy profiling with interactive viewer

**URL:** <https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920>\
**Category:** Package Announcements\
**Tags:** profiling, developer-tools, tooling, perfetto\
**Created:** [April 29, 2026, 3:29pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920 "2026-04-29T15:29:43Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![fonsp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fonsp/32/222349_2.png) [@fonsp](https://discourse.julialang.org/u/fonsp)\
**Post date:** [April 29, 2026, 3:29pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/1 "2026-04-29T15:29:43Z")

</div>

# New package: ProfilePerfetto.jl

I made a new package! With `@perfetto`, you can profile a piece of code, and view the profile using the [Perfetto](https://ui.perfetto.dev) browser-based trace viewer.

# Example

```julia
using ProfilePerfetto

@perfetto_open my_function()

```

This will profile your code, and open the Perfetto web UI with your trace loaded. You can then use the Perfetto interface to navigate (WASD keys) and inspect:

# Statistics, flame chart

Perfetto has many useful features, which we now get for free! This includes **statistics for a given selection** :

 ![perfetto stats](https://global.discourse-cdn.com/julialang/original/3X/8/f/8f6ff2c2b6b7c17b8d6b2eddd1d11d759514c0cb.png)

A **flame chart** viewer with multiple display options:

 ![perfetto flame](https://global.discourse-cdn.com/julialang/original/3X/0/a/0a8f0f718827b92031bcab49aae9bb2160396e16.png)

And more features can be discovered in the [Perfetto documentation](https://perfetto.dev/docs/) 🙂

# Bonus feature 1: Automatic sampling rate

To make profiling more accessible, ProfilePerfetto will automatically find a good sampling rate for you. It does this by running your code multiple times, and gradually increasing the sampling rate.

```julia-auto
julia> @perfetto_open do_some_work(600, 400, 500)
[ Info: 🔬 @perfetto: calibrating — 172.1 ms at Δ=10.0 ms (1.0×), sharpening to Δ=1.25 ms
[ Info: 🔬 @perfetto: calibrating — 97.7 ms at Δ=1.25 ms (1.0×), sharpening to Δ=156.2 μs
[ Info: 🔬 @perfetto: calibrating — 129.6 ms at Δ=156.2 μs (1.3×), sharpening to Δ=42.7 μs
[ Info: 🔬 @perfetto: calibrating — 186.2 ms at Δ=42.7 μs (1.9×), sharpening to Δ=22.5 μs
[ Info: 🔬 @perfetto: calibrating — 232.0 ms at Δ=22.5 μs (2.4×), sharpening to Δ=14.5 μs
[ Info: 🎯 @perfetto: 420.9 ms at Δ=14.5 μs (2% buffer, 4.3× baseline, round 6)
"/var/folders/v_/fhpj9jn151d4p9c2fdw2gv780000gn/T/jl_0HA38BsxYv.html"

```

# Bonus feature 2: Isolated function call

When profiling with other tools, you might have noticed lots of ‘noise’ from the REPL, the profiler, etc, showing up in your profile. ProfilePerfetto uses a clever trick to **only show** the profile of the code that you wrote.

# No bonus features?

If you don’t want these extra features, then you can use just the viewing functionality of ProfilePerfetto together with manual profiling:

```julia
using Profile, ProfilePerfetto

Profile.clear()
Profile.@profile my_workload()

perfetto_open() # or perfetto_view() in VS Code

```

# Inside VS Code, Pluto, Jupyter, etc

From the REPL, you can use `@perfetto_open` to open the perfetto viewer in your default browser.

But in Pluto, VS Code, Jupyter, or other interactive coding environments, you can use `@perfetto` instead. The profile viewer will then display **inline** , like a plot. Here is an example in Pluto:

 ![perfetto pluto](https://global.discourse-cdn.com/julialang/original/3X/b/7/b740ce895b520d45f38f1b28accea1c5a9cda922.png)

# Use of AI

I used _vibe coding_ to write large parts of this package. I reviewed all code, but I tried to let the AI ‘do its thing’ instead of managing too much. It works really well! I wrote this post by hand.

# Why this package?

I think Julia needs better developer tooling, and I am especially interested in _easy to use_ and _reliable_ tooling. I hope this package will make it easier for users to profile their code.

Still, there is a lot more that can be done! The information gathered and displayed by ProfilePerfetto is still very minimal, and the automatic rate detection can be improved. Feel free to contribute to the package!

# What do you think?

Try it out and let me know what you think!

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [April 29, 2026, 3:57pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/2 "2026-04-29T15:57:12Z")

</div>

I haven’t had a chance to try this out yet, but it looks super nice!

The Perfetto website says

> System-wide profiling for Linux and Android

Does that mean this does not work on macOS?

---

<div class="post-metadata">

**Author:** ![fonsp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fonsp/32/222349_2.png) [@fonsp](https://discourse.julialang.org/u/fonsp)\
**Post date:** [April 29, 2026, 4:32pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/3 "2026-04-29T16:32:10Z")

</div>

It works on all platforms 🙂 That part of the docs refers to the Perfetto profiler, but we only use the Perfetto viewer (which is web-based).

---

<div class="post-metadata">

**Author:** ![langestefan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/langestefan/32/207923_2.png) [@langestefan](https://discourse.julialang.org/u/langestefan)\
**Post date:** [April 29, 2026, 6:20pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/4 "2026-04-29T18:20:39Z")

</div>

It’s very cool! My first thought reading the title was ‘I hope it has auto sampling rate control’ 😃

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [April 29, 2026, 6:42pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/5 "2026-04-29T18:42:37Z")

</div>

It does look cool! Any way to integrate with VSCode for click → go to that line in code, like `@profview` does?

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [April 30, 2026, 5:55am UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/6 "2026-04-30T05:55:59Z")

</div>

> [@fonsp](#):
>
> Perfetto web UI with your trace loaded. You can then use the Perfetto interface to navigate (WASD keys) and inspect:

Does it mean you need an API key to browse the stats?

---

<div class="post-metadata">

**Author:** ![fonsp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fonsp/32/222349_2.png) [@fonsp](https://discourse.julialang.org/u/fonsp)\
**Post date:** [April 30, 2026, 11:39am UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/7 "2026-04-30T11:39:18Z")

</div>

No API key, just run `@perfetto_open` and everything will work.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 30, 2026, 2:55pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/8 "2026-04-30T14:55:05Z")

</div>

How feasible would it be to serve the perfetto UI locally?

---

<div class="post-metadata">

**Author:** ![langestefan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/langestefan/32/207923_2.png) [@langestefan](https://discourse.julialang.org/u/langestefan)\
**Post date:** [April 30, 2026, 9:47pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/9 "2026-04-30T21:47:18Z")

</div>

isn’t your browser viewed locally?

---

<div class="post-metadata">

**Author:** ![fonsp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fonsp/32/222349_2.png) [@fonsp](https://discourse.julialang.org/u/fonsp)\
**Post date:** [May 1, 2026, 11:38am UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/10 "2026-05-01T11:38:45Z")

</div>

Should be easy! I believe it’s a serverless HTML file ([source code](https://github.com/google/perfetto/tree/main/ui)), so you could ship it as Artifact and serve with HTTP.jl. Then we could also fork it for some better integration (remove sidebar, auto-confirm load dialog, etc)

---

<div class="post-metadata">

**Author:** ![abavoil](https://avatars.discourse-cdn.com/v4/letter/a/a88e4f/32.png) [@abavoil](https://discourse.julialang.org/u/abavoil)\
**Post date:** [May 3, 2026, 9:00pm UTC](https://discourse.julialang.org/t/ann-profileperfetto-jl-easy-profiling-with-interactive-viewer/136920/11 "2026-05-03T21:00:27Z")

</div>

This example shows a similar value as `@time` in the terminal with an M2.

```julia-auto
using Pkg
Pkg.add("ProfilePerfetto")
fib(n) = if n <= 1 1 else fib(n-1) + fib(n-2) end
@perfetto_open fib(42)

```
