microlog.me: six years of designing a tracking system
In 2019 I wrote the design doc for a tracking system I could not build yet. I spent six years contradicting one bullet in it.
Motivation
In April 2019 I was keeping a to-do list on paper and ticking items off by hand. I had wanted to build this as an app for a while and had not built it, and when I finally wrote down why, the reason was not a good one. What was stopping me most was not starting a list at all, because I kept bikeshedding over which app to use and could not find a perfect one.
Sizing the unit of work
So I stopped looking and used paper, and within a few days the paper told me something I could not have guessed at a whiteboard. Items that would take about two hours never got started. Items that took about twenty five minutes did. I wrote it down as a property of the system rather than a property of my mood:
"I also realized that there is a sweet spot in the length of time between ticks -- I can't have a to-do list item that takes 2 hours long because it feels too intimidating to start."
That is a measurement. It says the unit of work has an upper bound somewhere under two hours, and it says the bound is about starting rather than about finishing. You only get findings like that by running the system on yourself, which is why I wrote down a rule in the same entry that governed the next four years:
"The reason why I am not executing on mlog is because right now, the idea is much too vague, and I need to develop a manual system before optimizing it into an app ("it must exist before you can optimize it.")."
Adjacent work: Getting Things Done
Four months later I sat down to work out what the app should be, and started by reading the existing methodologies properly rather than assuming I already knew them. I planned to go through three of them and in the end only worked through one, Getting Things Done, which turned out to be enough because the thing I needed from it was a single abstraction.
The abstraction is the open loop. An open loop is anything unresolved that you are still holding in your head, and the argument is that holding them is expensive: your mind is a place for having and combining ideas, and every unresolved thread sitting in it takes room that combining needs. The method is a set of lists to move open loops out of your head and a weekly review to keep the lists from rotting. What I wrote down as worth keeping was the open loop itself, the calendar, and the weekly review, and I kept the weekly review for a specific reason, which is that a system with no scheduled maintenance decays without anybody deciding to abandon it.
What I did not keep was the two minute rule, which says that if a next action takes under two minutes you should just do it. My objection was not that the rule is wrong but that it leaves the middle unhandled:
"doesn't provide guidance for how to manage granularity of next action. don't really want everything to become something actionable within 2 minutes, and also don't want to handle multiplicity of projects that are > 2 minutes."
That is the same gap the paper had already shown me from the other side. Paper told me two hours is too big to start. GTD told me two minutes is small enough to just do. Nothing in either told me what to do with the enormous space in between, and the whole design problem of a personal system lives in that space.
One platform, or many tools over a shared store
The same document has a goal statement and a note to myself:
"The ultimate goal of microlog.me is to make it so you can design your own workflow through code. EXPAND UPON THIS"
Under that marker I wrote two bullets. The first is a question. The second is its answer, and I did not treat it as one:
"* what is the benefit of 1 productivity platform to run everything?
- i actually prefer a lot of individual tools but I prefer not to pay for them but I want some way such that all the data remains in sync"
I asked what a single unified platform buys you, and then immediately wrote that I prefer many separate tools and only want the data to stay in sync. Those are different systems. One is a platform that owns everything. The other is a set of independent tools over a shared store. I wrote the second one down, in bold, in 2019, and then spent the next six years building toward the first.
The second system needs one thing from every tool in it, which is a way for a program to read and write the data. That constraint decided things for me long before I could argue for it. In November 2020 I wrote that Trello with its API might be the custom solution I was looking for, instead of microlog and Notion, because I just needed something simple to implement my system and stick to. The reason Notion lost, stated flatly in the next sentence, is that Notion did not have an API. It has had one since 2021 and the sentence is a fact about that month rather than about the product. But it is a good illustration of the rule underneath: in a system made of independent tools, a tool with no programmatic access is not a component, it is a destination.
The log model
By the time I had a proper specification, the core idea had a name and a shape. I did not have a formal definition and said so, and then gave the two artifacts I was reasoning from:
"you can think of your life as a linear timeline of discrete, noteworthy events recorded chronologically. Similar to how logfiles record important events with relevant context, or how our banks/cryptowallets/finanical apps provide a transaction log, a "logfile for your life" would consist of timestamped chronological entries about the things important to you."
A program's log file and a bank statement have the same three properties. Entries are timestamped, they are appended rather than edited, and each line carries enough context to be read on its own later. Those properties are worth wanting for personal data, because they make the record honest. An append-only store cannot be quietly revised to match the story you would prefer, which is most of what makes a bank statement useful and all of what I wanted from my own.
The scope was deliberately wider than self tracking. A log entry could be anything I cared about, including things I had no part in, like a world event or something that happened to a friend. And the integration contract for anyone building on it was that they had to do the translation: developers should find ways to turn the behavior of their app into the language of logs and timestamped entries.
The implicit runtime
The fullest version of the specification is not a design document. It is a prompt I was writing to ChatGPT, asking it to act as an ideation partner, and most of the text is me explaining the system carefully enough that something else could think about it with me.
Partway through I walk through setting the thing up. I install a Gmail integration, authenticate, which produces a connection object inside my workspace, and then use that connection to create a feed of new messages. The feed comes from a community contributed flow that makes one API call and returns a plain object.
Then I asked a small implementation question, the kind you have to answer before you can write any code:
"in which runtime / exec context does this POJO (which may include functions) exist"
There is no way to answer that without conceding something. If the object exists, something is running that it exists inside. So the workspace is not a database with integrations attached, it is a program that runs continuously like an event listener loop, and the objects live on top of that program's execution context, and the transformations between them are operations in some evaluation order.
That concession is bigger than it looks, and the way to see it is to ask what the ordinary parts of a programming language are. There are values, meaning the things you can hold: a number, a message, a connection. There is somewhere those values live while the program is running, which is what separates a value from a line in a file. There are operations that take a value and produce another one. And there is an order those operations happen in, so that the second can depend on the first.
I had specified all four while trying to specify a tracking tool. The connection is a value. The workspace is where it lives. The flow that turns a connection into a feed of messages is an operation. And the fact that you have to authenticate before the feed can exist at all is an evaluation order, sitting there in my own setup story. Which produces the line in the document that I still like:
"Ooh, this means that Microlog.me has a sort of implicit VM and semantics for a simplified log-flow oriented language."
That is not a metaphor. Those are the parts, and I had drawn all of them without once using the word. It is a thing that happens to anyone who specifies a system carefully enough to build it: describe precisely how information moves through your thing, and somewhere in the description you will find you have defined a small language, whether or not you were trying to.
The document then ends. Not with a conclusion, but in the middle of a sentence, on the hardest remaining problem:
"While simplification / reduction of structured data models using the "log"-centric framework helps, the task of unifying the entire space of data structural patterns of infinite variety"
The missing primitive: inference
The design sat unbuilt for years, and it was not blocked on a database or a framework. In August 2023 I wrote one sentence that explains the delay better than anything I had written before it:
"It is now possible to apply automation and superintelligence for inference that would've taken my time, attention, and additional knowledge I do not possess. Projects like MicrologMe are finally possible."
The word is inference, and the sentence names three things it was standing in for: my time, my attention, and knowledge I do not possess. The first two are the sort of thing better software fixes. A task that takes too long gets automated, and a task that takes too much attention gets asked fewer times a day. The third is not that kind of problem. A faster form still does not know whether the sentence I just typed describes a meal, a purchase, or both, and no amount of discipline on my part supplies a judgement the software cannot make. Somebody has to do the interpreting, and for the first four years of this design the only somebody available was the person typing.
Consider what the 2019 design required. To record an ordinary sentence about your day, something has to decide which parts are events, when each happened, and which of your categories they belong to. In 2019 the only way to do that was to make the person do it, by filling in a form whose fields were defined in advance. Every schema I drew was a way of moving that work onto the user. By 2023 you could hand the raw sentence to a model and let it do the sorting, and the schema stopped being the interface and became a description of the output.
The clearest way to see that shift is to put the two versions of the same daily record next to each other. Here is the template I was filling in by hand in June 2020, with the contents stripped out:
Day 33/217 (184 days left)
Week 5/31
Mission
To do list
Habits
Journaling
Food Journaling
Expense Journaling
Fasting
Meditation
GYM
Bicep Curls
Shoulder Raise
Korean Learning
Highlights
Expenses
Food
Insights
Seven named sections, with nine named habits inside one of them, every one decided in advance. To record that I ate something I had to know that Food was a section and that it was a different section from Expenses, even when one purchase produced an entry in both. The schema is the interface, so using the system means holding the schema in your head.
Here is the same record now. There is one command, and it takes a sentence:
organs log "Ate: chicken, broccoli, okra (home cooked)"
organs log "Gym: bench DB 150x10, dips 3x8"
organs log "Weight 228.2"
organs log "Shipped tasks integration"Which appends to a file that has no fields at all, only a timestamp and whatever was said:
# 2026-08-30 (Sunday)
## Morning
- [10:06] ...
- [10:24] ...
The categories did not go away. Food, exercise, weight and work are all still there, and I can still ask for any of them. What moved is when the sorting happens.
The template does its sorting at write time, which is the worst available moment to ask for it. I am standing in a kitchen with one hand free, thinking about the food and not about the schema, and the system wants a decision about whether this belongs under Food or Expenses before it will accept anything. Get it wrong and the record is wrong, quietly, forever. The second version asks nothing at write time. It does the sorting when I go looking, which is a moment when I already know what I want, because wanting it is the reason I am there at all.
That is the difference between the two designs, and it is why only one of them survives contact with an ordinary day. A system that asks its hardest question at the point of least attention gets abandoned, however good the question is.
What it cost
I built it in 2025, and the version that ran taught me the thing six years of design documents had not.
"I am stacking too many things on top of my tracking system -- arbitrary logs -- and no views on it, I wanted it to be a habit tracker, a source of context for my AI, automated logger etc, but it has been a shitty version of all of them"
It reads like a complaint about arbitrary logging, and it is not. Arbitrary logging was the part I had right. A single store that accepts anything is the correct foundation, and it is the same append only shape I had admired in a bank statement. The failure is in the four words at the end. I stopped at the store, and then asked the store itself to behave like a habit tracker and a context source and an automated logger, when each of those is a different reading of the same data and should have been a separate narrow view sitting on top of it. Which is the 2019 bullet again: many individual tools, one synchronized store.
There was a second finding underneath, and it is the one I have used most since:
"The intelligence is there, but it has to be parameterized with the proper amount of configuration, and the incredible span of the possible design space of prompts makes it very frustrating to do so."
The model could do the job. What it needed was configuration, and configuration cannot be derived at a desk, because the hard cases and the edge cases only appear when a real person puts real sentences in. I had written the same thing in 2019 about paper, in almost the same words, and the fact that I had to learn it twice, once about a manual system and once about a model, is the most useful thing in this whole story.