DEV Community

Simple Memo
Simple Memo

Posted on

I deleted every Zettelkasten ID and my notes got better

For three years I hand-maintained a Luhmann-style ID on top of every note I kept: roughly 1,400 of them, little addresses like 3a2 and 3a2b clipped to the front of each line. Last spring I deleted all of them in one afternoon. The disaster every Zettelkasten guide promises, notes collapsing into an unnavigable pile the moment you remove the structure, never arrived. If anything, the notes got better at the one job I actually need them for now: being read by a machine.

I want to argue that the famous ID scheme at the heart of the Zettelkasten method solves two problems I no longer have, and quietly charges me for a third I never noticed. And I want to make that argument in the era where a large share of my note retrieval is not done by me at all, but by a language model reading my notes as context.

TL;DR

  • The folgezettel ID was an answer to a physical constraint (paper cannot be searched) and to a human navigator walking a branch by hand. In a plain-text note folder I have neither problem.
  • Full-text search and backlinks already reproduce most of what the ID graph did. Even inside the Zettelkasten community this is largely conceded for digital setups.
  • The newer reason to drop the IDs: a model reads dated plain prose far better than a lattice of cryptic addresses, and I feed it my notes constantly now.
  • What I lost is real. The "at a glance" shape of a thought's branch does not survive the change, so this is a trade, not a free lunch.

The orthodoxy, stated fairly

Niklas Luhmann, the German sociologist, built a paper Zettelkasten of around 90,000 index cards starting in the early 1950s, and credited it as the engine behind a working life of dozens of books and hundreds of papers. The cards were digitized and put online in 2019, so this is not folklore; you can go and look at the actual slips.

The part everyone borrows is the numbering. Luhmann used what German speakers call folgezettel, "follow-up notes." The first card is 1. An unrelated new card is 2. But a card that continues, comments on, or branches from card 1 becomes 1a; the next in that strand is 1b; a comment on 1a becomes 1a1. The address is not a filing location, it is a position in a tree of thought. A quietly brilliant second-order effect falls out of this: a topic worked for years grows long addresses, so the length of an ID tells you at a glance how deep that vein has been mined.

Sönke Ahrens' 2017 book How to Take Smart Notes carried this method out of German academia and handed it to a generation of knowledge workers, and the modern digital Zettelkasten scene (zettelkasten.de, the Obsidian and Logseq crowds) grew from there. The orthodoxy that travelled with it is stated often and stated confidently: the ID is what makes a Zettelkasten a system instead of a junk drawer. Drop the ID and you have a pile.

I believed that the whole time. I was wrong about it, and the reason I was wrong is the useful part.

Why did the IDs feel productive when they weren't?

Because assigning an address felt like thinking, and it wasn't. It was filing.

Every time I made a note I had to decide where in the tree it hung, which meant re-reading neighbors, comparing, placing. That work produced a warm sense of having done something rigorous. But almost none of it changed what I later understood; it changed only where a card sat. I had confused the ceremony of organizing with the act of thinking, and the ceremony carried a real cost I was paying at every single capture.

Here is the tell. In all those years I can count on one hand the times I retrieved a note by walking its folgezettel branch. Every other retrieval, thousands of them, was a full-text search. I had built and maintained an elaborate coordinate system and then navigated by coordinate almost never.

What the ID was actually for

Two jobs, and both have quietly expired.

The first job was giving paper a coordinate system. A physical card has no Ctrl-F. If you cannot search the contents you must know where a thing lives, so you impose an address and a tree on top of it. Luhmann's move was partly a workaround for the fact that a wooden box of cards is opaque to search. My vault is a folder of Markdown files. It is nothing but searchable. The original problem is simply gone.

The second job was letting a human walk a line of thought by hand, card to card. That one is subtler and more defensible, and I will come back to it, because it is the part I actually gave something up to lose.

