Brandur

Brandur

@brandur.org

Engineering @ Stainless. Ex-Heroku, Stripe, and Snowflake. Go, APIs, Ruby, and databases.

1.6K followers21 following79 posts

Tiny workflow optimization of the week: after switching to one of these terrible Apple keyboards with borderline unusable arrow keys, added bindings for Vi-style Ctrl+K/J for up/down history on Zsh prompt. bindkey '^K' history-search-backward bindkey '^J' history-search-forward

I'm embarrassed to say that I installed Postgres 18 and just tried to use the `io_method = io_uring` on my Mac. What can I say except, it's early. Kind of. Wouldn't it be nice if Apple actually added stuff like `io_uring` though.

Everyone knows about async I/O and UUIDv7 in Postgres 18 by now, but I was surprised to find out that `RETURNING` is getting `OLD.*` + `NEW.*`! Great new feature. Lets me unwind some old hacks involving `xmax` to check if an upserted row is new or not. www.crunchydata.com/blog/postgre...

crunchydata.comPostgres 18: OLD and NEW Rows in the RETURNING Clause | Crunchy Data BlogPostgres 18 now lets you see both old and new data when you add the RETURNING clause to an UPDATE statement

An overzealous/bad security team makes following security protocols so onerously difficult that people don't use them, or find workarounds. The net effect is organization ends up with *less* security. Is there a name for this very widespread phenomena?

Getting back into Kubernetes for work after years away, my main takeaway is that although Kubernetes is still kind of a meh complexity/value proposition, Argo CD is absolutely incredible. Glad there's a Kubes CLI, but having a great UI to backstop you changes the game. cd.apps.argoproj.io

Today, came across a Go package literally named "event". Such bland naming doesn't just hurt users, it hurts the package because being hard to google makes it less likely to be adopted. Ultra-generic naming isn't cool. It's just bad. For the love of god: brandur.org/fragments/go...

Still no RETURNING clause in MySQL ... It makes me really skeptical of anyone hawking MySQL as a competitive, modern database. If such a baseline, uncontroversial good idea is missing after a decade, what else is?

Past 8 PM, there is more life on one street corner in Berlin than all of San Francisco combined. It's wild. Annoying to no end that America's most beautiful cities are compromised because we let boomers who bought homes in 1980 for $50k pull up the ladder behind them.

Recently learned about the "American Frontier" movie trilogy, or in other words that Sicario (first watched a decade ago) has two spiritual successors. Watched Wind River tonight. Easily the best movie I've seen all year.

Tiny tool sharpening: noticed over the years Vimium getting less powerful and had assumed it was Chrome slowly killing extension capacity, as they do. Today, recovered some important ones with custom bindings. Also, smooth scrolling -> off to get rid of awful scroll animations.

Watched "Fountain of Youth" (2025) last night. The film industry will forever remain a mystery to me how the same person (Guy Ritchie) who directed Snatch, Lock Stock, and Sherlock Holmes can also be responsible for this tire fire.

