Latest Posts (20 found)
Lalit Maganti 1 weeks ago

GitHub has alternatives, but no replacement

Codeberg , a Git code hosting platform, recently took a decision to prohibit projects that mostly consist of generative-AI-written code which has prompted concern and extensive discussion elsewhere . The decision does not surprise me, and I don’t mean that as a criticism. Codeberg has always presented itself as a mission-driven alternative to GitHub, not neutral infrastructure. 1 What interests me is the disappointment in the response. Many people reacted as though one of the few plausible GitHub replacements had ruled them or their projects out. They wanted Codeberg to be a universal alternative, a better GitHub and the obvious place to go when leaving it. To me, that exposes a big gap in the open-source space. There are plenty of places to host a Git repository, but remarkably few places to host an open-source community. GitHub gives projects a shared pool of identities, habits and paths to discovery. None of the alternatives has reproduced that at a similar scale. I don’t think the answer has to be another centralized platform, or that every project should live in one place. But decentralization is not enough on its own. Whatever replaces GitHub still needs a shared social layer: identities contributors already have, conventions they understand and ways to discover projects across the network. Whenever dissatisfaction with GitHub comes up, someone inevitably says: “Git is decentralized. Just self-host a forge.” I’ve self-hosted Gitea for years, so this is an argument I’m very familiar with. Self-hosting works well for personal projects, but I wouldn’t use it for something I wanted strangers to contribute to. On GitHub, most people already have an account and understand how issues and pull requests work. On my forge, even reporting a small bug means creating another account, learning how my forge works and what conventions I want you to follow. Unless someone really cared, they probably wouldn’t bother. I know I wouldn’t. And contribution is only half of it. GitHub used to be genuinely good at discovery. I regularly found projects because someone I followed starred them, often in areas I would never have searched for myself. It felt like a social network built around people making things. GitHub has since redesigned that feed, and I almost never visit it anymore. Defaults are powerful: once discovery stopped being part of the experience GitHub put in front of me, it largely disappeared from my workflow. The basic experience of GitHub has been getting steadily worse. It is slow, things regularly fail to load and notifications are unreliable. GitHub itself recently described two major incidents as “not acceptable” . Its pull request experience has been awful too. Large PRs are painfully slow to navigate and review. Stacked PRs 2 have been common inside large software companies for well over a decade, but only just became a thing with GitHub and, even then, seems to be quite buggy . What frustrates me about GitHub’s push towards AI is that the core forge feels neglected while Copilot appears everywhere. An agent writing more code doesn’t help when the interface for reviewing it is already struggling. Ghostty exemplifies this frustration. In late April, Mitchell Hashimoto announced that Ghostty is leaving GitHub because frequent outages were preventing its maintainers from working reliably: On the day I am writing this post, I’ve been unable to do any PR review for ~2 hours because there is a GitHub Actions outage. This is no longer a place for serious work if it just blocks you out for hours per day, every day. Interestingly, he also makes the point that GitHub is more than hosting: To the “Git is distributed!” crowd: the issue isn’t Git, it’s the infrastructure we rely on around it: issues, PRs, Actions, etc. Hashimoto said Ghostty was in discussions with multiple commercial and FOSS providers and planned an incremental migration. The fact that such a prominent project had to shop around, rather than move to an obvious default, is exactly the gap I mean. It’s worth going through the alternatives and the problems I see with each: GitLab is capable, but it feels incredibly corporate, even more so than GitHub. 3 Nor have I found it as good as GitHub at helping people stumble across projects and developers. SourceHut is focused and transparent and, like Codeberg, openly values-driven. 4 Its email-oriented workflow, while battle-tested by projects like the Linux kernel, is unfamiliar to most GitHub users. Forgejo ’s federation project may eventually connect self-hosted instances into a shared network. It looks promising, but has been in development for quite some time, remains experimental 5 and is not yet a practical answer to the social fragmentation of self-hosting. Radicle is technologically interesting: repositories are replicated peer to peer, while issues and patches are stored alongside them. But it still feels too immature to replace GitHub for a public project. For example, its public web interface lets people browse repositories, but contributing requires them to install its CLI or desktop application. Someone encountering a bug should not have to install the forge’s software merely to report it. 6 The project I’m most interested in is Tangled , based mostly on gut feel. I like its focus on the social experience around code. For example, its home page immediately shows me a bunch of cool projects, exactly like old GitHub used to do. But it is still in alpha, and it remains to be seen whether it can blossom into a true alternative. One thing that stands out is that, apart from GitLab, every competitor is built around either decentralization or a social mission. That makes each of them fundamentally less “straightforward” than a for-profit company. It makes me wonder whether there is room for one. Perhaps it could look more like bunny.net than a venture-backed startup: a deliberately boring company with no ambition to become the operating system for software development or to reorganize programming around whatever technology investors currently find exciting. It might simply concentrate on making open-source collaboration pleasant and reliable, charge developers and smaller organizations directly, and grow at whatever pace that revenue supports. The open question is whether this could be a viable business. The difficult part is exactly what I keep saying is missing: shared identity, shared conventions and discovery only become valuable once a platform has reached scale. Better repository hosting alone would not solve that cold-start problem. 7 I don’t know who, if anyone, will solve it. But a real replacement will have to treat the social layer as the product, not as something that appears automatically once enough repositories are hosted. The English translation of the bylaws says Codeberg’s purpose “also intends to raise awareness for the social and philosophical questions” connected to free content and free software.  ↩︎ Stacked PRs split a large change into a sequence of dependent, individually reviewable changes.  ↩︎ For example, GitLab’s homepage describes it as “your intelligent orchestration platform for DevSecOps.”  ↩︎ For example, its Terms of Service prohibit cryptocurrency and blockchain projects.  ↩︎ Forgejo says federation is under active development and considered experimental . Moderation and access control have not yet been developed, and breaking changes are expected.  ↩︎ Radicle’s web interface is read-only , so interaction requires the CLI or desktop application. Features such as releases and bundled package registries are absent. CI is possible through community projects , but is neither official nor tightly integrated.  ↩︎ Bitbucket is the obvious existing counterexample: a conventional commercial forge that has never developed into a shared open-source community comparable to GitHub.  ↩︎ The English translation of the bylaws says Codeberg’s purpose “also intends to raise awareness for the social and philosophical questions” connected to free content and free software.  ↩︎ Stacked PRs split a large change into a sequence of dependent, individually reviewable changes.  ↩︎ For example, GitLab’s homepage describes it as “your intelligent orchestration platform for DevSecOps.”  ↩︎ For example, its Terms of Service prohibit cryptocurrency and blockchain projects.  ↩︎ Forgejo says federation is under active development and considered experimental . Moderation and access control have not yet been developed, and breaking changes are expected.  ↩︎ Radicle’s web interface is read-only , so interaction requires the CLI or desktop application. Features such as releases and bundled package registries are absent. CI is possible through community projects , but is neither official nor tightly integrated.  ↩︎ Bitbucket is the obvious existing counterexample: a conventional commercial forge that has never developed into a shared open-source community comparable to GitHub.  ↩︎

