<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>Perfetto - Lalit Maganti</title><link href="https://lalitm.com/tags/perfetto/atom.xml" rel="self" type="application/atom+xml"/><link href="https://lalitm.com/" rel="alternate" type="text/html"/><id>https://lalitm.com/tags/perfetto/</id><updated>2026-04-05T12:04:32Z</updated><author><name>Lalit Maganti</name></author><generator>Hugo -- gohugo.io</generator><entry><title>syntaqlite: high-fidelity devtools that SQLite deserves</title><link href="https://lalitm.com/post/syntaqlite/" rel="alternate" type="text/html"/><id>https://lalitm.com/post/syntaqlite/</id><published>2026-03-17T05:35:45Z</published><updated>2026-03-17T05:35:45Z</updated><summary type="html">&lt;p&gt;Most SQL tools treat SQLite as a &amp;ldquo;flavor&amp;rdquo; of a generic SQL parser. They approximate the language, which means they break on SQLite-exclusive features like &lt;a href="https://www.sqlite.org/vtab.html"&gt;virtual tables&lt;/a&gt;, miss syntax like &lt;a href="https://www.sqlite.org/lang_upsert.html"&gt;UPSERT&lt;/a&gt;, and ignore the &lt;a href="https://www.sqlite.org/compile.html"&gt;22 compile-time flags&lt;/a&gt; that change the syntax SQLite accepts.&lt;/p&gt;
&lt;p&gt;So I built &lt;a href="https://github.com/lalitMaganti/syntaqlite"&gt;syntaqlite&lt;/a&gt;: an open-source parser, formatter, validator, and LSP built directly on SQLite&amp;rsquo;s own Lemon-generated grammar. It sees SQL exactly how SQLite sees it, no matter which version of SQLite you&amp;rsquo;re using or which feature flags you compiled with.&lt;/p&gt;
&lt;p&gt;It ships as a &lt;a href="https://docs.syntaqlite.com/main/getting-started/cli"&gt;CLI&lt;/a&gt;, &lt;a href="https://docs.syntaqlite.com/main/getting-started/vscode"&gt;VS Code extension&lt;/a&gt;, &lt;a href="https://docs.syntaqlite.com/main/getting-started/claude-code"&gt;Claude Code LSP plugin&lt;/a&gt;, and &lt;a href="https://docs.syntaqlite.com/main/getting-started/c-parser/"&gt;C&lt;/a&gt;/&lt;a href="https://docs.syntaqlite.com/main/getting-started/rust/"&gt;Rust&lt;/a&gt; libraries.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also a &lt;strong&gt;&lt;a href="https://playground.syntaqlite.com/"&gt;web playground&lt;/a&gt;&lt;/strong&gt; which you can try now: paste any SQLite SQL and see parsing, formatting, and validation live in the browser, no install needed. &lt;a href="https://docs.syntaqlite.com/"&gt;Full documentation is available here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s syntaqlite in action:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Formatting with the CLI&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; syntaqlite fmt -e &lt;span class="s2"&gt;&amp;#34;select u.name,u.email,count(e.id) as events from users u join events e on e.user_id=u.id where u.signed_up_at&amp;gt;=date(&amp;#39;now&amp;#39;,&amp;#39;-30 days&amp;#39;) group by u.name,u.email having count(e.id)&amp;gt;10 order by events desc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;JOIN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signed_up_at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;now&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-30 days&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;HAVING&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Validation with the CLI&lt;/em&gt;&lt;/p&gt;</summary></entry><entry><title>Rendering 100k trace events faster with exponential search</title><link href="https://lalitm.com/post/exponential-search/" rel="alternate" type="text/html"/><id>https://lalitm.com/post/exponential-search/</id><published>2026-02-03T21:07:04Z</published><updated>2026-02-03T21:07:04Z</updated><summary type="html">&lt;p&gt;We&amp;rsquo;ve recently been looking into optimizing rendering performance of the Perfetto UI on large traces. We discovered that there was some inefficiency in our data fetching logic, especially when you&amp;rsquo;re very zoomed out.&lt;/p&gt;
&lt;p&gt;In this case, there can be a lot of slices (spans) which are so small that they take less than one pixel of width. So for each pixel, we need to figure out &amp;ldquo;what is the event which we should draw for this pixel&amp;rdquo;. Over time we&amp;rsquo;ve come to the conclusion that the best thing to draw is the slice with the largest duration in that pixel.&lt;/p&gt;
&lt;p&gt;We can break this into two sub-problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What is the range of events which correspond to each pixel?&lt;/li&gt;
&lt;li&gt;What is the event with the maximum duration for that pixel?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We&amp;rsquo;re going to focus on 1) in this post as that&amp;rsquo;s where the slowdown was. 2) is fascinating but also surprisingly orthogonal. If you&amp;rsquo;re interested, I would suggest reading &lt;a href="https://thume.ca/2021/03/14/iforests/"&gt;this excellent post&lt;/a&gt; from Tristan Hume explaining the basic algorithm we use.&lt;/p&gt;</summary></entry><entry><title>Perfetto: Swiss Army Knife for Linux Client Tracing</title><link href="https://lalitm.com/perfetto-swiss-army-knife/" rel="alternate" type="text/html"/><id>https://lalitm.com/perfetto-swiss-army-knife/</id><published>2025-10-31T00:00:00Z</published><updated>2025-10-31T00:00:00Z</updated><summary type="html">&lt;p&gt;&lt;em&gt;Discussed on &lt;a href="https://lobste.rs/s/6c86lq/perfetto_swiss_army_knife_for_linux"&gt;lobste.rs&lt;/a&gt; and &lt;a href="https://news.ycombinator.com/item?id=45771019"&gt;Hacker News&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I gave a talk at the &lt;a href="https://tracingsummit.org/"&gt;2025 Tracing Summit&lt;/a&gt; last month titled &amp;ldquo;&lt;a href="https://cfp.tracingsummit.org/ts2025/talk/TKVU8W/"&gt;Perfetto: The Swiss Army Knife of Linux Client/Embedded Tracing&lt;/a&gt;&amp;rdquo;. My goal in this talk was to show how Linux kernel, systems and embedded developers can use &lt;a href="https://docs.perfetto.dev"&gt;Perfetto&lt;/a&gt; when debugging and root-causing performance issues in their respective domains. Even though the Perfetto UI is primarily built for viewing &lt;a href="https://perfetto.dev/docs/#why-would-you-use-perfetto-"&gt;Android or Chrome traces&lt;/a&gt;, it is a flexible tool and can be used in many other ways!&lt;/p&gt;
&lt;p&gt;The talk was recorded and is available on &lt;a href="https://www.youtube.com/watch?v=VzTwul2Qb3g"&gt;YouTube&lt;/a&gt;. Taking inspiration from &lt;a href="https://simonwillison.net/"&gt;Simon Willison&lt;/a&gt;, this post is an &lt;a href="https://simonwillison.net/2023/Aug/6/annotated-presentations/"&gt;annotated presentation&lt;/a&gt; containing my slides and detailed notes on them. The talk also has a lot of UI demos: for these, I&amp;rsquo;ll have a screenshot but also a link to the relevant part of the video (videos are unbeatable for UI!).&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%;"&gt;
&lt;iframe style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" src="https://www.youtube.com/embed/VzTwul2Qb3g" title="TS2025 - Perfetto: The Swiss Army Knife of Linux Client/Embedded Tracing" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;First, what is Perfetto? Perfetto is fundamentally a suite of tools: it&amp;rsquo;s not just one thing but a bunch of different tools working together to help you debug and root-cause problems. This diagram shows how everything fits together, with the core parts of the Perfetto project in the center.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src="/img/perfetto-swiss-army-03.jpg" alt="diagram of all the pieces of Perfetto, Recording tools, protobuf format, trace processor, Perfetto UI, Python API, Format converters. Chrome JSON, Other profiling formats"&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;The recording tools for Perfetto consist of 1) an &lt;a href="https://perfetto.dev/docs/getting-started/in-app-tracing"&gt;SDK for C++ apps&lt;/a&gt; 2) a &lt;a href="https://perfetto.dev/docs/getting-started/system-tracing"&gt;daemon&lt;/a&gt; that can collect data from ftrace, /proc, /sys, and various kernel interfaces 3) another &lt;a href="https://perfetto.dev/docs/concepts/service-model"&gt;daemon&lt;/a&gt; that amalgamates trace data from multiple processes into a single trace file. These tools all speak the Perfetto &lt;a href="https://perfetto.dev/docs/getting-started/converting"&gt;protobuf format&lt;/a&gt;, a high-performance trace format designed to be very efficient to write but not to analyze or consume directly.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s where the &lt;a href="https://perfetto.dev/docs/analysis/trace-processor"&gt;trace processor&lt;/a&gt; comes in. It&amp;rsquo;s a C++ library that parses the protobuf format, but also a bunch of other widely used trace formats. It exposes this data via an SQL query interface to any embedding program including &lt;a href="https://perfetto.dev/docs/visualization/perfetto-ui"&gt;Perfetto UI&lt;/a&gt; (which is what most of this talk is about) and also to the &lt;a href="https://perfetto.dev/docs/analysis/trace-processor-python"&gt;Python API&lt;/a&gt; if you want to do ad-hoc scripting or analysis in Python.&lt;/p&gt;
&lt;p&gt;There are also very common tracing/profiling formats used by the Linux community: perf.data, ftrace text format, Firefox profiler format, and many others. Perfetto &lt;a href="https://perfetto.dev/docs/getting-started/other-formats"&gt;supports&lt;/a&gt; quite a few of those directly. There&amp;rsquo;s also the Chrome JSON format (AKA the &lt;a href="https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview?tab=t.0"&gt;Trace Event Format&lt;/a&gt;) which is a simpler interchange format. It&amp;rsquo;s not the most efficient to read or write, but it does the job for a lot of use cases.&lt;/p&gt;
&lt;p&gt;Often people write &lt;a href="https://perfetto.dev/docs/getting-started/converting"&gt;converters&lt;/a&gt;. They have their own tracing format, maybe proprietary, maybe open source but something we don&amp;rsquo;t know about, and it&amp;rsquo;s very common that people convert to one of the formats we understand, most commonly our protobuf or Chrome JSON formats.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src="/img/perfetto-swiss-army-04.jpg" alt="Slide showing Perfetto UI architecture with web-based trace visualizer features"&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;The &lt;a href="https://perfetto.dev/docs/visualization/perfetto-ui"&gt;Perfetto UI&lt;/a&gt; is fundamentally a web-based trace visualizer, combining timeline visualization, user-driven selection/aggregation, and SQL queries all in one interface. Because it has the trace processor as a backend, it works with a bunch of different trace formats.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s very important to note that even though the Perfetto UI is web-based, everything happens inside your browser and trace data never leaves your system. You can even &lt;a href="https://perfetto.dev/docs/contributing/ui-getting-started"&gt;build it&lt;/a&gt; and host it yourself on any static server: we&amp;rsquo;ve made it extremely easy to do so!&lt;/p&gt;
&lt;p&gt;At the start of 2025, we actually moved our whole development to GitHub. In the past, we used to develop on Android and GitHub was just a mirror. That&amp;rsquo;s no longer the case, GitHub is actually where we develop and take pull requests.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src="/img/perfetto-swiss-army-05.jpg" alt="Slide introducing the fractal renderer demo program with Vulkan and multi-threading"&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;Most of this talk, I&amp;rsquo;m going to spend actually showing you how you can use the Perfetto UI to debug performance issues on Linux. I don&amp;rsquo;t want to show you an Android trace which needs a lot of context about how the Android system works and so you think, &amp;ldquo;oh, that was cool, but I didn&amp;rsquo;t really understand what was happening.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;So to make this talk more approachable, I wrote a &lt;a href="https://github.com/LalitMaganti/fractal-renderer-vk"&gt;straightforward demo program&lt;/a&gt; you can look at yourself! So it&amp;rsquo;s obviously not a production system but I&amp;rsquo;ve tried to make it as representative of the sort of issues we use Perfetto for every day.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s a Rust program which generates a Julia set and visualizes it over time. The technologies I used: &lt;a href="https://vulkano.rs/"&gt;Vulkan&lt;/a&gt;, GPU rendering and also multi-threaded CPU computation. So how it works is that computation of various parameters is happening on background threads, and then that&amp;rsquo;s being passed to the main thread for rendering.&lt;/p&gt;
&lt;p&gt;And then, for demonstration purposes, there is a performance bug; rendering should run at 60 FPS, but every so often, the frame rate drops dramatically. Here&amp;rsquo;s what that looks like:&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src="/img/test.avif" alt="Animated visualization of Julia set fractal renderer showing frame rate drops"&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;The code is on &lt;a href="https://github.com/LalitMaganti/fractal-renderer-vk"&gt;GitHub&lt;/a&gt; and if you&amp;rsquo;re interested in following along. The traces are there as well - you don&amp;rsquo;t have to collect the traces yourself, but you can if you want. All the instructions and information is in the README.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src="/img/perfetto-swiss-army-06.jpg" alt="Slide titled &amp;ldquo;Suspicion #1: Maybe it&amp;rsquo;s a CPU problem?&amp;rdquo; with perf command examples"&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;So the first suspicion we may have is that maybe it&amp;rsquo;s some CPU problem. A lot of engineers I know would reach for perf immediately whenever they see a problem like this. The main reason is that if perf can capture the problem, they can go straight to the line of code without needing to spend time debugging using more complex approaches.&lt;/p&gt;</summary></entry><entry><title>On Perfetto, Open Source, and Company Priorities</title><link href="https://lalitm.com/perfetto-oss-company-prio/" rel="alternate" type="text/html"/><id>https://lalitm.com/perfetto-oss-company-prio/</id><published>2025-10-17T15:00:00+01:00</published><updated>2025-10-17T15:00:00+01:00</updated><summary type="html">&lt;p&gt;&lt;em&gt;Discussed on &lt;a href="https://lobste.rs/s/chaivl/on_perfetto_open_source_company"&gt;lobste.rs&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I recently stumbled across
&lt;a href="https://lobste.rs/s/fl7ly9/traceboot_precise_lightweight_tracing"&gt;this post on lobste.rs&lt;/a&gt;
about a project called
&lt;a href="https://codeberg.org/SpecialSnowflake/traceboot"&gt;traceboot&lt;/a&gt; which allows
visualizing the Linux boot process using lightweight ftrace events and Perfetto.
The author had
&lt;a href="https://codeberg.org/SpecialSnowflake/traceboot#woes-with-a-rant-and-ideas-last-paragraph-of-this-section"&gt;some commentary&lt;/a&gt;
about their experience trying to order tracks in Perfetto:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ordering tracks with perfetto has been ridiculously complicated. It has taken
the majority of the time of this project! Upstream&amp;rsquo;s answers are basically
that the main user is Android (Perfetto is a Google project) so others come
second if at all. While I get the reasons to do so, I read that as a caution
against depending on it as a third-party. Google is notorious for (&amp;hellip;)
completely killing projects&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Honestly? All of these points are right:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is really unfortunate that doing something so simple took so much effort.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s true that external users are supported at a lower priority than Android
users.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s also the case that Google has historically wound down projects when
priorities shift&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The good news is that we just
&lt;a href="https://github.com/google/perfetto/pull/3273"&gt;landed&lt;/a&gt; support for trace
writers to specify explicitly how traces should be ordered with the JSON format
in Perfetto without any extreme workarounds! This feature is already available on
the &amp;ldquo;Canary&amp;rdquo; UI channel and on &amp;ldquo;Stable&amp;rdquo; within 3-4 weeks.&lt;/p&gt;</summary></entry></feed>