The first thing I looked up on syscall.sh was open. Not because I needed it, but because I wanted to see whether a reference site would tell me the truth about a syscall I use reflexively and have never once typed by hand. On x86-64 it is number 2. It has been number 2 since the architecture existed. And it has been quietly superseded by openat and then openat2, which is the sort of fact you absorb without noticing, like learning that a road you drive every day was rerouted years ago.

That is the small pleasure of the site, and it is also the larger point. A table of system calls looks like plumbing. It is actually a record of decisions. Every number in that table was assigned by someone at some point, and every gap in the numbering is a syscall that was proposed and never shipped, or shipped and withdrawn. The site scans the syscall table and the SYSCALL_DEFINE macros of every mainline release it can find, across 27 architectures, from Linux 3.3 forward. It records when each entry first appeared and when it was dropped. Removed entries do not vanish; they stay visible, tagged with the release that killed them.

I have spent enough time in kernel changelogs to know that this is harder than it sounds. The syscall table is not a single file. It is per-architecture, and the numbers do not agree across architectures, and the calling convention differs, and the instruction that enters the kernel differs. The site records all of that: where the number goes, where the arguments go, what instruction crosses the boundary. That is the part most references skip. They give you the number and leave you to guess what the ABI expects.

The API is the real product, if you ask me. curl https://api.syscall.sh/v2/syscalls/x64/read returns a JSON object with the number, the six argument registers, the instruction, and where the return value lands. You can pull the whole table for an architecture as a plain JSON file. You can diff releases. You can ask what changed between 5.10 and 6.1 and get an answer that is not a paragraph of prose but a list.

What makes this more than a lookup table is the since field. A syscall whose since equals the first release the site scanned was already there, and may be much older. That caveat is honest and it matters. The data has a floor. Everything below it is inference. Most reference sites would bury that fact or pretend the floor does not exist. This one puts it in the documentation.

I keep thinking about what a table like this is for. The obvious answer is debugging: you have a strace line, you want to know what the number means on this architecture, you look it up. But the more interesting use is historical. You can watch the kernel's interface accrete. You can see which syscalls arrived together, which ones were deprecated, which architectures got features first. The numbering is not arbitrary, but it is not designed either. It is a sediment layer.

There is a temptation, with a project like this, to call it a public service and move on. I want to resist that. The site is a public service in the way a good map is: it does not tell you where to go, it tells you what is there. The fact that someone walked the kernel source for 27 architectures and every release since 3.3, and then built an API on top of it, is the kind of quiet infrastructure work that rarely gets attention and always gets used. I will be curling that endpoint the next time I cannot remember whether epoll_wait is 232 or 233. And I will probably look up open again, just to see if it is still number 2.

https://syscall.sh/