0 views
Lalit Maganti 1 weeks ago

AI agents are not subsystem maintainers

Antirez, the creator of Redis, recently argued that expert programmers using AI should think of themselves as being Linus Torvalds . The key part of his analogy is this: Automatic programming, instead, in the hands of people that are expert technicians, or expert programmers, expert designers, expert software architects, is to assume the role of Linus, with the agents and the LLMs assuming the role of the different maintainers of the different subsystems. This analogy does not work for me. As they exist today, I cannot be Linus and an LLM cannot be my subsystem maintainer. Why? In one word: trust . Linus trusts his subsystem maintainers. He is able to focus on the big picture, safe in the knowledge that his lieutenants will consistently exercise good judgment in the long-term maintenance of their subsystems. He knows this because they have earned his trust by proving themselves over and over again . Every time I have tried to give current LLMs the opportunity to prove themselves in this way, I’ve ended up regretting it. At a high level, I simply dislike too many of the decisions they make. This has happened even in areas (performance, databases, developer tool UX) where I feel qualified to judge how well an AI is doing. I’ve written about this in depth in my account of building Syntaqlite with AI , but beyond this, I’ve used LLMs in many different ways both in my job and in other side projects. If a human behaved like this repeatedly, I would not give them ownership of any part of a project I own. Trust has to be earned, and current agents have not come close to earning enough of it for me to step back. It is much cheaper for me to stay involved while the design is taking shape than to discover at the end that a sequence of plausible local decisions added up to the wrong system. And no, just passing tests or static verification is not enough for me. The decisions I most often dislike are precisely the ones that cannot be easily checked. Tests cannot tell me that an agent chose the wrong abstraction or produced an API that is unpleasant to use. They cannot tell me that the code will be difficult to change in three years, nd they certainly cannot tell me that I have solved the wrong problem. None of this makes AI a bad tool. With clear parameters and enough steering, it is an extremely capable bounded implementer. AI has substantially changed what I can build, and I use it extensively every day. But calling it a maintainer is a step too far. If I cannot trust it to exercise independent judgment, then I still have to own the code. At best, today’s AI is helping me implement my decisions; it is not freeing me to be Linus.

