As some of you may know, I practically live inside Emacs. And like a lot of Emacs users a good portion of that time is spend in org-mode, a package that is hard to describe due to its overwhelming large number of features.

One of the many ways I use org-mode is to implement a Getting Things Done (GTD) workflow. That is, managing all of the projects that I’m trying to push forward as well as all of the routine recurring tasks that I have to deal with on a daily basis.

The issue that every org-mode user eventually has to wrestle with is what to do with all those completed projects and obsolete tasks. For some projects the obvious answer is to simply delete them. This is especially true if you’re using a version control system to track your org-mode files. But if you regularly need to refer to completed projects/tasks (i.e. “what was that crazy query I ran last time?”) then archiving is a better option.

Archiving Options in org-mode

In org-mode, archiving is the process of moving a subtree somewhere else when it’s no longer needed1. The destination for an archived subtree is taken from the org-archive-location variable.

By default, org-mode will move the subtree to another file whose name is derived from the name of the current file by appending “_archive” to the name, but before the extension. That said, like everything in Emacs, the options for configuring the archive destination are virtually limitless.

A really common way to configure archiving is to use a dedicated file, usually Whether you use a single archive file or the default strategy of using a file named after the current one, you will ultimately run into the same problem, huge unwieldy org-mode files.

I think there’s a better way to archive projects and tasks: use a lot of small files. Specifically, when I archive a subtree in org-mode I send the subtree to the current day’s journal entry.

Using the org-roam Journal

I maintain my personal knowledge base in org-mode thanks to org-roam. One of its features is the ability to manage journal entries. The journal system in org-roam is simply a collection of subtrees in a one-file-per-day organization scheme. In other words, each day gets a new org-mode file and throughout the day I add headings to the file in order to record certain events.

When I archive a subtree from somewhere in my vast collection of notes, org-mode stores it in one of my journal files. The specific journal file used is based on the date chosen from a prompt when I run the following archiving function:

(defun pjones:org-archive-subtree-to-daily (&optional _find-done)
  "Arhive the current subtree to the roam daily file."
  (require 'org-roam)
  (when-let* ((today (save-excursion
                       (org-roam-dailies-goto-date nil "d")
               (concat today "::* Archived From %s")))
    (org-archive-subtree 0)))

You can tell org-mode that you want this to be your archiving function by setting org-archive-default-command:

  '(org-archive-default-command #'pjones:org-archive-subtree-to-daily))

After which you can archive the current subtree with the normal key binding “C-c C-x C-a”. This leaves “C-c C-x C-s” alone if you want to use the built in system which relies on org-archive-location.

(Note: I have both daily and monthly journal files. To avoid being asked which one I want to archive to I pass “d” as the second argument to org-roam-dailies-goto-date. This bypasses the prompt and goes directly to the daily journal file.)


I find it easier to manage many small files verses a small number of huge files. To avoid a massive file I archive subtrees into my org-roam journal. This makes it a lot easier to find what I’m looking for and provides a bit of context when found. And it pairs perfectly with rg-project and consult-ripgrep.

  1. You can also tag the current subtree with the ARCHIVE tag which darkens the heading and keeps the tree collapsed. This can be done with the org-toggle-archive-tag function or the “C-c C-x a” key binding. ↩︎