Then there is the job nobody designed the ID for, the one that decided it for me. I now spend a large part of my week handing chunks of my own notes to a language model as context: debugging with it, drafting with it, asking it to reconcile something I wrote in March against something I concluded in June. A model does not traverse my link graph. It reads text, straight through, in order. To that reader a line like 2026-03-14 Outbox retry needs jitter or the whole queue wakes on the same tick is entirely legible. A line that opens with 3a2b -> is noise it has to spend attention decoding. The ID I was maintaining for a human navigator is, to my most frequent reader, litter.

Folgezettel ID Dated plain line
Optimized for A human walking a branch Search, and a model reading straight through
Cost per capture Compare neighbors, place in the tree Stamp the date, type the thought
How I retrieve Navigate the graph by address Full-text search or a backlink
Machine-readable Poorly; the address is opaque Natively; it is just dated prose
Maintenance on insert Re-thread, sometimes re-number None

The evidence, including the part that hurts

The community already half-admits the first half of this. Spend an hour on the Zettelkasten forums and you find the folgezettel debate running for years: whether the branching ID means anything once you have gone digital. The recurring finding is that in a tool like Obsidian you do not need unique IDs to capture the folgezettel structure at all, because backlinks reproduce it. Open a note and its continuations are simply listed as the things that link back to it. The timestamp method, where you date-stamp the note and let search and links carry the rest, is a completely mainstream alternative and not a heresy I invented on my own.

So the deletion was low-drama. I stripped the 3a2 prefixes with a script, kept the dates, and my retrieval, being search all along, never noticed the IDs were gone.

Now the part that hurts, because I do not trust a case that only flatters the person making it.

Folgezettel's second job, the at-a-glance topography, does not come back. When the shape of the branch is the information, when seeing that one vein has grown a forty-character address tells you instantly that this is where your real work has accumulated, backlinks genuinely do not give you that. A list of backlinks is a set, not a shape. For the two years I was building toward one long argument, that topography might have been worth its tax. I killed it because I am not building one long argument. I am running a software product and catching fast-moving thoughts before they evaporate. Different job, different tool. But I would rather say plainly that I traded something away than pretend I found a strictly dominant move.

So when does a Zettel ID still earn its keep?

Three honest cases. When your corpus has to outlive your tools, whether that means paper or a format you will migrate across decades, an ID that is independent of any one app is a real asset. When the branch shape is the product, as in genuine long-form theory-building, the topography is worth maintaining by hand. And when you have no trustworthy full-text search, the coordinate system stops being ceremony and goes back to being load-bearing.

None of those is true for me. All of them might be true for you, and if so, keep your IDs; the method earned its fame honestly.

What I run now is almost the opposite of a system. One folder, one dated line per capture, written in nouns and verbs a stranger could parse, no addresses. Search is the index. Backlinks are the graph. And the second reader I actually optimize for is not future-me squinting at 1a1; it is the model I will paste these lines into next week. In the LLM era, the second brain worth keeping is the one the machine can also read.

I deleted 1,400 IDs and replaced them with the date.

A few questions I keep getting

Isn't this just a worse Zettelkasten? It is a different bet. Classic Zettelkasten optimizes for a human building a connected argument over years. I optimize for cheap capture and for two readers, search and a model. If your work looks like Luhmann's, mine is the worse choice. If it looks like shipping and debugging, I think the reverse.

How do you link notes with no IDs? Plain backlinks and the date. If two notes belong together I link their titles directly; the date gives me a stable ordering and a rough "what was I chewing on that week" axis. I also split capture and curation into a fast layer and a slow one, so the linking happens later, while I am reading, not while I am trying to catch the thought.

Does full-text search really hold up over years? So far, yes. My notes are a couple thousand plain Markdown files and search is instant. The one place it strains is genuinely ambiguous terms, which a date range or a single backlink resolves. Plain text is also the one format I am confident will still be searchable in twenty years, which is more than I can say for any app's database.