0 views
Lalit Maganti 2 weeks ago

How I Find Problems to Solve as a Staff Engineer

Note: this post was revised after publishing for increased clarity, based on reader feedback . “How do you find problems worth working on?” a senior engineer I mentor asked me recently. He’s trying to make the jump to staff engineer and realized that the role isn’t just about doing the work he’s assigned. He also needs to get involved in figuring out what his team and org should be building. Someone else had suggested blocking out time in his calendar to think about the bigger picture. He’d tried that, but hadn’t found it productive, so he asked if I had any alternatives. I told him I rarely find good problems by staring at a blank page and trying to “think strategically.” Instead, I act like a sponge. I listen to the stream of day-to-day noise, absorb the problems people are having and let them sit in the back of my mind. Over time, some fade away while connections begin to appear between others that initially seemed unrelated. Eventually, I start to see what’s really slowing people down and what my team or I can do about it. I’ve worked with many engineers who’ve never really tried this. They wait for managers or leads to identify opportunities, then demonstrate their value by solving the hardest assigned problems. That can absolutely lead to promotion. But the projects that have made the biggest impression in my career were the ones where I found and solved an important problem my leaders did not yet realize existed. One caveat: my experience comes mainly from working on infrastructure and developer tools at large companies, on teams where engineers have a lot of bottom-up autonomy to influence their roadmaps. In a more top-down environment, there may simply be less room to work this way. People love talking about the problems they are facing: in meetings, chat threads, presentations and email. They explain why their work is hard, complain about what slows them down and describe what they wish they could do. When something overlaps with my area, I start pulling on the thread. I might ask, “If X existed, would it solve your problem?” or point them at an existing feature in a product I own and ask how much of their use case it covers. Users often ask for a particular solution instead of explaining their root issue. Rather than taking the request at face value, I keep digging until I understand what they are trying to accomplish and why existing products do not work for them. As a natural introvert, this sort of ambient listening works particularly well for me. I don’t need to fill my calendar with speculative meetings just to find ideas; there is already an enormous amount of useful information flowing around me during a normal week. When a problem seems worth exploring, though, I become more active; I need to see how it affects the team’s day-to-day work. I’ll sit with them as they walk me through their workflows and the bugs they’re investigating. When I can, I’ll try working through some of those bugs myself. Seeing the problem firsthand makes it easier to separate what the team actually needs from the solution they asked for. I also seek out people who see more of the organization than I do: those who own critical systems, work across several teams or have particularly deep insight into the work downstream of my team. I’ll arrange a 1:1 or coffee chat and ask about interesting problems they’ve come across. They may have already seen the same issue in several places and started connecting the dots, giving me a head start on patterns I might otherwise have taken much longer to notice. Several times, I’ve been burned by moving too fast. I became excited by a request from a vocal team, built the feature and watched them barely use it. Their priorities had changed, or the request had come from a one-off investigation that no longer mattered. How eager a team was in that moment wasn’t the same as how important the feature was relative to everything else my product needed to support. By hyperfocusing on their request, I lost sight of the bigger picture. That taught me to let potential problems pile up. Listening the way I do leaves me with far more of them than I could possibly solve, and not all deserve action. Most don’t need to turn into projects the first time I hear about them; waiting can be a superpower. Waiting means the same problem might pop up independently in different teams, making it a higher priority to solve. Or problems that look different on the surface might turn out to have the same shape, so I can address several use cases in one shot. Or, as I’ve learned painfully, the requesting team didn’t even care that much in the first place. Instead, I make a mental note and revisit the problem if it comes up again. Other engineers I know write this sort of thing down more systematically. The mechanism is a personal choice: everyone has to figure out what works for them. What matters is keeping unresolved problems around long enough for more evidence to accumulate. Waiting helps me collect evidence, but that alone doesn’t tell me what to build. I still need to work out whether the problems I’ve retained are genuinely related and what, if anything, could address them together. Perfetto, the performance debugging tool I work on, is a good example. It displays recordings of system activity on a timeline made up of rows called “tracks.” Over a couple of years, teams kept asking for small, specific additions to the UI. One wanted a command to keep their preferred tracks pinned to the top of the screen; the next team wanted the same, but for a completely different set of tracks. Others wanted Perfetto to open already zoomed in on a particular part of a recording, or to show a custom aggregation tuned to what they cared about. A few had stopped waiting for us and built elaborate workarounds with bookmarklets. 1 By the time enough of these had piled up, my head was the usual tangle: the requests themselves, the constraints on each and a handful of half-formed solutions. I’ve learned not to force a solution by just sitting at a desk and thinking. Instead, my best untangling happens on long, aimless walks around London, where connections come more easily when I’m not trying to force them. What I eventually realized was that none of these teams really wanted the specific feature they’d asked for. Each wanted to personalize Perfetto for their own workflow without imposing their choices on everyone else. The underlying need wasn’t any one feature but rather the ability to extend the UI. When a connection like that finally clicks, it’s one of the best feelings in the job: several awkward requests collapse into a single idea, and possibilities open up that none of them hinted at on their own. That feeling, though, is exactly when I have to be careful, because a common shape is only a hypothesis and elegance is not evidence. When it happened with extending the UI it turned out to be real, but I’ve been fooled before. In another recent case I was convinced that building a transparent caching system for querying Perfetto traces would solve issues with sharing large traces and repeated queries. It was only as I wrote the RFC and built a prototype that I realized the elegance was a lie: the two problems wanted genuinely different solutions. I reluctantly split the design in two, both halves of which have since shipped. 2 You’d think this would be the moment I start building, but it usually isn’t. How far I go depends on how sure I am that the idea works and that people actually want it. If something is useful and low-risk enough, I act straight away: I send the change and let my manager know. When I’m unsure whether an idea will work or how much effort it will take, I build a throwaway prototype instead; it exposes the failure points and gives me something concrete for others to react to. And when an idea is big but I’m convinced by it, I commit to the full effort: weeks or months of work and the hard yards of building support across other engineers and teams. Through all of it, I’m not only trying to convince other people; I’m also trying to convince myself. Sometimes the honest answer is to stop: if people don’t see the value I do, or we hit a major technical wall, I’d rather drop the idea now than build something no one uses or that becomes a maintenance nightmare. And sometimes it holds up but the timing is wrong, so I park it, ready to spring into action the day it becomes an org priority. When an idea does hold up, I don’t necessarily need to be the person who builds it. I might implement it, someone else on my team might, or it might change what the org focuses on. Finding and shaping the right problem can have an impact even when I don’t own the implementation. The Perfetto extensions idea was worth that full effort. We were already building plugins to modularize the UI, but they weren’t enough: teams had to open source all their plugin code, which wasn’t an option for many internal use cases. So before building anything new, I took the problem and my proposal to my manager, teammates and the client teams. I ended up writing two RFCs, having several 1:1s and giving a couple of talks, refining it as the feedback came in. In the end, I designed and implemented macros as “lightweight extensions”: a way to automate actions in the UI without writing a plugin. Extension servers took the idea further by letting teams share their macros. Instead of implementing every requested feature ourselves, we gave teams ways to adapt Perfetto to their own needs. Dozens of teams inside Google now use macros and extension servers, and several other companies use extension servers internally too. The more often I go through this process, the easier it becomes. When I show genuine interest in someone’s problem, ask useful questions or help solve it, they remember. They start coming to me earlier and bring me into conversations with other people facing related issues. That gives me a wider view of what is happening across the organization, making it easier to spot patterns and build things people actually need. Solving one of those problems brings me into more conversations, and the loop continues. Those successes build the kind of trust that comes from long-term stewardship . Early on, I had to turn many of these ideas into something real myself to prove that my judgment was sound. Over time, my manager and org gave more weight to my assessment of what mattered. That allowed me to influence the roadmap without needing to own every project. This differs from the idea that becoming a staff engineer means replacing technical work with meetings and coordination. For me, conversations are inputs into what I build, not the end result. That is what I wanted my mentee to understand: finding problems worth solving isn’t separate from the rest of the job. It comes from staying engaged with people’s work long enough to see what no single request can show you. These workarounds used bookmarklets to run JavaScript against Perfetto’s internal UI APIs.  ↩︎ The original proposal was to use a transparent cache for repeated queries and faster reopening of large traces. As I worked through it, I realized repeated queries were better served by keeping sessions warm in memory, whereas reopening was better served by explicitly exporting a trace into a format designed to load quickly. A transparent disk cache could also retain multi-gigabyte files without the user realizing and would need a new system to manage their lifetime. The proposal was ultimately replaced by warm sessions and streaming table export .  ↩︎ These workarounds used bookmarklets to run JavaScript against Perfetto’s internal UI APIs.  ↩︎ The original proposal was to use a transparent cache for repeated queries and faster reopening of large traces. As I worked through it, I realized repeated queries were better served by keeping sessions warm in memory, whereas reopening was better served by explicitly exporting a trace into a format designed to load quickly. A transparent disk cache could also retain multi-gigabyte files without the user realizing and would need a new system to manage their lifetime. The proposal was ultimately replaced by warm sessions and streaming table export .  ↩︎

