Julia Evans

Hey! I'm Julia. Welcome to my blog. Here's every post I've ever written, organized by category. Enjoy! You can subscribe to a weekly digest of these blog posts.

I publish computer zines at Wizard Zines.

Most recent 10 posts

Entering text in the terminal is complicated
Reasons to use your shell's job control
New zine: How Git Works!
Notes on git's error messages
Making crochet cacti
Some Git poll results
The "current branch" in git
How HEAD works in git
Popular git config options
Dealing with diverged git branches

and all posts by category: (or see popular posts)


Entering text in the terminal is complicated
Reasons to use your shell's job control

Cool computer tools / features / ideas

What helps people get comfortable on the command line?
Lima: a nice way to run Linux VMs on Mac
Writing Javascript without a build system
Monitoring tiny web services
Notes on running containers with bubblewrap
sqlite-utils: a nice way to import data into SQLite for analysis
A list of new(ish) command line tools
Things that used to be hard and are now easy
Hosting my static sites with nginx
Some notes on using esbuild
Firecracker: start a VM in less than a second
Server-sent events: a simple way to stream events from a server
Docker Compose: a nice way to set up a dev environment
ninja: a simple way to do builds
Implementing 'focus and reply' for Fastmail with JMAP
scanimage: scan from the command line!
entr: rerun your build when files change
A little bit of plain Javascript can do a lot
PaperWM: tiled window management for GNOME
SQLite is really easy to compile
Why are monoidal categories interesting?
Tailwind: style your site without writing any CSS!
An awesome new Python profiler: py-spy!
Batch editing files with ed
Glitch: write fun small web projects instantly
Binder: an awesome tool for hosting Jupyter notebooks
Cool vim feature: sessions!
Data structure: the treap!
a tiny whack-a-mole game
Log-structured storage
Using the Strict-Transport-Security header
The fish shell is awesome
homu + highfive: awesome bots that make open source projects easier
you can take the derivative of a regular expression?!
tcpdump is amazing
How to measure your CPU time: clock_gettime!
Fast integer sets with Roaring Bitmaps (and, making friends with your modern CPU)
Sendfile (a system call for web developers to know about!)
PAPERS ARE AMAZING: Profiling threaded programs with Coz
LD_PRELOAD is super fun. And easy!

Things i built

Mounting git commits as folders with NFS
Open sourcing the nginx playground
New playground: memory spy
Introducing "Implement DNS in a Weekend"
New playground: integer.exposed
A list of programming playgrounds
Some tiny personal programs I've written
New tool: Mess with DNS!
New tool: an nginx playground
Notes on building debugging puzzles
A tool to spy on your DNS queries: dnspeep
A little tool to make DNS queries


Notes on git's error messages
Some Git poll results
The "current branch" in git
How HEAD works in git
Popular git config options
Dealing with diverged git branches
Inside .git
Do we think of git commits as diffs, snapshots, and/or histories?
git branches: intuition & reality
How git cherry-pick and revert use 3-way merge
git rebase: what can go wrong?
Confusing git terminology
Some miscellaneous git facts
In a git repository, where do your files live?


Some notes on NixOS
Some notes on nix flakes
How do Nix builds work?
Some notes on using nix


Why is DNS still hard to learn?
Making a DNS query in Ruby from scratch
Why do domain names sometimes end with a dot?
The multiple meanings of "nameserver" and "DNS resolver"
A toy DNS resolver
Some ways DNS can break
Why might you run your own DNS server?
DNS "propagation" is actually caches expiring
What happens when you update your DNS?

Computer networking

How to send raw network packets in Python with tun/tap
A toy remote login server
Reasons for servers to support IPv6
How to put an HTML page on the internet
Networking tool comics!
An example of how C++ destructors are useful in Envoy
Some Envoy basics
Editing my blog's HTTP headers with Cloudflare workers
IP addresses & routing
netdev day 2: moving away from "as fast as possible" in networking code
netdev day 1: IPsec!
How I use Wireshark
A few things I've learned about computer networking
Finding out if/why a server is dropping packets
What's a network interface?
Iptables basics
netdev conference, day 3
netdev conference, day 2
How to filter packets super fast: XDP & eBPF!
netdev conference, day 1
Slow down your internet with tc
How big can a packet get?
Dissecting an SSL certificate
What's interesting about UDP?
Why do UDP packets get dropped?
How do HTTP requests get sent to the right place?
Why do we use the Linux kernel's TCP stack?
What are SSL ciphers & session keys?
CDNs aren't just for caching

How a computer thing works