If you run a real folgezettel Zettelkasten, here is what I want from you: the single retrieval you can do that I no longer can. The specific lookup where walking the ID graph beats my search box. Not the philosophy, the concrete case. That is the thing I might have thrown away without noticing.


I build Simple Memo by myself: an iOS app that puts one line of text into my email about a second after I type it, and appends the same line to my Markdown vault on the evenings I sit down to curate. I wrote up how the Markdown side works if that is the part you came for.

Top comments (11)

Collapse
 
fromzerotoship profile image
FromZeroToShip

This lands the same week I stripped my own note index down to almost nothing, so it hit home. My version of the Zettelkasten ID was an index where every entry had grown a rich three-clause summary "so I wouldn't have to open the file" — and that convenience quietly became the bloat. The detail belonged in the note; the index just needed to be a signpost pointing there. The moment I cut each line back to "what it is + where to look," the whole thing got usable again.

The deeper pattern you're naming is that a system's ceremony can quietly outgrow its purpose. IDs, tags, elaborate metadata — each one earns its place individually, and collectively they turn note-taking into note-administration. The test I've started using: if I spend more effort maintaining the structure than consulting the content, the structure is the problem, not the solution.

What did deleting the IDs cost you, if anything? I keep expecting a downside — a link I can't rebuild, a note I can't find — but every time I simplify, the loss I feared just doesn't show up. Curious whether you hit any real edge, or whether the fear was the whole cost.

Collapse
 
simple_memo profile image
Simple Memo

Your signpost test — "more effort maintaining the structure than consulting the content" — is almost exactly the line I crossed without noticing. Your index that grew three-clause summaries is the same disease as my IDs: the scaffolding quietly took over the building's job.

On the cost, because I don't trust the version of this that only flatters me: I did hit one real edge, and it took a few months to surface. Search fails me when I remember where a thought sat but not what words it used. "It was a branch off the retry-jitter note" is a position, not a query — my search box can't take it, and the folgezettel ID could have walked me straight there. A handful of notes in ~2,000 are stranded that way. Rare, but a genuine loss, not just the fear.

So mostly the fear was the whole cost — but not entirely. What survived was narrow: positional memory with no words attached. I lean on backlinks now for the two or three veins I actually think in branches, and let everything else stay flat and dated. When you cut your index to a signpost, did you keep any handle for the notes you navigate by position rather than by content?

Collapse
 
fromzerotoship profile image
FromZeroToShip

"I don't trust the version of this that only flatters me" — that sentence is why I'm answering at length, because it's the exact posture I try to hold and mostly fail at. You went looking for the cost that survives your own preference, found a real one, and reported it at its actual size. That's rarer than the technique.

To your question, honestly: I kept two handles, and neither fully covers the case you named. The first is a wikilink between notes — [[the-note-it-branched-from]] — which encodes "this thought lives next to that one" as a relation instead of an ID. It gets me most of the way to a folgezettel: "it was a branch off the retry-jitter note" becomes a link I can follow, as long as I remember the neighbor. The second is a namespace prefix on the name itself — domain plus role — so "that admin-scope thing in the ops tool" narrows by position-in-the-system even when I've lost the words. Together they catch the notes I navigate by what they sit near, which is a big chunk of your case but not all of it.

Where I land is the same triage you did. Most notes are fine flat and dated — content-addressable, findable by search, no scaffolding earned. A minority genuinely live in branches, and only those get links. The hard part isn't the mechanism, it's predicting which notes will later be remembered by position and not by words — you can't know that at write time, so a few always strand, exactly your handful in 2,000. I've stopped trying to eliminate that and started treating it as the correct residual cost: the price of not paying folgezettel rent on all 2,000 to save the twelve. Your trade sounds identical — backlinks for the two or three veins you actually branch in, flat for the rest. Maybe the honest answer is that positional memory with no words attached is just genuinely lossy, and the skill is spending the handle only where the branch is load-bearing.

Thread Thread
 
simple_memo profile image
Simple Memo