0 views
Lalit Maganti 3 weeks ago

What I'm Changing After A Year Of Blogging

Writing for the world is something which has ebbed and flowed for me over time. I’ve always liked sharing my thoughts, starting with websites all the way back when I was a kid. In times when I sustained it, I had various “blog”-like things for technical projects which would often veer into sharing personal beliefs as well. It’s been a year since my latest attempt at what I expect to be a lifelong endeavor. So I’ve been reflecting on how it’s gone, and that’s led me to make some decisions on how I want to rework things going forward. I have two goals with my writing: Although it might not seem like it, these goals are somewhat in conflict with each other. Sometimes I’ll write up TILs or low-effort posts which may not be that interesting to most people, and I don’t want these mixed up with my best work in the eyes of readers encountering me for the first time. I’m by no means unique in this; lots of internet writers have the same dilemma and take different approaches to dealing with it. Two options I considered are: I don’t like option 1 because I don’t particularly like social media. I was off it completely for years and have begrudgingly come back because it’s useful for sharing things with people, but it’s not something I enjoy. More importantly, I want everything I write to live on my own site, under my control, rather than scattered across platforms I don’t own. Instead I’ve taken option 2: I’ve decided to more strongly separate articles and notes from each other. The main way I’m doing this: I’m no longer going to be sending out notes over email on Substack . I initially conceived of Substack as a “newsletter” of sorts, rounding up everything new on the blog since the last edition. But over time I’ve come to dislike the effect this has: I don’t feel like sending out a newsletter until a high-effort article is ready to go with it. If nothing is ready, I end up just waiting, sometimes for more than a month. Why? Because I don’t want a newsletter edition which doesn’t put my best self forward. This might all be a me thing: I don’t know how many of my newsletter readers mind if I send them low-effort things. But I feel bad about it, and I think that’s enough for me to not do it. So instead I plan on reworking it from a newsletter into an articles-only feed. When an article is ready, I’ll publish it on the blog and send it out over email on the same day. I’m going to try to do this on Saturdays, though I can’t promise I’ll always manage it. At the bottom of each email, I’ll also leave a short “since I last sent you an article, I published thoughts on X, Y and Z”. But it’ll be a one line footnote, not the full content as I do today. If folks do want to subscribe to everything, my suggestion (see the subscribe page ) is to use RSS or an RSS-to-email service. Setting one up on my side would require either managing emails myself (which I think would be painful), manually copying posts to Substack (the tedium disincentivizes me from writing the short posts), or paying for a second email service alongside Substack (which I don’t want to do unless someone will actually use it). If you want everything from me in your inbox, reach out as it will help me decide if I should change my mind. This also knocks on to the homepage. In my previous redesign post I discussed how I switched to a two-pane dashboard feel and categorized what I wrote into three things: essays, write-ups and notes. While this was certainly cool and I liked it, I also constantly fell into the trap of having content which could debatably fall into either essays or write-ups. So I’ve erased that distinction: both are now simply articles, reflecting the effort and thought I’ve put into them. Notes remain much the same as before. I also went back to a single chronological feed, because readers gave me the feedback that they liked seeing at a glance if something was new, rather than scanning across three distinct sections to try to work it out. Articles are still clearly differentiated from notes though: they’re bigger, bolder and have explicit labels. Unrelatedly, I also spent a bunch of time improving RSS. After dogfooding my own feeds, I realized I had made some real mistakes in the way the feed was generated: content was losing all its links and being shortened. Now full articles are published properly to the feed (though things like sidenotes still won’t look the same as on the website). All in all, I feel a lot happier after figuring out how I wanted to handle high- vs low-effort content and deciding on making the Substack articles-only. My best work now gets presented in the way I want, and that makes me feel a lot freer to publish the imperfect stuff too. I want the freedom to write what I want and put as much or as little effort into it as I like. I care a lot about presenting the work I think is good in the best way possible to readers. High-effort content on the blog, low-effort content on social media. Separating content on the blog into high-effort (articles, essays) and low-effort (notes, snippets, TILs, etc.).

