A Decade of TILs
I started my TIL repo ↗ (essentially a microblog) 10 years ago to the day. February 6th, 2015 ↗.
Has it really been 10 years?
In that time I've written almost 1600 tiny Today I Learned posts across a bunch of programming topics. It's tempting to focus on the numbers (and I'll get to those later in the post), but first I want to be a bit reflective.
Here are some of the insights I've had looking back.
Routine
I'm a very routine-oriented person, so having this habit of writing TILs has been very anchoring for me. Like any software career I've experienced the ebbs and flows of energy and excitement around both paid work and side-projects. Even when a work project was in a bit of a doldrum or there were challenging team dynamics, I was always able put on a learning mindset. At the end of my day I could look through my notes, see some of the interesting things that had caught my eye, dig in a bit further, and then write a TIL.
When I first started writing TILs, I was working at a small Ruby on Rails consultancy. I was surrounded by the smartest and kindest software devs I've ever had the privilege to work with. It was intimidating. I was learning a ton every day to the point of overwhelm and yet also felt constantly like I didn't know enough. Writing TILs was as much a way to convince myself that I was steadily improving as anything else.
Constraints
Constraints were always a big part of what made this manageable and successful. Every TIL needed to be tightly focused. My aim was to be able to write something up in 5 to 10 minutes. Part of how I did that was by constraining the medium. Titles needed to be 50 characters or less. The content of the TIL needed to be 200 words or less. Each TIL needed to fit under a category, though sometimes they felt like they could have been between one or another.
These constraints meant that the perceived effort of writing a TIL at the end of a long day was low. I knew I could knock it out quickly and so I did, over and over. 1600 times. Speed matters ↗.
Process
Find a good process not a perfect process. I think I have a pretty good process
when it comes to writing these TILs. I scribble notes throughout the day in a
physical notebook (or sometimes a notes.md
file), things that caught my
attention while pairing, reading some code, taking a twitter scroll break, etc.
When I have a little time, I dig in a bit further (how exactly does that flag
work, what does the man page say, etc.). I think of a concise title. Then I
write it up in Vim. I manually add the entry categorically and alphabetically
to the README.md
. Make a commit, push, and boom, it's published.
Countless people over the years have made suggestions of how I could streamline the process, add a python script or github action to automate adding the README entry, automate the commit messages, turn the whole thing into a github pages blog, etc. These weren't bad suggestions, but they were unnecessary. I already had a good process, one that was working fantastically for me. I didn't need a perfect process when I had one that was more than getting the job done.
Impact
It's incredible to see the impact that this microblog repo has had. I only ever intended it as a way to document my learning journey. However, it has caught fire a couple times on the orange site. It has 13k stars on GitHub. People have come up to me at meetups to talk about the repo. I occasionally get emails from people about how it encouraged them to start their own TIL repo. Despite all the content being buried in a github repo, I sometimes see one of these posts show up in google search results. I even apparently inspired Simon Willison to start writing TILs ↗. Simon is a prolific blogger and creator, so it feels kinda surreal to have been in any way a source of inspiration for him.
While discussing this post with Jake Worth ↗ he reminded me that early in my time at Hashrocket when my TIL repo was still new, I proposed that he build a TIL platform for the company as an apprenticeship project. He built the platform and started writing TILs regularly, as did much of the rest of the team. Here is a reflection Jake shared with me:
"TILs helped me get out of my head; up to that point I was trying to earn my spot on the Hashrocket team by doing things like reading HTTP: The Definitive Guide cover-to-cover. And I think showing that I was improving every day convinced the team I was worth investing in. And I was improving."
More than anything else though, writing TILs has been a useful practice and tool for me. It pushes me to deepen my understanding of things I'm learning, enough so that I can write about them. Writing in and of itself is a useful skill that I've inadvertently been practicing consistently through this effort.
As I wrote about in How I Built A Learning Machine ↗, I often have a question come up and instead of doing a google search, I think, "I'm pretty sure I wrote a TIL about that!" and then I quickly find it in my TIL repo instead (especially handy if I'm on an airplane without wifi). And now I have an ever-growing 10-year artifact that demonstrates my breadth and depth of knowledge, my varied interests, and my ability to communicate complex topics.
Numbers
Ok, let's take a look at some numbers.
Though I've been saying 1600 TILs, the actual number at the time of this writing is 1585. I'm getting close. That is almost 160 TILs per year. Let's see the actual counts by year though.
(2015...2025).each do |year|
start_commit = `git rev-list -1 --before="#{year}-02-07 00:00" HEAD`.strip
end_commit = `git rev-list -1 --before="#{year+1}-02-07 00:00" HEAD`.strip
# Count new markdown files between those commits
count = `git diff --diff-filter=A --name-only #{start_commit}..#{end_commit} -- "*.md" | wc -l`
puts "#{year}-#{year+1}: #{count}"
end
2015-2016: 326
2016-2017: 176
2017-2018: 105
2018-2019: 154
2019-2020: 141
2020-2021: 135
2021-2022: 147
2022-2023: 98
2023-2024: 83
2024-2025: 220
What about the top three topics/categories for each year?
(2015...2025).each do |year|
start_commit = `git rev-list -1 --before="#{year}-02-07 00:00" HEAD`.strip
end_commit = `git rev-list -1 --before="#{year+1}-02-07 00:00" HEAD`.strip
puts "\n#{year}-#{year+1}:"
# Get all added markdown files for this period
files = `git diff --diff-filter=A --name-only #{start_commit}..#{end_commit} -- "*.md"`
# Group files by their parent directory and count
dir_counts = {}
files.each_line do |file|
# Get the top-level directory
dir = File.dirname(file.strip).split('/').first
dir_counts[dir] = dir_counts.fetch(dir, 0) + 1
end
dir_counts.sort_by { |dir, counts| -counts }.take(3).each do |dir, count|
puts " #{dir}: #{count}"
end
end
2015-2016:
vim: 85
postgres: 60
ruby: 42
2016-2017:
elixir: 32
postgres: 31
vim: 25
2017-2018:
react: 14
javascript: 13
vim: 11
2018-2019:
react: 30
reason: 29
javascript: 26
2019-2020:
rails: 25
ruby: 21
elixir: 12
2020-2021:
rails: 27
unix: 12
git: 11
2021-2022:
rails: 24
ruby: 20
postgres: 18
2022-2023:
rails: 13
postgres: 11
typescript: 10
2023-2024:
unix: 20
jq: 9
rails: 8
2024-2025:
unix: 26
rails: 25
go: 20
And then how about all-time counts per topic/category?
git ls-files "*.md" | xargs dirname | sort | uniq -c | sort -nr
167 postgres
161 rails
156 vim
148 unix
148 ruby
114 git
103 javascript
57 react
52 elixir
35 tmux
31 workflow
29 reason
28 mac
26 go
24 css
21 typescript
21 clojure
19 devops
16 chrome
15 mysql
14 internet
13 jq
12 nextjs
11 vscode
9 xstate
9 sed
9 prisma
8 html
7 rspec
7 python
7 phoenix
7 heroku
6 zod
6 linux
6 github-actions
5 webpack
5 vercel
5 remix
5 mongodb
4 tailwind
4 react-testing-library
4 neovim
4 groq
3 zsh
3 pnpm
3 java
3 drizzle
3 docker
3 brew
3 ack
2 yaml
2 sqlite
2 shell
2 llm
2 kitty
2 jj
2 inngest
2 astro
1 streaming
1 react_native
1 planetscale
1 next-auth
1 netlify
1 http
1 gatsby
1 deno
1 ansible
1 amplify
Conclusion
It has been fun reflecting on this learning journey which has been going on for a large portion of my career.
Please reach out (bluesky ↗, twitter ↗, email, etc.) and let me know about your TIL repo or some other project that has been an important part of your career. A crucial element of this whole TIL thing has been learning from others — I'd be excited to learn something from you. Lastly, let me know if this has stirred any reflections for your career and learning journey.