Articles on Eric Fritz
Recent content in Articles on Eric Fritz
Latest posts
My AI junior dev still needs an adult in the room
The past two years has been a constant and exhausting barrage of AI hype. At the beginning, I was ready to dismiss the utility of AI coding assistance entirely. My employer at the time threw all available energy chasing this trend. It sucked all the air out of the room and extinguished all existing efforts. I didn’t understand why. Back then, GitHub Copilot was the state-of-the-art AI…
A visual intuition for the Box-Muller transform
When trying to generate fake data for a database performance test, I found myself falling down a rabbit hole researching how to create random variables that fall into a specific probability distribution. Finding myself with a solution but without intuition, I ended up creating an interactive visualizer to help learn more deeply what was going on. I encourage you to both read on and take the…
Hosting a blog like it's 2024
This blog is built by the Hugo static site generator and hosted by Render, along with a number of other sites I maintain with an identical deployment. Before joining Render and discovering how freakin’ slick it is for hosting static sites, I had massively over-engineered my own patchwork solution. I had built a Zastava Yugo from spare parts when I could’ve just called an Uber. This…
Sourcegraph went dark
Towards the end of my mid-2019 job search, I was down to joining the Google Go team or Sourcegraph. Sourcegraph ultimately won due to cultural factors - the most important of which was the ability to build 100% in the open. All documents were public by default. Technical and product RFCs (and later PR/FAQs) were drafted, reviewed, and catalogued in a public Google Drive folder. All product…
I am abusive to Git
When I was working as a Staff Engineer at Sourcegraph, I performed a lot of “exploratory coding” that helped determine if some nascent idea is able to stand on its own legs. If the idea was validated with sufficient confidence, it would be polished, productionized, and shipped. Sometimes the polish ended up taking the majority of the effort. Often times these ideas were backtracked and…
PostgreSQL Stories: Taking Random Samples from Big Tables
PostgreSQL Stories: A simple query with a big problem
PostgreSQL Stories: From slow query to fast—via stats
Precise Code Intelligence: An LLM Antihallucinogen
This article was originally written on July 3rd, 2023 but was never officially published. I am publishing this here as a historic snapshot of an interesting technical project, though the details of this article are likely out of date and no longer indicative of the current capabilities or development methodology of Cody, Sourcegraph's AI Coding Assistant. Within the rapidly expanding domain of…
Pearl: Compressing source code ranges
Since the dawn of time, mankind hath sought to make things smaller. One of the favorite little pieces of code I wrote during my time at Sourcegraph was an EncodeRanges function that took a series of offsets into a text document and compressed them into a tight, tiny, opaque ball of bits. At the time, I was designing a new set of Postgres tables and indexes that would store a quick way to go from a…
Home office setup
I recently ended a four (plus) year stint at a geographically distributed, all-remote, async-first startup, and began a similar remote role at another slightly earlier stage SF-based startup. I took the two weeks between jobs to tidy up my home office to clean my mental slate. It’s like cleaning your dorm between terms: new semester, new me. I snapped a few pictures to immortalize the…
Precise Code Intelligence: An LLM Antihallucinogen
Ranking in a week
Last week we announced that we are now ranking search results on https://sourcegraph.com in order to prioritize relevant as well as reusable code. We consider this Sourcegraph’s code intelligence platform’s first major victory of many, and a booming herald for a new era of code search. The effort to bring ranked results to our public instance was a concerted effort of four developers across…
Multi-version upgrades
It’s finally happened. The most obnoxious restriction (by a very wide margin) related to administration of a Sourcegraph instance no longer applies. Sourcegraph instances (v3.20 or newer) are now able to upgrade directly to a future release, without the requirement to hit every minor release along the way. A recent peek at our customer instance distribution showed that 70% of our self-hosted…
How to Stop Autovacuum from Sucking up Your Performance
How we finally fixed an embarrassing (migration) problem
We have recently identified the root cause of a frequent, insidious pain point related to database migrations during Sourcegraph version upgrades. Many users handling the installation and upgrade of their Sourcegraph instance can likely attest to seeing an error similar to the following midway through an upgrade from one minor release to the next. ERROR: Failed to migrate the DB. Please contact…
Optimizing a code intelligence commit graph (Part 2)
In Part 1 of this optimization story, we detailed how Sourcegraph can resolve code intelligence queries using data from older commits when data on the requested commit is not yet available. The implementation lies completely within PostgreSQL, and the queries run with very low latency (< 1ms). We boldly claimed that our fears of scalability were no longer cause for concern. Turns out that claim…
Optimizing a code intelligence commit graph (Part 1)
Sourcegraph’s Code Intelligence team builds tools and services that provide contextual information around code. These enable users to perform fast, comprehensive, and accurate code navigation, and to surface dependency relationships across projects, repositories, and languages. In this post I’ll dive into how Sourcegraph can resolve code intelligence queries using data from older…
Why we're updating the minimum supported version of Postgres
As of Sourcegraph 3.27 (released April 20, 2021), we’re updating the minimum supported version of Postgres from 9.6 to 12. If you are maintaining an external database and your Postgres version is older than Postgres 12, you will need to update your database instance prior to upgrading from Sourcegraph 3.26 to 3.27. See the following instructions for a step-by-step guide. If you are using the…
Migrating to Postgres: A Cloud of Mistakes
At Sourcegraph, we have recently decided to migrate code intelligence data that has historically been stored in thousands of SQLite databases on disk into a single Postgres instance. Long story short, we were running into some limits of writing a persistence layer over SQLite databases in a consistent way. We were unable to horizontally scale, as one database can only be opened by one backend at a…
Optimizing a code intelligence indexer
We (Sourcegraph’s Code Intelligence team) recently made Go code intelligence faster, especially on very large repositories. For example, we cut the indexing time by 95% for the huge Go AWS SDK repository, from 8 minutes to 24 seconds. Here’s how we did it. Background: what is code intelligence? Developers use Sourcegraph for code search and navigation. When you’re navigating code…
Evolution of the code intelligence backend
Jumping to the definition of a symbol under your cursor and finding all its references are two of the basic mental mechanics of software engineering. Fast code navigation accelerates the rate at which you can build a mental model of the code, and when it’s available, you’re likely to use it hundreds, if not thousands, of times per day. Code navigation is the core of how Sourcegraph…
Optimizing a code intelligence backend
When it comes to developer tools, speed is a critical feature. The difference between a 100ms, 1s, and 10s delay fundamentally alters user psychology—it’s the difference between coding at the speed of thought vs. losing focus as your mind wanders while waiting for the UI to respond. One of Sourcegraph’s magic powers is its ability to provide compiler-accurate code navigation in…
Works On My Machine
As described in a previous article, Sourcegraph’s main source of truth for all code data is gitserver, which is a sharded RPC service wrapping git commands. Requests to this service specify a repository name, which indicates the directory to perform the git command in, as well as the arguments that should be passed to the command. The LSIF service needs to fetch commit ancestry data from…
Easy Peasy SQL Audit Tables
Deposition (described in a previous article) is a tool used to track the dependencies and vulnerabilities of a software project. This product belongs to a class of tools that benefits greatly from the existence of an audit log. Most of the time, modifications to data via the API are performed by a build user in the context of a continuous integration system. The API and the UI does allow data to…
Subtle Circular Import Bug
Sourcegraph’s main source of truth for all code data is gitserver, which is a sharded RPC service wrapping git commands. The LSIF service requires git ancestry data in order to answer queries such as find the commit closest to $c$ for which we have LSIF data, or determine if commit $c$ (for which we have LSIF data) is the closest such commit to the HEAD of master. Each query to the LSIF…
Found a Golang Bug!
I have to say, this was a cool milestone in my career. Before we start this story, I need to point out that if you think that your application is behaving in a strange way due to a compiler bug, a programming language runtime bug, an OS bug, or a hardware bug, you’re almost certainly displaying a disproportionate amount of hubris. But sometimes you just hit those weird edges. On January…
Testing Patterns in Go
This article outlines some patterns of unit testing in Golang that I have found, over time, to work extremely well. he testing code here assumes the use of the gomega assertion library and the sweet test-suite runner library. Mocking Interfaces Consider the following definition of the function WithCache that memoizes the result of a function using a cache instance that conforms to the (simple)…
Arrow-Structured Concurrency
This article adapts some ideas from Arrows for JavaScript for use as concurrency primitives for some high-level language as a response to Nathaniel Smith’s article Notes on structured concurrency, or: Go statement considered harmful published on April 25, 2018 and Martin Sústrik’s response Structured Concurrency in High-level Languages published on April 28th, 2018. In the first half…
Deposition
Impetus In Autumn 2017, we had an incident involving multiple services crashing and failing to re-initialize. We quickly correlated the time of the crashes with the time our Elastic Stack became unavailable. We then determined that our logging library did not put a maximum capacity on the number of log messages in the publish queue (see gomol issue #20), causing the memory usage of the application…
Linear MTF Hash Table
Vehicular routing is a very interesting real-world problem that contains two distinct but interacting combinatorial optimization problems: the travelling salesman problem (TSP) and the 0-1 knapsack problem (KP). This unison of problems, unfortunately, creates a lot of opportunity for local maxima. Finding a better route for a particular truck may decrease the optimality of the contents fo the…
An Adventure in Unstable APIs
Antirez announced the Redis module system in May 2016. At this point in time, Charon’s Redis interface was a set of Lua scripts which was the best available solution for atomicity and bandwidth at the time. Because scripts simply invoke other Redis commands, the data model had to be designed carefully to fit into Redis’s supported datatypes. As a result, each script modified up to a…
Charon Simulator
Configuring rate limits Charon, as described in the whitepaper, is a cooperative system used to enforce limited access to resources on behalf of users. For example, an HTTP API server can choose to immediately return an HTTP 429 response if the limited resource has had a large number of requests from that user in its recent history. This can help save, for example, expensive database operations…
On Monads
Just kidding.