0 views
Lalit Maganti 3 weeks ago

The git history command deserves more attention

Working with lots of changes in parallel on git can be painful. You end up juggling branches and commits, and running scary commands that can leave your tree in a half-broken state if you so much as sneeze. , an alternative to , gets discussed a lot these days ( 1 , 2 , 3 , 4 ) and is often pitched as a solution. While I’m very sold on the problems is trying to solve, the way it solves them hasn’t quite hit home with me. Every 3 months, for the last 1.5 years, I try it out for a few days, really trying to make it part of my workflow but eventually I give up and go back to git. 1 That’s where comes in. It’s an experimental command that arrived across two releases, 2.54 (April, and subcommands) and 2.55 (June, subcommand). It got a flurry of attention on each release day, and then, as far as I can tell, not much community discussion since. Which is a shame, because IMO it already delivers several of the benefits people tout for without needing to switch your whole workflow. And the cool thing is that it’s part of the core git distribution, so you can try it without installing anything.

0 views
Lalit Maganti 1 months ago

Perfetto v57: fixing PyTorch traces, plus journald logs and an AI skill

We just released Perfetto v57 and I wanted to share the new things I’m most excited about. This is something I wanted to do for past releases but I just never quite got round to it. It’s also something I plan on doing more of going forward: there might even be dedicated pieces if I think the feature deserves it! What I’m most excited about in this release isn’t a feature but a bugfix. If you used the PyTorch profiler and opened the resulting trace in Perfetto, there was a decent chance some of your events would just not show up; specifically this would happen when these events overlapped each other on a single track. Technically, PyTorch is in the wrong here. The Chrome Trace Event (JSON) format says duration events on a track have to nest and can’t overlap; if you need overlap, you’re supposed to use async events. appears to handle them, but its rendering is actually buggy as soon as a trace has real overlaps; people just learned to live with it. So when a bug came in January about overlapping events being broken, I closed it as working-as-intended because I couldn’t see any easy fix from our end.

