Chapter 7: Tags and Properties - The Metadata Layer
You’ve organized your tasks. Now let’s make them searchable, filterable, and queryable. Tags and properties are Org-Mode’s metadata system—the layer that transforms static lists into a dynamic, searchable knowledge base.
1. Tags: Categorization with Colons
Tags attach labels to headings:
#+begin_example
2. TODO Fix authentication bug urgent bug security
3. Meeting notes from client call meeting client acme
4. Ideas for next sprint planning ideas
5. DONE Implement user dashboard feature frontend done
#+end_example
Tags appear at the end of the heading line, wrapped in colons. One tag looks like :tag:, multiple tags like :tag1:tag2:tag3:.
5.1. Adding Tags
Don’t type them manually. Press C-c C-c on a heading:
- Org prompts:
Tags: - Type tag names (with completion if configured)
- Press Enter
Or use C-c C-q for the same effect (mnemonic: “q” for taQ).
Tags are case-sensitive. :Work: and :work: are different. Choose a convention and stick with it (lowercase recommended).
5.2. Tag Inheritance
By default, tags inherit. A child heading has all its parent’s tags:
#+begin_example
6. Project Alpha work client_a
6.1. TODO Design phase design
6.2. TODO Development phase development
#+end_example
“Design phase” effectively has tags :work:client_a:design:. “Development phase” has :work:client_a:development:. You don’t repeat common tags—inheritance handles it.
Disable inheritance if needed:
(setq org-use-tag-inheritance nil)
Or disable for specific tags:
(setq org-tags-exclude-from-inheritance '("project" "personal"))
6.3. Predefined Tags
Typing tags gets tedious. Predefine common ones:
(setq org-tag-alist '(("work" . ?w) ("personal" . ?p) ("urgent" . ?u) ("email" . ?e) ("phone" . ?h) ("meeting" . ?m)))
Now when you press C-c C-c to add tags, Org shows a selection interface. Press w for “work”, u for “urgent”, etc. Much faster than typing.
Group related tags:
(setq org-tag-alist '((:startgroup . nil) ("@office" . ?o) ("@home" . ?h) ("@errands" . ?e) (:endgroup . nil) (:startgroup . nil) ("urgent" . ?u) ("someday" . ?s) (:endgroup . nil)))
Groups are mutually exclusive. Adding @office removes @home and @errands. Perfect for context tags (GTD-style).
6.4. Per-File Tags
Set tags available in specific files:
#+TAGS: work(w) personal(p) urgent(u)
#+TAGS: { @office(o) @home(h) @errands(e) }
The {} creates a mutually exclusive group (same as :startgroup: in elisp).
6.5. File-Level Tags
Apply tags to the entire file:
#+FILETAGS: :project_alpha:confidential:
Every heading in the file inherits these tags. Useful for project-specific files.
7. Searching by Tags
The power of tags emerges when searching.
7.1. Tag Sparse Trees
C-c / m - Show headings matching tag query
Examples:
work- All headings tagged “work”work+urgent- Both “work” AND “urgent”work|personal- Either “work” OR “personal”work-boss- Tagged “work” but NOT “boss”work+urgent-meeting- Work AND urgent, but NOT meeting
The document folds to show only matches. Combined with tag inheritance, this is phenomenally powerful.
7.2. Tag Agenda Searches
From the agenda (covered in Chapter 8):
C-c a m - Match tags across all agenda files
Your entire Org system becomes searchable by arbitrary tag combinations.
8. Properties: Structured Metadata
Tags are simple labels. Properties are key-value pairs for structured data:
#+begin_example
9. TODO Implement new feature
#+end_example
Properties live in a :PROPERTIES: drawer. Each property is a key-value pair.
9.1. Adding Properties
C-c C-x p - Set a property
Org prompts for property name, then value. The property drawer auto-creates if needed.
9.2. Special Properties
Some properties have special meaning:
EFFORT- Time estimate (used in agenda views)CATEGORY- Category for agenda displayORDERED- If t, children must be completed in orderCUSTOM_ID- For stable linking (Chapter 5)ID- Unique identifier
Others are custom metadata you define.
9.3. Property Inheritance
Like tags, properties can inherit:
#+begin_example
10. Project: Website Redesign
10.1. TODO Design mockups
10.2. TODO Implement frontend
#+end_example
If CLIENT is set to inherit, all subtasks automatically have CLIENT: ACME Corp.
Configure inheritance:
(setq org-use-property-inheritance '("CLIENT" "PROJECT_CODE"))
Or inherit all properties (be careful—this can slow down large files):
(setq org-use-property-inheritance t)
10.3. Allowed Property Values
Constrain property values for consistency:
#+PROPERTY: ASSIGNED_ALL Alice Bob Carol Dave #+PROPERTY: STATUS_ALL Open In-Progress Blocked Completed #+PROPERTY: PRIORITY_ALL Low Medium High Critical
Now when setting these properties, Org offers completion from the allowed values. No typos, no inconsistent data.
In elisp:
(setq org-global-properties '(("ASSIGNED_ALL" . "Alice Bob Carol Dave") ("STATUS_ALL" . "Open In-Progress Blocked Completed")))
10.4. Column View: Spreadsheet of Properties
View properties as a table:
C-c C-x C-c - Enable column view
Org displays headings with their properties in columns:
ITEM | ASSIGNED | EFFORT | STATUS --------------------------------------------------- Implement feature | Alice | 4:00 | In-Progress Write tests | Bob | 2:00 | Open Deploy | Carol | 1:00 | Blocked
Edit properties directly in the column view. Press q to exit.
Define which columns to show:
#+COLUMNS: %25ITEM %ASSIGNED %EFFORT %STATUS
Or globally:
(setq org-columns-default-format "%25ITEM %TODO %3PRIORITY %TAGS %EFFORT")
Column view transforms Org files into databases with editable spreadsheet views.
10.5. Dynamic Blocks: Property Tables
Create property summaries:
#+BEGIN: columnview :hlines 1 :id local #+END:
Place cursor on #+BEGIN: line and press C-c C-c. Org generates a table from properties:
#+BEGIN: columnview :hlines 1 :id local | ITEM | ASSIGNED | EFFORT | STATUS | |-------------------+----------+--------+-------------| | Implement feature | Alice | 4:00 | In-Progress | | Write tests | Bob | 2:00 | Open | | Deploy | Carol | 1:00 | Blocked | #+END:
Update properties and regenerate with C-c C-c. The table auto-updates.
Generate reports this way:
- Task assignment by person
- Effort summaries by project
- Status overviews
Plain text becoming a database before your eyes.
11. Property Searches
Search by property values:
C-c / p - Property sparse tree
Enter property name and value. Org shows matching headings.
11.1. Advanced Property Searches
Tag/property search syntax (C-c / m or C-c a m):
+work-boss+CLIENT="ACME Corp"+EFFORT>2:00
Translation: Tagged “work”, not “boss”, CLIENT property equals “ACME Corp”, and EFFORT greater than 2 hours.
Operators:
=- Equals<>- Not equal<- Less than>- Greater than<=- Less than or equal>=- Greater than or equal
For numbers, times, and dates. For strings, use =.
Regular expressions:
CLIENT={acme|widgets}
Matches CLIENT containing “acme” or “widgets”.
This is query language built into plain text.
12. Combining Tags and Properties
Tags for broad categories, properties for specific metadata:
#+begin_example
13. TODO Implement payment processing feature backend urgent
#+end_example
Now you can query:
- “All backend features” (tag search)
- “All tasks for FinTech Startup” (property search)
- “Urgent tasks assigned to Alice requiring more than 4 hours” (combined search)
The metadata layer makes everything discoverable.
14. Practical Tag Systems
14.1. GTD-Style Contexts
(setq org-tag-alist '((:startgroup) ("@office" . ?o) ("@home" . ?h) ("@computer" . ?c) ("@phone" . ?p) ("@errands" . ?e) (:endgroup) ("work" . ?w) ("personal" . ?r)))
Tag tasks by where they can be done. Filter your task list by current context.
14.2. Project-Based
#+begin_example
15. Tasks
15.1. TODO Design
#+end_example
All tasks inherit project context.
15.2. Energy Levels
(setq org-tag-alist '((:startgroup) ("@high_energy" . ?h) ("@low_energy" . ?l) (:endgroup)))
Tag tasks by required energy. When you’re tired, filter for low-energy tasks.
15.3. Work Breakdown Structure
#+begin_example
16. Project: Website Redesign
16.1. Phase 1: Discovery phase discovery
16.2. Phase 2: Design phase design
16.3. Phase 3: Development phase development
#+end_example
Track budgets, phases, and allocation through properties. Report with column view.
17. Property Clocking Summaries
Combined with time tracking (Chapter 9), properties enable powerful reports:
#+BEGIN: clocktable :scope file :maxlevel 2 :properties ("CLIENT" "PROJECT")
#+END:
Generate time reports grouped by client or project. Send invoices from plain text files. It’s absurd and brilliant.
18. Bulk Property Operations
Need to tag 20 items at once?
- In agenda view (Chapter 8), mark multiple items
Bfor bulk actionsto add tags or properties- Enter tags/properties
- All marked items update
Metadata at scale.
19. Your Exercise
- Create a file with at least 10 tasks
- Define a set of common tags (work, personal, contexts, etc.)
- Tag all your tasks appropriately
- Add properties to at least 5 tasks (effort, assignment, client, etc.)
- Practice tag searches with
C-c / m(try AND, OR, NOT combinations) - Try property searches with
C-c / p - Enable column view and edit properties in the spreadsheet interface
- Create a dynamic property table with columnview
20. The Philosophy of Metadata
Good metadata is the difference between a pile of notes and a knowledge system. Tags and properties transform your Org files from documents into databases—queryable, filterable, reportable.
The discipline is adding metadata consistently. The reward is finding exactly what you need, when you need it, across thousands of entries.
Start simple. Add a few tags. As your system grows, add more structure. The beauty of plain text: you can always add metadata retroactively.
21. Next: Agenda Views
You’ve got TODOs, tags, properties, and timestamps. Now let’s pull it all together. The Agenda is where Org-Mode’s true power manifests—a dynamic, customizable view of your entire task universe. Prepare to achieve inbox zero (well, maybe).