Written on 2026-09-20
After struggling for years with information and task management, I have developed a custom personal knowledge management system (PKMS) that works for me. Some people have been curious about it, and requested that I write about it, so in this article I will:
Note that not one size fits all, and this is the result of lots of small iterations to scratch my own itches. If you want to build your own system, start simple and address points of friction as you go. I will make an effort to give context for my own decisions, so that you can decide whether they make sense for you or not.
My system is organized around my own requirements, rather than around interesting technology or trends. I use it to keep track of:
I record this information for several purpose:
I also self-host my contacts and calendar management using vCard and iCalendar respectively, but this is orthogonal to my personal knowledge management system, so I consider it out of scope for this article.
I use variants of the same system at home and at work, so it needs to satisfy their distinct requirements. Those variants are more alike than different, but let me point out some of the differences.
On top of the above, I have a few additional requirements specifically at home.
First, I need support for multiple devices. I don't want to be locked to a single stationary workstation for taking notes.
Second, I need to be able to jot down quick notes on my phone, to be fleshed out and polished later at home.
Third, I need this system to help me manage future tasks. This may sound unrelated to knowledge management, but we will see later how it can make sense to couple them.
At work, I need to manage meeting notes. This requires keeping up with the meeting, but also ensuring that I can later easily recall what I captured.
I also need to manage TODOs, which is separate from the task management that I need at home, because I already have a ticketing system at work. Those TODOs have fewer constraints (no sync across devices, always access to my main system), so I have a different solution for them.
Finally, here are a few use cases that some people have for their PKMS, but are explicitly out of scope in mine:
I have briefly tried to adopt existing systems, but realized that none of them really worked for me.
Zettelkasten is interesting, but it focuses too much (for me!) on emergent knowledge. In fact, it is actively discourages "building your own wiki". I do want to let relations surface, but it is not my only motivation, and I do want to build my own, private wiki.
Organizational frameworks such as PARA or CODE also do not make a lot of sense to me, due to the diversity of information and structure that I have in my system.
Finally, I've found external resources (blogs and YouTube videos) to have very low signal to noise ratio, even just as inspiration.
My approach is to have good data1, with good tools that operate over it, and keep them decoupled.
I store all my data as Markdown. This limits me to simple note taking (no rich media or databases), which works fine for me, and prevents me from going overboard.
It is easy to deal with, has no vendor lock-in, and is compatible with lots of existing tools (and writing custom ones is simple).
Markdown is also AI friendly, although I don't plan on using it on my data at this time.
I manipulate all this Markdown using Neovim, my preferred text editor. Doing so let's me leverage my expertise with it, and always be in a familiar, comfortable environment. I use it together with markdown-oxide, an LSP server that I use for auto-completion, navigation and refactoring.
On my phone, I use Obsidian, although I make conservative use of its features to preserve compatibility. When I'm travelling for extended periods of time without a personal laptop, I tend to use Termux over scrcpy for significant edits.
Features that I mainly rely on include:
Using Git with text data is second nature to me, and I'm anxious editing it without some sort of version control. It provides me with several benefits:
On top of that, I find it very convenient that uncommitted changes naturally map to work in progress. If I didn't use Git, it would be too easy for me to loose track of in-progress changes, likely leaving bits of unfinished work alone.
In my personal setup, I make use of iCalendar task lists for a few use cases.
First, I use it for taking quick notes (mostly on my phone) to be later fleshed out and polished at home. Those notes may be specific events that happened, in which case I associate them with the date at which they happened. They are always listed in the past.
Second, I use it for designating (potentially recurring) tasks in the future. The designation (i.e. giving the task a specific time to perform it) is crucial (to me) to actually getting it done. It also helps me not overload myself by not designating an excessive amount of work at a given date.
Last, I also put non-designated "tasks" in there, when they have no priority. This is typically how I store movie or book recommendations from other people.
I prefer using that over putting everything in the Git Markdown repo (potentially using #todo tags), as it reduces churn. This data is transient, so it doesn't need to be put in version control.
I self-host a Radicale server to share task lists between me devices. On the client side I use vdirsyncer and DAVx5 to sync and todoman and Tasks.org (on desktop and Android respectively).
When I need to capture some information to later turn into a Markdown note (e.g. as a result of a conversation, something I have read, some idea I came up with), I will capture that as an iCalendar task.
This workflow is very simple:
I process those captures when I get home, to turn them into proper notes.
Ultimately, all of my notes (research, travelling, meetings, introspection, health, etc.) are written down in my Markdown repo.
As I write things down, I make use of custom keymaps to efficiently create and link notes. I create new notes for any concept that I might want to later expand upon or to link. Technically, both markdown-oxide and Obsidian deal well with unresolved links, but I personally prefer to have actual files for them anyway.
Because it is so easy to create new notes, I tend to quickly map out the domain. Depending on the size of the subject being research and the amount of information/concept that is new to my repo, I may either take some quick notes, or flesh them out on the spot. For example, it is more likely that I will start with some messy notes about a country that I've visited for the first time, whereas I will probably document a refinement to an existing math concept as a one-shot.
Regardless, a key aspect of this workflow is that I almost never commit changes that are not properly polished. This is important so that:
Here is an example of a short note:
# $\LaTeX$
## Math variables
- Don't use `\text{}`, since it exits math mode.
- Use `\mathrm{}` (roman) for constants, units, or short labels (e.g. $F_{\mathrm{max}}$).
- Use `\mathit{}` (italic) for multi-character variable names (e.g. $\mathit{speed}$).
## Distributions
[Tectonic](https://tectonic-typesetting.github.io/) is a "modern" distribution that downloads packages on demand, and leverages XeTeX and TeXLive.
## Links
- [[latex_cheatsheet]]
(In practice, math and plots are rendered inline in my editor.)
I try to keep my notes relatively short (so that it's easy to link to any piece of information), but they can easily contain a lot more links and information.
For actual task management (i.e. things I need to do in the future, not the on-the-go captures I described earlier), I also use my task system.
Every time I come up with something I need or want to do in the future, I add a new iCalendar task. Critically, every task must have a designated time in the future to accomplish it. This helps me make sure that I will get to it, but more importantly, it ensures that the load remains realistic. If I see that I already have too much on my plate, I can either pick a later date, or decide to drop another task. This forces me to make choices, rather than accumulate a never ending TODO list, which would sap my motivation.
Those tasks get synced with my regular calendar, so I can quickly see what is coming up, and when I have available time. Tasks and calendar events are similar in many ways, but it is relevant to distinguish them:
For me, this workflow is reliant on knowing my limits to not overburden myself, and having some buffer, so that things can slip without me getting behind, and so that I have some room to add new short/medium term tasks.
Note that it is very possible to have a "TODO" task in the future that refers to a "capture" task, and is about designating some time to flesh it out and add it to the Markdown repo. It all comes together!
Here are some of my personal preferences about how to structure files and note contents.
All of my files live in the same directory. I make no use of sub directories for the following reasons.
First, I make extensive use of [[wiki_links]] (as opposed to [Markdown links](path/to/file.md)), which requires file names to be unique across the repo to prevent ambiguities. Having all files in the same directory ensures that all names are unique.
Second, it makes it a lot easier to manage. I spend no time wondering where to create new notes, I always have exactly one place to look whether I already have a specific one in my repo, etc.
Third, a single hierarchy is too limiting for me. Plenty of notes belong in more than one category, and I have little interest in building taxonomies.
I consider writing Markdown with one sentence per line to be vastly superior to the alternatives.
Links are my main tool for serendipitously finding existing notes, and one of my 2 tools (together with text search) for intentionally finding them.
I link aggressively to establish relevant forward and back links. With that being said, I do not overdo it: I will rarely have the same link twice in a single note.
I link directly in the note's prose, but also often have a "Links" second level section at the bottom of the file. This section exclusively contains a list of links (both internal and external, if the external resource doesn't have its own note) that I consider to be relevant. Think of it as a combination of Wikipedia's "Notes" and "External links" sections.
I also make heavy use of indices (aka maps of contents). Indices are topical notes that only contain a list of links to other notes (potentially indices themselves). They make it very convenient to drill down from a high level topic to a specific note. All notes in the repo are reachable from the README.md regardless, but indices makes it quicker to get to them.
Here is a severely shrunk2 example of a note that is a hybrid of a regular note and an index:
# C++ - [[compiler_optimizations]] - [[const_cast]] - [[cxx_ranges]] - [[cxx_reflection]] - [[extern_template]] ## Misc tricks - Use unary `operator+` to convert a lambda to a function pointer. ## Links - [Special member function table](https://www.foonathan.net/2019/02/special-member-functions/) - [[the_worst_programming_language_of_all_time]]
I don't make use of tags, because they are not worth the time required to maintain to me.
I can see how they are useful for performing queries on my data, but indices and search are currently sufficient for me to find the information that I'm looking for.
I keep journals ("logs", as I call them) both at home and at work.
At home, I use it to write miscellaneous everyday notes that I wouldn't link to, and therefore don't deserve a dedicated note. I also link life events, so that I can later go back and see what was going on at a particular time.
At work, I use it to write down what I do, every single day. This helps me look back during team meetings, and gives me some perspective on how I spend my time. Sometimes, it helps me realize that I've been stuck on the same topic for a while, and it is time to consider a different approach, or bounce some ideas off of a colleague.
In both cases, the logs are split by year, for 2 reasons:
Logs are formatted as a series of second-level headings, each being the date for that entry.
Here is an example of how my logs look like:
# 2026 ## 2026-09-20 Let's pretend that this is an entry in my personal log. I met with [[some_friend]] that I hadn't seen in a while. It was nice catching up, and I'm writing it down, because I want to remember it later. I went to see [[a_movie]] that afternoon, and it reminded me of [[an_idea]] I had a while back. In the evening, I caught a flight that was the beginning of [[2026-09-20_trip_to_tokyo]]. In that note, you'd find a sort of mini log, together with sections about my thoughts on the trip, and links to various relevant things. ## 2026-09-21 Now let's pretend that I'm in my work log. This one would be a lot more spartan, especially without the explanations. [[work_monitoring]] This note would contain notes about the work that needs to be done on monitoring. It would also have a section called TODO containing a list of remaining tasks, and another one called Done containing a list of dated tasks. [[2026-09-21_meeting_with_john]] This note would be my notepad during the meeting. At the end of the day/when I get to committing it to Git, I would extract out the useful information into other notes, new or existing.
For timed events (either point in time, or ranges) like meetings or travels, I split them out in their own note. Those notes are named YYYY-MM-DD_note_name, where the date is the start of the event. This note is linked appropriately as usual, and also linked into the log (in the case of ranges, I link it both in the log entry for the first and last day).
It is important that the contents are not in the logs themselves (otherwise they would immediately get lost/forgotten), but it is useful to have links to those notes in the logs for continuity.
I exclusively use text files in my repo. Obsidian supports rich media and Neovim can display images, but I haven't had the need for them, and prefer to err on the side of compatibility.
With that being said, I do write a significant amount of LaTeX (math and plots) in my notes, which both Neovim and Obsidian can render inline.
While I disagree that it is a bad idea to write one's own wiki (if anything because it contains private information), I do believe that it is critical to paraphrase, rather than import information unedited (light quotations are fine).
First of all, rephrasing information helps ensuring that I understand it properly.
More importantly, there is typically a mismatch in the prerequisites, amount of information, and level of abstraction, between the source material and what I want to commit to my repo. For example, the source material may present some prerequisites that I'm already familiar with, or have a separate note for. Generally speaking, I want to maximize the value that I will get from the note in the future, which is always going to require presenting the information in a way that is different from the source material.
As a final word, here is one thing that I don't do yet, but plan on trying out at some point: I would like to implement a system for "me time".
The details are unclear, but I'm thinking about designating some time in my task system, but without a specific associated task. I would just block out this time, and pick from a pool of things to do (or not, it's me time!).
1 I generally make a difference between data (which is raw) and information (which is contained in data). In that sense, I try to capture information in my repo, but it is stored there as data.
2 You didn't think that I was going to give away all my C++ tricks, did you?