0 views
Lalit Maganti 1 months ago

On "When impressive performance gains do not matter"

When impressive performance gains do not matter is a very nice article covering some ways in which going after performance alone is not sufficient without considering the wider picture. It resonated a lot with how I think about performance. If there are multiple bottlenecks in the pipeline—and with these systems, this is common—the overall throughput will not improve until every last bottleneck is removed. His focus is on distributed systems bottlenecks, but I’ve hit the same “do-nothing” speedups when optimizing client side programs. Usually this comes from spending a lot of time thinking something was the bottleneck when it wasn’t. CPU profiling is where this bites me most: it tells me “function X is taking 30% of the cycles” and I think “oooo, there’s a lot of gains to be made there”. I build a microbenchmark for X, optimize it and there’s only a marginal gain at the high level. While disappointing, I’ve become used to it over time and internalized that performance is highly non-linear and actually knowing where the problem lies is really hard.

0 views
Lalit Maganti 1 months ago

syntaqlite 0.6: SQLite dot commands and pyodide

Since my original launch post for syntaqlite, I’ve been quietly working away on it in the background. A lot of the work has been fixing correctness bugs which I discovered as I integrated it into production as the parser for PerfettoSQL in the Perfetto trace processor: as I wrote previously, this has been my dream for over 8 years so it’s amazing to see it finally realized. Just today, I released syntaqlite 0.6 , the most interesting release since the original launch, so I wanted to talk about what’s new. The biggest step forward for real world applicability is that we now support SQLite dot commands : SQLite scripts are very common in the wild and in the past we would simply error on dot commands like and , causing spurious warnings and an inability to format files like this properly. Now, these lines will be silently ignored while still parsing, formatting and validating the SQL inside!

0 views
Lalit Maganti 1 months ago

TIL: Iroh: peer-to-peer networking for app developers

I came across Iroh ( via , via ) today as it hit 1.0 and found it a really interesting solution to a problem I knew existed but had not thought a lot about. Judging from the comment sections, it seems pretty clear that lots of people are confused as to exactly what Iroh is. I don’t think their launch post does their product justice at all, and their tagline is “IP addresses break, dial keys instead” which sounds cool, but if you think about it for just a second, you’ll end up with lots of questions. The biggest one is: “so how is this different from a mesh VPN like Tailscale, ZeroTier, Netbird, etc.?” It’s only after reading a lot of developers’ comments on the threads that I feel I understand: Iroh is aimed at  application  developers who want to communicate P2P between machines running their app, while mesh networks are aimed at  network admins  who want to connect devices they own/manage together.

0 views
Lalit Maganti 2 months ago

17 bugs in 10 weeks from AI security scanning

