I live in Singapore, and I’ve spent 6 years I’ve been here working remotely for companies where most employees aren’t located in Asia. Grafana is globally distributed, but the distribution is extremely lumpy - ask any of our APAC engineering colleagues. I like Brendan Gregg’s piece 3 years of Extremely Remote Work very much, but it largely covers the challenge of being a remote worker when most of the people you work with are co-located and in an office. That’s not my experience, so I wanted to share a little about being a “more isolated” remote engineer in Asia and what it takes for a company to be effective with these employees.
We lost the ability to write online
Here are some slop “signs” that I find triggering:
- Quietly
- Load-bearing
- Not one. Not two. Just three phrases destroying the flow of all online writing.
They’re all over the internet now! You see this most when there’s pressure for volume. Instagram and LinkedIn posts, high-volume, low-quality sites like The Verge. Outside of the headlines, I think people barely read these things anyway. But it has also violently infected programming blogs - largely because I think we’ve gotten so comfortable using LLMs for so many other parts of our work.
DICOM is a disaster for patients
I recently had a few different scans of my body and brain done. Hooray for turning 40! At each imaging center I was given a USB drive “with my images on them.” It turns out those images are in a format called DICOM, and they usually come bundled with some kind of viewer application.
These things are a disaster!
- When you open them, you get to input a password made wholly of easily-findable data like date of birth and national ID number.
- The folder structure is a mess and differs from provider to provider. Just finding the DICOM is annoying even for my doctors.
- They ship old versions of free DICOM viewer software like MicroDicom and Weasis. These naturally fail OS integrity checks, which means you either get to bail, dig through OS settings, or call your grandson.
- The disks have known security insanity on them like
autoexec.bat. In 2026!
This could be improved easily:
My AI coding setup today
My AI coding setup has been evolving the last few months. Here are some things I’ve tried and moved on from:
- Gas Town. It’s just too much to wrap my head around right now.
- Pi and custom harnesses. I’m not at the stage where I need to deeply customize my workflow, starting from zero. I’m also not at the stage where I’m frequently switching models for different tasks. The Claude CLI is still good for me at this stage.
Here’s my current simple-to-use setup today:
Zen: A Browser You Can Love
Everyone is putting AI in their browsers now. Good (maybe even great!) browsers have been discontinued so users can focus on AI.
I’m not opposed to using AI agents for all sorts of things, but I don’t feel comfortable giving it nigh-unfettered access to the web. I’m not ready to let LLMs take on life-altering responsibilities like booking flights, looking at my banking sites, or reading my emails. I don’t trust their data retention policies with potentially sensitive context like calendars or emails. Nobody’s
Multi-agent coding and the resurgence of the terminal
All of the exciting AI coding is happening in terminals. Codex is good, the various VSCode forks are good, but if you’re doing multi-agent orchestration you’re generally using terminal UIs, roped together with Gastown, agent-deck, OpenClaw, lemonaid, or something else.
It’s gratifying, as someone who never left the terminal for a “grown up” IDE, to see how small programs piped together is the paradigm for innovation here. The stuff that makes it possible? Simple, largely open-source tech:
Introducing nvim-beads: Manage beads in neovim
A few days ago my co-worker Bob turned me on to Beads. Beads is a step up from things like PLAN.md when managing work for coding agents, because it provides more structure, is easy for agents to parse, and provides things like progress tracking for multi-agent workflows.
I was intrigued by the setup because it seemed like a way to improve my agent’s ability to work autonomously, but I needed a way to try it out without stepping on top of some complex multi-person projects at work. I decided to use bd and a coding agent to implement a neovim plugin for managing beads.
Podcasting is dominated by warm applesauce
The end of podcasting as a viable cottage industry really does seem to be here now, and the end of podcasting as a culture-moving media format has arrived. Amy Poehler won the first podcasting Golden Globe for a “hang out and promote my new project” podcast. Most celebrity podcasts are this way. Even the ones that ostensibly have a theme: Smartless is barely anything anymore. They’re warm applesauce, and they dominate the format to the point that ad revenue is draining away from a lot of better shows.
All the data had nowhere to go
Pablo Torre is on episode 506 of TrueAnon1, which is mostly about the NBA-adjacent poker fixing scandals, but touches on sports betting. The fact that data collection is not a neutral activity comes up repeatedly.
Player performance is monitored and measured for non-nefarious reasons: players and teams both benefit from better understanding of strengths and weaknesses in different ways. Pablo makes the case that the mere existence of this data - the predominance of statistical analysis in front offices and the advanced stats published by the leagues - changed the culture of American sports in negative ways. Rationalization of athletic performance led fans to believe the could get some edge (alpha in the financier’s language), and sports gambling was the natural outlet for this.
Finding “Just Fine”
I’ve had a record player for at least 20 years. For the last 10 or so it was an Audio Technica LP120, which is on the upper end of ’non-audiophile’ turntables. Swappable cartridges, tons of tracking force adjustments, speed adjustments and strobes to check for accuracy. Direct drive. I ended upgrading the cartridge at some point. I loved that turntable, and it was darn reliable.
I did manage to fry it on 220v here in Singapore, despite the fact that it advertised compatibility with 220v. After it broke, it didn’t take me long to find a successor: an Audio Technica LP70X, which is in many ways the opposite: Fixed cartridge, no tracking force adjustment or speed adjustment. Belt driven.
LLMs are great at box diagrams
I love diagram languages like mermaid.js and PlantUML because the text format that backs the diagram can be tweaked, takes up very little space in storage, and can be re-rendered at various resolutions any time you need. They’re great! I hate writing them. Mermaid has a different syntax for every diagram type, and they’re hard to remember. PlantUML is more consistent, though not totally, and in my experience can be quite verbose.
Ten years of joeblu.com
I’ve had this domain, this site for 10 years. Running on Hugo the whole time. There are only a few things here, but it’s no big deal. There are very few things I have on the internet that have been live that whole time and are still a going concern:
- this site
- gmail
Only one of those gives me real control of what I put out here, with no rules but my own and the law. It’s a blessing to still be able to do that in 2025 - give anyone the power to publish anything.
What was WTF with Marc Maron?
I first met Marc Maron in 2010 at a comedy festival in Southern California. WTF was less than a year old, and most of the guests thus far were “alternative comedians”. All podcasts back then were either tech-focused or comedy-focused, particularly LA alternative comedy. I found the tech ones interminably boring, but alternative comedy was really important to me and I was hooked on WTF.
I was in the back of a van with Maron and Maria Bamford (in hindsight, insane situation) as we drove around Lake Arrowhead for half an hour. Marc bored into me for at least half the time, asking me about what made me move to California, my ethnic background and family history in the US, opinions on late night shows. It was more intense than any first date conversation, and I was flattered by the attention. Still, I doubt it’s an encounter he’d remember. He’d been doing his radio show for years, meeting hundreds of new people a year between that and standup sets. I think he’s just that way - curious about every person and what drives them.
hugo-editor: A Claude experiment
I write and publish this blog with Hugo, a static site builder that uses YAML for its posts. It’s also what we use to build the Grafana docs site, so I use it often. For the past few years I’ve been using vim to write posts. The final site content is copied onto a server after it’s built.
I have an SSH client on my phone, so I can theoretically write posts from anywhere. However, using a text editor over SSH on a phone leaves a lot to be desired. There are also iOS git clients like Working Copy, but they can’t run a script to verify my builds. Before publishing, I need a separate step, and it’s not part of my writing workflow.
Why would you use .gitkeep?
I’ve been using Git for 9 years now, and today was the first time I knowingly encountered a file named .gitkeep in a diff. “What’s the point of this empty file?”, I thought. Quickly realizing that the idea is to track an empty directory, I started to wonder “Why would you want to make sure a directory exists when there’s nothing to put there?” and I started seeing blog posts about preparing for future changes that will add files to the directory or making sure your team has a consistent directory structure.
Think big, build small
I’ve been at a few software organizations navigating the transition from small company to established businesses with big customers. At that point, duplication starts to become a cost, and consistency and stability in the product becomes more important than earlier in the business cycle. This is when everything starts getting “platformized” and standardized: application platforms, app development frameworks, managed job queues, data pipelines. These all have the chance to be transformative for your company from a dev experience and cost control perspective. They also routinely get mired in endless migration timelines, and never being “ready enough” for big systems to transition to the platforms.
Our Furtive Encrypted Future
By 2030, real encryption may be illegal in the European Union. Heck, Spain wants to ban end-to-end encryption entirely It’s already under attack in the UK. Be sure that the USA and China will be nipping at their heels.
Because mathematics are mathematics, there’s not actual safe way to provide lawful government access to encrypted communications. If the government has a key, at some point the key will leak. The shared keys for DVD CSS and AACS leaked. Any shared keys for decrypting content eventually leak, and there’s no sound way to update content to disable those private keys.
American schools should all have uniforms
I love fashion as a means of self-expression. Getting creative with pieces found in thrift stores and flea markets was a big part of my 20s. I’ve been thinking a lot recently about fashion in a school context and its effects on children.
My daughters are in their early years of school. Even in preschool here in Singapore, kids wear a school uniform. It’s usually simple - a polo shirt and shorts, with embroidered school logos. Everybody buys them from the same uniform supplier, and you buy a PE uniform too. State schools, international schools, religious schools. They all have uniforms. My daughters have very different tastes in their own wardrobes, but at school they’re essentially equal.
Loog Piano: My review
I bought two of the original Loog guitars, little 3-string acoustic guitars intended for new learners and especially children. There’s a lot to like about them: they’re inexpensive, cute, and have surprisingly good sound and volume. The larger one gives a tenor guitar sort of sound that’s pleasant, and the smaller one is ukulele-ish. The kids are getting old enough to be into them, and I love having them around.
What’s a “thunk”?
I remember when everyone started talking about using “thunks” in Redux to execute code without blocking the UI. And I remember getting tripped up on the word “thunk”. What’s a “thunk”? Why are we calling it that?
The term “thunk” goes all the way back to ALGOL 60! It’s a play on “think”, because the ALGOL compiler needed to “think” about what sort of subroutines to generate. ALGOL allows passing expressions as arguments to subroutines, not just constants. One way of allowing this is to substitute the expression for another subroutine that evaluates the expression when the original subroutine call happens. This new subroutine is the “thunk” - the result of the “thinking”.
jq -n --argjson
jq, a tool for manipulating JSON data, is one of the Don’t use mocks
Writing good unit tests is made much easier by dependency injection. This lets you separate your code’s behavior from that of your dependencies.
Many people use mocks to add dependencies to unit tests. I think this is usually a mistake.
Supreme Court DoS attack
Looking in Go’s Mirror: How and When to use reflect
This article was originally published on gopheradvent.com
reflect can be intimidating to new Go programmers because it’s very generic and you lose access to many niceties in the language. But it doesn’t have to be. Let’s build some programs that use reflect as a way to demystify the package and illustrate the power and pitfalls that come with using it.
What is software for?
In the last blog, I wrote a few things that software is for:
- putting people on the moon
- safely deploying airbags
- making my bank account add up
…
Code is not Prose
Once a month or so, this idea comes rambling out of the programming community1:
Software is prose. It is written to communicate ideas to others, it has the interesting side effect that it can be transformed into something a computer can execute.
- Chet Hendrickson
This sounds nice on paper. It makes for a good conference talk about how to structure software, how to design programming languages, and how to collaborate. I agree with what I think is the intent: write software so that other people can understand it and change it as they need to.
Nasty refactorings with go.mod replace
At work I’ve been building a new program on top of an SDK that’s under very active development. After about 6 weeks without updating the version, the SDK had deleted some code I was using and had a ton of breaking changes. If I’d simply updated the library, my entire program would fail to build, and it also wouldn’t be clear how to get it back to a good state. Following in the spirit of Branch by Abstraction, I’d rather introduce the new code side-by-side with the old and incrementally migrate without breaking the program.
Caroline Ellison is not a sympathetic figure
I recently read this Washington Post Article (archive.org) titled Caroline Ellison wanted to make a difference. Now she’s facing prison. After the first read-through I was incredulous at the sympathetic presentation in the biography. It reads like a resume, like a “it all spun out of control!” story about someone who got in over her head. I tweeted:
Lol how do you get such a sympathetic bio after stealing billions of dollars @GerritD
Unmarshaling JSON in Go: The weird parts
Evaluating New Tools
I was reading about Phoenix today, looking at guides and documentation. It’s great to see in a guide when it’s easy to quickly set up a project, that makes it fun to get started and explore. The most exciting thing about Phoenix is that “reactivity”, or live updates, are a core part of the system, not an add-on. Nowadays I find any software without reactive updates frustrating and annoying to use.
Podcasts At the End of the Indie Web
There’s been a lot of restrospecting lately, lamenting the loss of the “indie web” and its subsumption by content platforms like Facebook, Instagram, Reddit and Twitter. (I’ve always wondered where Tumblr fit in - more indie than any of these, but still - owned by Yahoo!). A few casualties that fell by the wayside: blogs, web comics, and independent, topic specific forums.
All of these media still exist, much diminished and publishing social posts to route you to their sites, but they are still self-hosted, free of editorial control and in their author’s hands. To some degree, these forms will probably stay on the web until millenials die out.
GitHub Squash Merges are a Menace
I love squash merging. I think it’s the simplest way to maintain a legible commit history on main, a shared dev branch, etc. It’s easy for most people to follow, and it doesn’t require you to be too Big Brained about git. GitHub even provides a convenient interface for doing this, right in the pull request UI!
But GitHub’s squash merge workflow undermines the biggest benefits of squash merges: clear, simple, atomic commit messages that explain what each commit does.
How We Do Our Best Work
Dan Luu tweeted about some great work interns that he has mentored accomplished at Twitter:
One intern did https://t.co/nsFW20j9Hm and another did interesting data analysis then built a working prototype for across the fleet profiling that others were able to use to find real inefficiencies.
— Dan Luu (@danluu) August 31, 2022
Those are things that could go into a staff promo packet as a major project.
Thoughts on OKRs
OKRs are one of those business ideas that are just simple enough to be dangerous. You think you understand it in a day, and you can see where your company is falling short: lacking focus and underdelivering. You see how clear, measurable goals could improve the situation.
Here’s the one sentence version: You set objectives, and for each objective come up with several key results that you can measure to see if you met the objectives. There’s a whole book for implementing this process in large organizations, and a mystique because of its association with Google’s early and frightening effectiveness.1
You Should Squash Merge to main
Every so often I’ll see a meme on Twitter like:

and it makes me so mad. For good reason! OSS project repositories that support merge commits to main are usually littered with useless comments like: “Merge change from $USER, $PR”. It makes the commit history on main utterly useless and you get to check the various feature branches in a never ending snake of commits to find out what the hell changed.
Why I (Still) Use Vim
Every so often I wonder if I’m making trouble for myself by doing all of my typing in vim. Writing for this blog, writing engineering plans and design documents, and writing code. There are tools that are made especially for doing these jobs, and vim certainly doesn’t have any facility for making diagrams.
All vim can really do is edit a bunch of bytes, trying to represent them as formatted text. It doesn’t even really understand code, which is what most people use it for.
My Country, Tis of Thee
I’ve spent a lot of time the last 3 years watching Umberto Eco’s sign’s of Ur-Facism manifest, and manifest, and manifest. I’ve seen a lot of things that I was raised to believe wouldn’t couldn’t happen here happen in sequence, with frightening speed. Out-of-control (willfully so) police beating and gassing people in the street, night after night after night. Destruction of public schools, along with requiring states fund religious schools. A Justice Department hell-bent on revenge for the President. Open xenophobia, brazen racism by members of congress. I thought we left that behind when Strom Thurmond finally died.
Font Measurements
TLDR;
I learned a bunch about rendering fonts and I thought it would be interesting to read about them from a programmer’s perspective. I gained a ton of empathy for type design and type-setting developers, as they work with a dizzying variety of screen resolutions, font styles, and a wide variety of device speeds to produce type that looks as good as it possibly can under harsh conditions.
Background
I’ve been working on a project involving a two-color e-ink screen. I’m drawing on the screen and that involves drawing text. The project is written in Go. There are common font-rendering librares like Cairo, which are written in C. I find compiling against C libraries like using cgo difficult and complex, so I was really interested in a Go-only solution.
Influence
I got an email from an old co-worker the other day:
I was thinking about you and how you are a person I see as not being particularly embroiled in office politics, but also as having a lot of influence and knowing how and where to leverage it. I was curious if you had any words of advice for how you got to that place.
Of course I was happy to hear that I come off this way, and as I thought about how to reply, I found myself writing an essay.
Lucky
We went through layoffs at work recently. Like a lot of companies, the belt is tightening, and the bathtub drain is getting blugged. I’m lucky to have not been laid off. Lucky again - this is the third “surprise” layoff where I’ve kept my job. I’m batting 1.000 but I know my number has to come up sometime.
I graduated from college in 2009, 9 months into the Great Financial Crisis. I was lucky to get into a good graduate school on a stipend that paid my rent, and even luckier to be leaving undergraduate without student debt. I was lucky that when I needed to quit graduate school I could find a government job.
Fast is a Feature
We all use dozens of pieces of software a day - email clients, web browser, email clients inside web browsers. Cameras and chat, digital art tools and spreadsheets. We switch between them dozens of times, and when we really get into a task, when can sometimes achieve a state of flow, a state of satisfying and effective effort that lets us accomplish more than we thought and enjoy it all the way.
Garage Shelves
I started taking paternity leave on my first daughter’s due date. (Un?)fortunately, she was born late, and I found myself with both a lot of free time, and a lot of pent-up anticipatory energy.
My workshop was a bit of a mess, since I’d acquired more tools - including a heavy miter saw and grinder. My mother-in-law was staying with us and helping with chores, so I decided to focus on cleaning up the shop. I built a sturdy set of shelves from scrap lumber and cheap sheathing plywood to hold my bench tools when they’re not in use.
Guitar Shelf
I have a lot of guitars and ukuleles, and I was also feeling like I hadn’t played them enough. When we moved at one point, I sold all my guitars but one, but that honeslty didn’t last too long. Now that I own a home, it was high time to build myself a real place to keep them. Keeping instruments close at hand reduces my barriers to practice and play.
Workbench
Every workshop needs a good work bench. A good bench is stable and flat, letting you estimate the flatness of your workpiece, and with plenty of space to hold the work and clamp it down.
You can buy nice workbenches for many hundreds of dollars, and then you can buy nice clamps for many more. I wanted to use this project as a learning experience, though. So I spent my time researching table plans, trying to pick one that would give me a good surface without being a big expense.
Cardsharp
I’m a big fan of Zach Gage’s games. He recently released a game called “Sage Solitaire” in which solitaire is played with poker hands. You can make a Full House, Straight, Straight Flush, etc, to clear cards from the board. To choose what hands to make, it’s pretty important to know what cards remain in the deck, much as it can be in poker.
I wrote Cardsharp to help me keep track of remaining cards in a Sage Solitaire deck. It’s helped improve my score quite a bit, and gave me some recent Python experience before I started looking again for backend engineering jobs.