Notes on using a single-person Mastodon server
Behind "Hello World" on Linux
What happens when you press a key in your terminal?
Implementing a toy version of TLS 1.3
How to use undocumented web APIs
Some things about getaddrinfo that surprised me
How to find a domain's authoritative nameservers
How to use dig
How do you tell if a problem is caused by DNS?
Tools to explore BGP
Quadratic algorithms are slow (and hashmaps are fast)
How to look at the stack with gdb
The OSI model doesn't map well to TCP/IP
Why strace doesn't work in Docker
Getting started with shaders: signed distance functions!
"server" is hard to define
How tracking pixels work
How containers work: overlayfs
SQL queries don't start with SELECT
How does gdb call functions?
How do groups work on Linux?
Async IO on Linux: select, poll, and epoll
Weird unix thing: 'cd //'
What happens when you start a process on Linux?
How does gdb work?
Should you be scared of Unix signals?
I conquered thread pools! For today, at least.
Thread pools! How do I use them?
What is "the stack"?
Why Ruby’s Timeout is dangerous (and Thread.raise is terrifying)
Why you should understand (a little) about TCP
How the locate command works (and let's write a faster version in one minute!)
How gzip uses Huffman coding
Diving into concurrency: trying out mutexes and atomics
How does SQLite work? Part 2: btrees! (or: disk seeks are slow don't do them!)
How does SQLite work? Part 1: pages!
How is a binary executable organized? Let's explore it!
What happens if you write a TCP stack in Python?
Diving into HDFS
Three steps to learning GDB

Binary representations of things

Some possible reasons for 8-bit bytes
Why does 0.1 + 0.2 = 0.30000000000000004?
Examples of problems with integers
Examples of floating point problems

Kubernetes / containers

Operating a Kubernetes network
Reasons Kubernetes is cool
How Kubernetes certificate authorities work
Cherry picking commits & shell scripting in golang
How does the Kubernetes scheduler work?
A few things I've learned about Kubernetes
Swapping, memory limits, and cgroups
A container networking overview
What happens when you run a rkt container?
Running containers without Docker
What even is a container: namespaces and cgroups
A list of Linux container software
"I just want to run a container!"
Some questions about Docker and rkt
Docker is amazing

Zines / comics

New zine: How Git Works!
New zine: How Integers and Floats Work
Print copies of The Pocket Guide to Debugging have arrived
New zine: The Pocket Guide to Debugging
Pages that didn't make it into "How DNS Works"
New zine: How DNS Works!
All my zines are now available in print!
You can now buy print version of my zines!
I put all of my comics online!
New zine: Hell Yes! CSS!
Wizard Zines' first print run: Help! I have a Manager!
Some more CSS comics
Some CSS comics
New zine: How Containers Work!
New zine: Become a SELECT Star!
Your Linux Toolbox: a box set of my free zines
New zine: HTTP: Learn your browser's language!
New zine: Bite Size Networking!
New zine: Oh shit, git!
New zine: Help! I have a manager!
New zine: Bite Size Command Line!
New zine: Profiling & tracing with perf!!
New zine: So you want to be a wizard
Linux comics: a small zine
Linux tracing zine
"Let's learn tcpdump" zine: now available for everyone
New zine: let's learn tcpdump!
New zine: "Networking! ACK!"
A tiny zine about machine learning
More drawings about computers
A few drawings about Linux
New zine: Linux debugging tools you'll love
A few sketches
A zine about strace


Questions to help people decide what to learn
Challenge: find Twitter memes with suffix arrays
Solutions to the tiny window manager challenge
Challenge: Write a bouncy window manager
What makes a programming exercise good?
Notes on building SQL exercises
git exercises: navigate a repository
curl exercises

On writing words

Some tactics for writing in public
Some blogging myths
Teaching by filling in knowledge gaps
Patterns in confusing explanations
Write good examples by starting with real code

On writing comics / zines

Building a custom site for zine feedback
How I write useful programming comics
A new way I'm getting feedback on my zines: beta readers!
Some possible future zines
An attempt to make a font look more handwritten
Some notes on vector drawing apps
Some research on shipping print zines
Zine revenue for 2019
Taking a year to explain computer things
How to write zines with simple tools
How do you document a tech project with comics?
When does teaching with comics work well?
Why sell zines?
How to teach technical concepts with cartoons
Handwritten books
An idea for a programming book
Why cute drawings?
How (and why) I made a zine


!!Con 2019: submit a talk!
Systems We Love 2016
PolyConf 2016
Women in Machine Learning 2015 (fun!!!)
AdaCamp Montreal 2015
Data Day Texas 2015
PyData NYC (I gave a machine learning talk! yay!)
Strange Loop 2014
!!Con talks are up
♥ PyCon
CUSEC = fun
PyData Boston 2013
Open Data Exchange 2013
Montreal All-Girl Hack Night #2: now with cookies
Montreal All-Girl Hack Night #1: AMAZING

Organizing conferences

Ideas for making better conference talks & conferences
You can choose who submits talks to your conference
Should my conference do anonymous review?
Anonymous talk review is amazing.

Businesses / marketing

A few things I've learned about email marketing
saturday comics: a weekly mailing list of programming comics
A few early marketing thoughts
Who pays to educate developers?
I started a corporation!

Statistics / machine learning / data analysis

An attempt at implementing char-rnn with PyTorch
Some nonparametric statistics math
Some good "Statistics for programmers" resources
How do these "neural network style transfer" tools work?
A few reasons to be skeptical of machine learning
Looking inside machine learning black boxes
Winning the bias-variance tradeoff
How to trick a neural network into thinking a panda is a vulture
Is machine learning safe to use?
Some easy statistics: Bootstrap confidence intervals
A/A testing
Fun with machine learning: logistic regression!
Fun with machine learning: does your model actually work?
Fun with stats: How big of a sample size do I need?
Machine learning isn't Kaggle competitions
A pandas cookbook
Graphing bike path data with IPython Notebook and pandas

Year in review

2023: Year in review
Some business graphs for 2022
2021: Year in review
2020: Year in review
2019: Year in review
2018: Year in review
2017: Year in review
2016: Year in review
2015: Year in review


New talk: Making Hard Things Easy
New talk: Learning DNS in 10 years
New talk: High Reliability Infrastructure Migrations
Build impossible programs
So you want to be a wizard

Infrastructure / operations engineering

Some notes on running new software in production
What can developers learn from being on call?
Bash scripting quirks & safety tips
Ideas about how to use AWS
Service discovery at Stripe
Consistency vs availability (wat?)
What's devops?
Operations for software developers for beginners
How do you do capacity planning?
Why I love log files
TIL: clock skew exists
Fear makes you a worse programmer

Career / work

Get better at programming by learning how things work
Things your manager might not know
When your coworker does great work, tell their manager
Tell candidates what to expect from your job interviews
Questions you can ask about compensation
Get your work recognized: write a brag document
What's a senior engineer's job?
Some possible career goals
Open source sabbatical = awesome
Writing performance reviews with positive constructive feedback
Taking a sabbatical to work on Ruby profiling tools
Telling people what you're working on
Writing down my career
Hiring & opportunity
Choosing the "best software"
Getting things done
How I got a CS degree without learning what a system call is
Release it, then build it
How do you decide what to work on?
Three ways to solve hard programming problems
Talking about stock options = awesome
Things you should know about stock options before negotiating an offer
1:1 topic ideas
How I learned to program in 10 years
Stopping to think
Becoming a better developer (it's not just writing more programs)
Sounding confident in interviews
What my technical interviews have looked like
Questions I'm asking in interviews

Working with others / communication

Making small culture changes
How do you make an awesome team?
Learning to like design documents
Senior engineering & fantasy heroes
On reading the source code, not the docs
Pair programming is amazing! Except... when it's not.
Pair programming

Remote work

Working remotely, 4 years in
Surviving meetings while remote
Working remote, 8 months in (seeing humans is important!)
Working remote, 3 months in
Reports from remote-land: remote pairing works great!

Talks transcripts / podcasts

A few recent podcasts
Talk: Building a Ruby profiler
How does the internet work? podcast
A swiss army knife of debugging tools: talk & transcript
Notes from my PyData Berlin keynote
A few notes on my CUSEC talk
Ruby Rogues podcast: systems programming tricks!

On blogging / speaking

Blog about what you've struggled with
Metaphors in man pages
Organizing this blog into categories
Talks I'd love to see at RustConf
Measuring a blog's success: focus on conversations, not page views
How I set up an automatic weekly blog digest
Blogging principles I use
Switching to Hugo
"advice" for aspiring tech bloggers
Reproducing awesomeness
How to set up a blog in 5 minutes
Open sourced talks!
You should give talks. They will be awesome. Here's why!
Trying out Octopress

On learning

Celebrate tiny learning milestones
How to get useful answers to your questions
How to teach yourself hard things
How to answer questions in a helpful way
Learning at work
Rules of programming experiments
How to ask good questions
Asking good questions is hard (but worth it)
How does knowledge get locked up in people's heads?
Asking questions is a superpower
"Ask if you have questions" isn't enough


A couple of Rust error messages
Rust in 2018: it's way easier to use!
My first Rust macro
Debugging a segfault in my Rust program
Bindgen: awesome Rust tool for generating C bindings
What's a reference in Rust?
Learning systems programming with Rust
A second try at using Rust
Calling C from Rust
Why I ❤ Rust
My Rust OS will never be finished (and it's a success!)
Writing an OS in Rust in tiny steps (Steps 1-5)
Some things my kernel can't do

Linux debugging / tracing tools

What problems do people solve with strace?
A perf cheat sheet
Linux tracing systems & how they fit together
Notes on BPF & eBPF
3 short screencasts (/proc, tcpdump, strace)
ftrace: trace your kernel functions!
Linux debugging tools I love
Using ltrace to debug a memory leak
A useful new strace feature
A workshop on strace & tcpdump
How does perf work? (in which we read the Linux kernel source)
perf top: an awesome way to spy on CPU usage
A few spy tools for your operating system (other than strace!)
Seeing system calls with perf instead of strace
Spying on Hadoop with strace
I can spy on my CPU cycles with perf!
Debug your programs like they're closed source!
Debugging shared library problems with strace
More practical uses for strace!
Using strace to avoid reading Ruby code
Spying on ssh with strace
Understanding how killall works using strace


A debugging manifesto
Tips for analyzing logs
Some ways to get better at debugging
Debugging by starting a REPL at a breakpoint is fun
Reasons why bugs might feel "impossible"
When debugging, your attitude matters
What does debugging a program look like?
How I got better at debugging
Coding strategies

Debugging stories

Debugging a weird 'file not found' error
Reverse engineering the Notability file format
Debugging netlink requests
A small website mystery
Investigating Erlang by reading its system calls
Surprises in Ruby HTTP libraries
Nancy Drew and the Case of the Slow Program

Fan posts about awesome work by other people

Awesome NLP tutorials by Allison Parrish
Like zines about computers? You might love Bubblesort Zines
A magical machine learning art tool
"A Critique of the CAP Theorem"
Some of my favorite blogs
A few blogs I really like
Julia Serano's 'Excluded'
Transit maps: 1941 vs 2011


No feigning surprise
A litmus test for job descriptions
Women-only spaces are a hack
An argument for hiring junior developers
Programming doesn't belong to men (it belongs to me)
What women in technology really think (150 of them, at least)
When is "guys" gender neutral? I did a survey!

Not about computers

Making crochet cacti


Documentation site for rbspy!
Prototyping an ltrace clone using eBPF
Profiler week 6/7: more experiments, and a `report` subcommand!
Profiler week 5: Mac support, experiments profiling memory allocations
Writing eBPF tracing tools in Rust
Spying on a Ruby process's memory allocations with eBPF
Profiler week 4: callgrind support, containers, Mac progress!
I think I found a Mac kernel bug?
How do you spy on a program running in a container?
How do you read the memory maps of a Mac process?
Profiler week 3: refactoring, better testing, and an alpha release!
Profiler week 2: support for 1.9.3 -> 2.5.0, and line numbers!
Should I pause a Ruby process to collect its stack?
Profiler adventures: resolving symbol addresses is hard!
Profiler week 1: testing & profiling stripped binaries
How are Ruby's headers different from Python's headers?
How often do Ruby's stack struct definitions change?
How do Ruby & Python profilers work?
How to spy on a Ruby program


Profiling Go programs with pprof
How much memory is my process using?
Benchmarking correctly is hard (and techniques for doing it better)
The Etsy site performance report is amazing
Some links on Java garbage collection
Java garbage collection can be really slow
I/O matters.
Have high expectations for your computers
How CPU load averages work (and using them to triage webserver performance!)
Java isn't slow
A millisecond isn't fast (and how we made it 100x faster)
Computers are *fast*!

Open source

Figuring out how to contribute to open source
A few questions about open source
Learning at open source sprints (no preparation required)
Don't feel guilty about not contributing to open source

Linux systems stuff

How to get a core dump for a segfault on Linux
Things to learn about Linux
Guessing Linux kernel registers
You can be a kernel hacker!
Recovering files using /proc (and spying, too!)
4 paths to being a kernel hacker

Recurse center 2020

Day 57: Trying to set up GitHub Actions
Day 56: A little WebAssembly
Day 53: a little nginx, IPv6, and wireguard
Day 52: testing how many Firecracker VMs I can run
Day 51: Fixed my logging and made a couple of puzzles
Day 50: Building some tarballs for puzzles, and trying to make a kernel boot faster
Day 49: making the VMs boot faster
Day 48: Another Go program, and a little vim configuration
Day 47: Using device mapper to manage Firecracker images
Day 46: debugging an iptables problem
Day 44: Building my VMs with Docker
Day 43: Building VM images
Day 42: Writing a Go program to manage Firecracker VMs
Day 41: Trying to understand what a bridge is
Day 40: screen flickering & a talk about containers
Day 39: Customizing gotty's terminal
Day 38: Modifying gotty to serve many different terminal applications at once
Day 37: A new laptop and a little Vue
Day 35: Launching my VMs more reliably
Daily blog posts about my time at RC
Day 34: Learning about qemu
Day 33: pairing is magic and beautiful git diffs
Day 32: A Rails model that doesn't use the database with ActiveHash
Day 24: a short talk about blogging myths, and a debugging tip
Day 23: a little Rails testing
Day 22: getting OAuth to work in Rails
Day 21: wrangling systemd & setting up git deploys to a VM
Day 19: Clustering faces (poorly) using an autoencoder
Day 20: trying to figure out how Google Cloud IAM works
Day 18: an answer to an autoencoder question
Day 17: trying to wrap my head around autoencoders
Day 13: BPTT, and debugging why a model isn't training is hard
Day 11: learning about learning rates
Day 10: Training an RNN to count to three
Day 9: Generating a lot of nonsense with an RNN
Day 8: Start with something that works
Day 5: drawing lots of faces with sketch-rnn
How do you write simple explanations without sounding condescending?
Day 3: an infinitely tall fridge
Day 2: Rails associations & dragging divs around
Day 1: a confusing Rails error message
I'm doing another Recurse Center batch!

Recurse center 2013

How I spent my time at the Recurse Center
How I did Hacker School: ignoring things I understand and doing the impossible
Hacker School's Secret Strategy for Being Super Productive (or: Help.)
"How was Hacker School?"
Day 46: Never Graduate
Day 45: I now have Rust code for executing executables!
Day 44: qemu + gdb = so great
Day 42: How to run a simple ELF executable, from scratch (I don't know)
Day 41: Linkers are upsetting
Day 39: Writing malloc wrong, for fun
Day 40: 12 things I learned today about linkers.
Day 40: Linkers are amazing.
Day 38: After 6 days, I have problems that I can't understand at all
Day 37: After 5 days, my OS doesn't crash when I press a key
Day 36: On programming without malloc
Day 35: Types in Rust, for beginners
How to call Rust from assembly, and vice versa
Videos from PyData NYC are up!
What happens when you run 'Hello, world'
Writing a kernel using rustboot & rust-core
Day 34b: Writing curl using my TCP stack
Day 34: The tiniest operating system
Day 33: How to make music with ClojureScript
Day 32: Magical Orchestra!!!
Day 31: Binary trees with core.logic!
Day 30: Making music in Clojure with Overtone. Clojure bugs with laziness! Fun!
Day 29: Trying out Emacs!
Day 28: Made a git workflow visualization webapp!
Day 27: Automatically testing changes in state! Visualizing my Git workflow! Floats!
Day 25: ACK all the things
Day 26: Trying to describe the TCP state machine in a readable way. Failing.
Women in Technology workshop at PyData NYC
Day 24: Unit testing this TCP library
Day 22: Got some TCP packets back!
Day 23: Started writing a TCP stack in Python
NYC Python talk
Day 21: Trying to TCP
Day 19: A few reasons why networking is hard
Day 20: Traceroute in 15 lines of code using Scapy
Day 18: ARP cache poisoning (or: In ur connection, sniffing ur packets)
Day 17: How to write a buffer overflow exploit
Day 16: gzip + poetry = awesome
Do Rails programmers use node.js? Visualizing correlations in command usage
Day 15: How a .gz file is structured, redux
Day 14: When it's hard to write tests, that's when I should be testing
Day 13: Off by one errors
Day 12: Why Julia likes Julia
Day 10: Goals. Goals? Maybe I need to be *reading* more code?
Day 11: How does gzip work?
Day 9: Bytecode is made of bytes! CPython isn't scary!
Day 8: Julia writes Julia! And remembers that open source is hard.
Day 7: An echo server in Clojure
Day 6: I wrote a rootkit!
Day 5: I wrote a kernel module!!!
Where to find bike sharing systems' data feeds
Day 4: Processes vs threads, and kernel modules!
Day 3: What does the Linux kernel even do?
Day 2: netcat fun!
Day 1: What does a shell even do?
Hacker School Day 1: Messing around with the stack in C
Hacker School Day -4: unit testing in C. checkmk!