Over the last several weeks, I’ve been receiving more security bug reports for Perfetto’s trace processor than I ever have before, all of them found by AI. And I’m very happy about it! These are bugs that would almost certainly not have been found a year ago and it feels good to close these loopholes even though trace processor is by no means security critical. For years, security researchers concentrated their time on the highest-stakes targets: kernels, cryptography libraries, password managers. But there’s a lot of code out there which is security-relevant but not truly security-critical. In my experience, these sorts of projects didn’t draw much attention. Now systems in the long tail can get that attention which they wouldn’t have before. Trace processor is a project which sits squarely in that long tail. It’s a C++ library (yes, Rust would be the obvious choice today but it’s not practical to rewrite, see footnote 1 ) for processing recorded traces of various formats. These are typically traces you collected yourself or in your test infra and process offline so “untrusted input” isn’t much of a concern.

0 views
Lalit Maganti 2 months ago

Which country voted the best at Eurovision?

Eurovision was on yesterday. I’ve never been interested much in the musical side but the weird political dynamics of Eurovision voting have always fascinated me; I tune in each year just for them and somewhat snarky commentary of Graham Norton, the UK commentator. As I was watching the jury votes come in, a question popped into my head: Which country has voted the best in Eurovision? That is, which country was best at picking the eventual top 10 and in the right order? Strangely enough, while there’s plenty of work on voting blocs and bilateral biases at Eurovision, most of it asks who votes for whom ; I wanted to ask who votes accurately . I couldn’t find anyone asking the question that way, so I decided to do some data analysis myself. To begin to answer this question, I first needed to formalize what “best” even means. That is, some mathematical notion of “good” and “bad”.

0 views
Lalit Maganti 2 months ago

Don't answer the first question

In my work on Perfetto, a performance debugging tool, one question I get often is: “how do I split a Perfetto trace into multiple files?” Instead of answering directly, I say: “there isn’t an easy way to do that, but what’s leading you to collect traces large enough to want to split?” This is one of my golden rules at work. When a user asks me something “weird”: don’t answer the first version of the question . On the surface this might appear like I’m talking about the XY problem , but that stops one step short. It treats the user’s stated question as a puzzle to decode: figure out what they really meant, answer that, move on. I think we can go much further. Instead, the confusion that produced the wrong question is itself an opening, and the conversation it sparks is valuable to both sides. The user walks away with a better mental model of the tool. I walk away with a clearer picture of where the product confuses people. And sometimes, between us, we figure out that the product itself needs to change.

0 views
Lalit Maganti 4 months ago

Eight years of wanting, three months of building with AI

For eight years, I’ve wanted a high-quality set of devtools for working with SQLite. Given how important SQLite is to the industry 1 , I’ve long been puzzled that no one has invested in building a really good developer experience for it 2 . A couple of weeks ago, after ~250 hours of effort over three months 3 on evenings, weekends, and vacation days, I finally released syntaqlite ( GitHub ), fulfilling this long-held wish. And I believe the main reason this happened was because of AI coding agents 4 . Of course, there’s no shortage of posts claiming that AI one-shot their project or pushing back and declaring that AI is all slop. I’m going to take a very different approach and, instead, systematically break down my experience building syntaqlite with AI, both where it helped and where it was detrimental. I’ll do this while contextualizing the project and my background so you can independently assess how generalizable this experience was. And whenever I make a claim, I’ll try to back it up with evidence from my project journal, coding transcripts, or commit history 5 .

0 views
Lalit Maganti 4 months ago

syntaqlite: high-fidelity devtools that SQLite deserves

Most SQL tools treat SQLite as a “flavor” of a generic SQL parser. They approximate the language, which means they break on SQLite-exclusive features like virtual tables , miss syntax like UPSERT , and ignore the 22 compile-time flags that change the syntax SQLite accepts. So I built syntaqlite : an open-source parser, formatter, validator, and LSP built directly on SQLite’s own Lemon-generated grammar. It sees SQL exactly how SQLite sees it, no matter which version of SQLite you’re using or which feature flags you compiled with. It ships as a CLI , VS Code extension , Claude Code LSP plugin , and C / Rust libraries. There’s also a web playground which you can try now: paste any SQLite SQL and see parsing, formatting, and validation live in the browser, no install needed. Full documentation is available here . Here’s syntaqlite in action: Formatting with the CLI Validation with the CLI

1 views
Lalit Maganti 6 months ago

Rendering 100k trace events faster with exponential search