The prefix is doing more work than the wikilink, and I think it's the more interesting of the two. A backlink needs me to remember the neighbor; lose the words and the neighbor together and it's dead too. The namespace prefix survives losing both, because the position is baked into the name structurally instead of stored as a relation. That's the one handle that actually reaches my stranded case.

On predicting at write time, I tried exactly that and it failed worse than you'd guess. For a month I flagged "branchy" notes with a leading asterisk so the load-bearing ones would be easy to thread later. When I audited it, my write-time guesses were worse than chance. The notes that turned out position-memorable were mostly ones I'd judged unimportant while writing, which is the whole reason I gave them no searchable words. You can't flag what you underweighted.

So I've come all the way around to your "correct residual cost," with one edit: it isn't a random twelve in 2,000, it's a biased twelve, the notes I misjudged at capture. Which leaves the structural hedge you already named as the only one that works, since the prefix costs nothing at write time and doesn't need me to have guessed right.

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

"You can't flag what you underweighted" is the sentence — that's the whole failure mode in one line, and it kills every importance-at-write-time scheme, including the one I'd half-built.

I run a note store with exactly your two handles: namespace prefixes on the filenames and explicit backlinks between them. Your ranking is right — the prefix survives losing the words and the neighbor because it encodes kind, not importance, and kind is something I can classify at write time without predicting the future. Backlinks are the ones that rot, exactly as you say: they need me to still hold the relation.

The one thing I'd add, because it reaches your biased twelve specifically: a third handle that's neither a relation nor a guess — a single flat index where every note lands as one line, regardless of prefix or links. It costs the same "nothing you have to get right" as the prefix, but it also reaches the note you misclassified, not just the one you filed correctly-but-stranded. When the prefix itself is wrong — I underweighted it, so I dropped it in the loosest bucket — the index line is the only handle left, because scanning the whole list doesn't require me to have known where it belonged. Prefix hedges wrong-neighbor; the flat index hedges wrong-prefix. Both work for the reason yours does: no write-time cleverness required.

Thread Thread
 
simple_memo profile image
Simple Memo

The flat index is the one I underrated, and you've put your finger on why: it's the only handle whose key I can't get wrong, because I don't assign it. The note just lands in order, and chronology is the zero-cleverness index. The timestamp comes from the world, not from my judgment, so there is nothing there to misclassify.

Where I'd push, because I don't want to just nod twice in a row: the flat index reaches the misjudged note only if I recognize it on the scan. For the biased twelve that's the hard case, since I misread them once and can slide right past them a second time too. It rescues the note I filed lazily, not always the one I actively saw wrong. Still a real third hedge, and cheaper than either of us is admitting. Have you ever caught one of your own wrong-prefix notes on a flat-index scan, or does the misjudgment tend to repeat?

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

Direct answer: it repeats. I have a clean measurement of this from two days ago, and it's worse than "sometimes slides past."

My flat index isn't just scannable, it's loaded at the start of every working session — so I read the line in question dozens of times over several weeks. It said the catalog held 46 items. The actual count was 58. Not a subtle drift: three other documents said 42, and I'd read those too. Every one of those readings was a flat-index scan of exactly the kind we're describing, and not one of them caught it, because I wasn't reading the line as a claim. I was reading it as the answer to a question I'd already stopped asking.

What finally caught it wasn't a better scan. It was someone in a comment thread describing a phantom-count problem in their own system, which sent me to check mine — and then a mechanical comparison, not my eyes: I added an assertion that the number quoted in the index has to equal the number of rows actually in the catalog. That check found the discrepancy in one run, and its first act was to fail on my correction, because my first fix used a count from a stale copy. So my answer to your question is: the flat index made the note reachable, and reachability was never the binding constraint — the same judgment that misfiled it is the judgment doing the scan. Where it earns its keep is as the surface a machine can assert against. Prefix hedges wrong-neighbour, the index hedges wrong-prefix, and a count assertion over the index hedges the wrong-reader, which turned out to be me every single time.