Just in case I'm not the only one who didn't know about this (it's not new, but TIL for me) ... you can set watches on GitHub repos based on custom settings, like for releases only. So useful.

One of these is parody. The other is real. Which is which? We need to go back to designers making things for people, and function over form. For a decade plus, designers have been exclusively making things for other designers, and favoring form over function throughout.

The bull vision is a fourth Postgres cloud that's competitive in scope with AWS / Azure / GCP. A maximum array of small Postgres providers is optimally good, but also, as long as tech titans are powering an outsized amount of Postgres, the more titans competing, the better.

Amazon's Wheel of Time series cancelled. I've never been happier to see a show go. I thought I'd love a TV adaptation, but after seeing this and Rings of Power, I say: leave books as books. Budgets can't be big enough to do them justice, and there are just too many ideologues in Hollywood.

What's more exciting? This, or iPhone 17? Just kidding. It's a rhetorical question. Nobody cares about the iPhone 17.

Wrote a timestamp to SQLite as "2006-01-02T15:04:05.999" instead of "2006-01-02 15:04:05.999" [1]. Every subsequent query failed. No error. No warning. Just silent failure. Fellow Postgres users: just remember everyone, we've got it pretty good. — [1] Strings because SQLite has no time types.

Most of us would be disappointed to learn how much of the tech we use works by virtue of sheer, overwhelming brute force. As in, the implementation isn't elegant, simple, or even good, but works by having colossal quantities of compute/storage thrown at it so it's Good Enough™.

Waymos are the best thing to happen to SF in decades. Tech is amazing. Even better is the natural traffic calming they create. The more Waymos, the safer the streets. They're going to save a lot of lives. San Franciscans will fight it kicking and screaming every step of the way.

Watching "progressive" San Franciscans turn red in the face with rage as they're forced to stop at a crosswalk or stop sign (an inhuman indignity no Californian should ever have to endure) because the Waymo in front of them is doing it will *never* get old.

Damn, we need to have a serious conversation about programming docs standards. >50% of the time they're so bad that why even bother. Data defines the data. X0 defines the X0. X1 defines the X1. Y0 defines the Y0. What else did you want to know dummy?

After implementing support in our home-grown Go data loader for `SELECT ... WITH UPDATE` yesterday, I'm now wondering how may apps use something like Rails' `Locking::Pessimistic` versus YOLOing (like we were) because transaction anomalies are rare and it's usually okay. Probably 80%+ the latter?

Upgraded projects to golangci-lint v2 yesterday. The change in conf format was a bit irking, but the built-in migration tool worked reasonably well. V2's error output is better in that it summarizes failing lints, and so far fewer obscure caching bugs compared to v1. ldez.github.io/blog/2025/03...

IMO, the right way to to do data fixtures in Go: * No framework needed, but use sqlc + validator. • Real DB records. • No error return to making calling succinct. • Pointer helpers to get 4 LOCs down to 1 LOC. • Defaults for everything possible. brandur.org/fragments/go...

It's always such a nice surprise finding a fast, well-written test suite (they are very rare). Here's the Sequel gem's (Ruby ORM). 18 year old project. Runs <10s on battery power.

Come MacOS 15.1, no more X button on this thing. You can snooze for an hour, or activate it then fuck around in settings to cancel it, but the user-hostile UX/Security teams at Apple are sending a clear message: the computer you bought was never yours, and you're on our schedule.

It's always mildly terrifying when a product has a "try our new UI" button, especially when the UI is already good. But ... tried it with Sentry and good results so far. Comments without needing to access them via sub-widget is a win.

Instead of allowing trailing commas in SQL—which will save thousands of wasted hours per year and has no downsides whatsoever—everyone should adopt my completely unintuitive, labor intensive alternative styling that moves the problem of a trailing comma to one of a leading comma.

Squashed 2/2 (100%) known intermittently failing tests in the past 24 hours. You have to be the Liam Neeson of tracking down and destroying these things. If allowed to fester, they accumulate and turn DX to mush in mere weeks.

We started measuring memory allocs over API requests in production to track down some sudden memory overruns. `runtime.MemStats` in Go needs to stop the world to get a stable reading, but we found its overhead for 2x calls an acceptable ~100µs. brandur.org/fragments/pr...

brandur.orgProfiling production for memory overruns + canonical log statsUsing Go’s <code>runtime.MemStats</code> and canonical log lines to isolate huge memory allocations to a specific endpoint.

Put in a novel new system to dump a pprof profile to S3 if a request exceeds 1 GB allocations, then the memory overruns I'm trying to debug ... stop happening. Of course.

If Wise were to become a template for security on the internet, it's going to be a painful future. For one money transfer in a <15 min session: • 2x password prompts. • 1x TOTP prompt. • 2x SMS code prompts. Product engineer who knows security >> security engineer.

I'm tempted to call out anyone using `_1` for an unnamed closure variable now that Ruby 3.4 brought in `it`. But also, every time I think about using `it`, I use `_1` instead because `it` is just an awful name for an unnamed closure variable. So I just shut up about it instead.