We’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’re very zoomed out. 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 “what is the event which we should draw for this pixel”. Over time we’ve come to the conclusion that the best thing to draw is the slice with the largest duration in that pixel. We can break this into two sub-problems: We’re going to focus on 1) in this post as that’s where the slowdown was. 2) is fascinating but also surprisingly orthogonal. If you’re interested, I would suggest reading this excellent post from Tristan Hume explaining the basic algorithm we use. What is the range of events which correspond to each pixel? What is the event with the maximum duration for that pixel?

2 views
Lalit Maganti 6 months ago

The surprising attention on sprites, exe.dev, and shellbox

Over the last few weeks, three new products have announced themselves on Hacker News to great success, each making the frontpage: All three have a very simple pitch: they will give you full access to Linux virtual machines to act as a sandboxed developer environment in the cloud. At first glance, the attention these have gotten is very head-scratching. The idea of a Linux VPS has been around for more than 20 years at this point and VPS providers like DigitalOcean and Hetzner are widely known and used in the industry. From a technological standpoint, there’s very little revolutionary here. Is it price then? Well no: the hardware specs are pretty awful for what you pay. For example, exe.dev gives you 2 CPUs and 8GB RAM shared across your whole account for $20/month. For comparison, at Hetzner for roughly that price, you can get a single VPS with 16 CPUs and 32GB RAM… Sprites (fly.io) with 508 votes and hit #7 exe.dev with 457 votes and hit #2 shellbox.dev with 316 votes and hit #4

0 views
Lalit Maganti 6 months ago

Why Senior Engineers Let Bad Projects Fail

When I was a junior engineer, my manager would occasionally confide his frustrations to me in our weekly 1:1s. He would point out a project another team was working on and say, “I don’t believe that project will go anywhere, they’re solving the wrong problem.” I used to wonder, “But you are very senior, why don’t you just go and speak to them about your concerns?” It felt like a waste of his influence to not say anything. So it’s quite ironic that I found myself last week explaining to a mentee why I thought a sister team’s project would have to pivot because they’d made a poor early design choice. And he rightfully asked me the same question I had years ago: “why don’t you just tell them your opinion?” It’s been on my mind ever since because I realized I’d changed my stance on it a lot over the years.

0 views
Lalit Maganti 7 months ago

One Number I Trust: Plain-Text Accounting for a Multi-Currency Household

Two people. Eighteen accounts spanning checking, savings, credit cards, investments. Three currencies. Twenty minutes of work every week. One net worth number I actually trust. The payoff: A single, trustworthy net worth number growing over time. No app did exactly what I needed, so I built my own personal finance system using plain-text accounting principles and a powerful Python library called Beancount . This post shows you how I handle imports, investments, multi-currency, and a two-person view. It all started during the 2021 tax season. I had blocked out an entire weekend and was juggling statements, trying to compute capital gains, stressing about getting the numbers mixed up. “This is chaos”, I thought. “There must be a way to simplify this with automation”. Being a software engineer, I did what felt natural and hacked together a bunch of scripts on top of a database.

0 views
Lalit Maganti 8 months ago

Homepage Redesign, Light Mode and More

Just a quick note documenting some recent changes to the blog. Nothing groundbreaking, but enough accumulated updates that I wanted to write them down. The homepage used to be a chronological list of articles; your classic default blog format. I’ve redesigned it into more of a two-pane “dashboard” feel. The reason? My content is quite varied: I have long essays and technical write-ups but also short TIL or notes posts (like this one!). Having a way to differentiate between them while also scanning across the titles of different types of posts felt really valuable. I was inspired by this post which I stumbled across. A couple of days ago, a reader emailed me and asked if I could add a light mode to the blog because they were reading in a bright environment. Though personally I prefer dark mode, I appreciate not everyone agrees so it made sense to add.

0 views
Lalit Maganti 8 months ago

Why I Ignore The Spotlight as a Staff Engineer

Discussed on Hacker News , lobste.rs and r/programming. Lately I’ve been reading Sean Goedecke’s essays on being a Staff+ engineer. His work (particularly Software engineering under the spotlight and It’s Not Your Codebase ) is razor-sharp and feels painfully familiar to anyone in Big Tech. On paper, I fit the mold he describes: I’m a Senior Staff engineer at Google. Yet, reading his work left me with a lingering sense of unease. At first, I dismissed this as cynicism. After reflecting, however, I realized the problem wasn’t Sean’s writing but my reading. Sean isn’t being bleak; he is accurately describing how to deal with a world where engineers are fungible assets and priorities shift quarterly. But my job looks nothing like that and I know deep down that if I tried to operate in that environment or in the way he described I’d burn out within months . Instead I’ve followed an alternate path, one that optimizes for systems over spotlights , and stewardship over fungibility .

0 views