Thread Thread
 
simple_memo profile image
Simple Memo

"The wrong-reader turned out to be me every single time" is the line I'm keeping. The assertion caught it because you'd encoded a falsifiable invariant — index count must equal row count — and a machine will hold that without ever getting bored of re-reading it. But that's also its ceiling: it only reaches notes that assert something checkable. A dated line like Outbox retry needs jitter has no row count to diff against; there's no ground truth for the check to fail on, so for the prose half of the vault the wrong-reader is still me, unassisted.

So I've started sorting captures by whether they carry an invariant at all. The ones that do get a check that can fail loudly and early; the ones that don't stay exactly as exposed to my own stale reading as they always were — I just know now which half I can't automate my way out of.

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

The partition is right, and I'd push on where the line falls, because I think it's more movable than it looks.

"Outbox retry needs jitter" carries no invariant as written — but that's a property of the phrasing, not of the content. It's a claim about the world stated as an intention. Rewrite it in the present tense about the code — "outbox retry has no jitter" — and it becomes checkable: grep the retry path for a jitter term. Same note, now falsifiable. And it picks up the property you actually want, which is that it dies on its own the day someone adds jitter, instead of sitting there being true-but-finished.

For the half that genuinely can't carry one, there's still something a machine can hold that isn't a judgment about content: whether the referent moved. A note that mentions outbox.js can be checked against that file's history — "this has changed fourteen times since you wrote this line." That says nothing about whether the note is wrong. It says the note is now unverified, which is a different state from stale and a much more actionable one.

One thing I'd expect to bite later: the sort isn't one-time. A note with no invariant today acquires one the moment the thing it describes exists, and nothing will tell you it crossed over.

Collapse
 
secondbrainstarter profile image
Second Brain Starter

Strong case for dropping the address - the dated-line setup is exactly the direction I ended up in too. Two nuances from maintaining a plain-text vault that way:

  1. The argument is against the tree address, but an identifier has a second, quieter job: keeping links alive when you are not inside the app. Your capture pipeline appends lines to the vault from outside (email, scripts), and the automatic link update on rename only runs when you rename inside the editor. Links typed by hand or generated by a script rot silently the day a target gets renamed - or a duplicate filename shows up. A stable, unique filename slug (not an address, just an anchor that never changes) is the cheap insurance that keeps plain backlinks working across a restructure.

  2. The topography loss is real, but cheaper to replace than it looks. Backlinks are a set, agreed - but a small set of hand-curated hub notes (one per topic, "what was I actually chewing on here") restores a rough at-a-glance shape for minutes of maintenance, no coordinate system required. That covers the "where has my real work accumulated" question well enough for me.

On your open question to folgezettel users: I cannot answer it either, because I never walked branches. But I suspect most digital Zettelkasten users would have to search hard for a retrieval that genuinely beats full-text search - and that hesitation is itself the tell you are describing.

Collapse
 
simple_memo profile image
Simple Memo

You've drawn the line I blurred. I dropped the address — the tree position that claimed to know where a thought belonged — but you're right that a stable anchor is a different animal, and in one spot I threw it out with the bathwater.

The capture lines are safe: their anchor is the timestamp, world-assigned and never renamed, the same zero-cleverness key we landed on upthread. The rot shows up one layer later. When I promote a line to its own file during curation and rename it to something readable, a link a script appended from an old daily note still points at the old name — nothing updates it, because the rename happened in the editor and the reference lives outside it. So the address was the part worth deleting; the anchor was the part I should have kept. They just happen to live in different layers: the timestamp anchors capture, the slug anchors curation.

On the hub notes — they recover the topography I noticed, but a hand-curated hub inherits the bias we beat to death here: a note only reaches it if I already recognized it mattered. So hubs rebuild the deliberate structure and still miss the latent kind.

Do you mint the slug at capture time, or only when a line graduates to its own file — and if at capture, how do you keep it stable without it quietly turning back into the address you were escaping?