Why I Ditched Taskwarrior - Arthur Dick

Saturday, July 12th, 2025

In the world of command-line productivity, one tool stands as a titan: Taskwarrior. It's a powerhouse of features, offering sophisticated filtering, tagging, project management, and a rich ecosystem of extensions. When I set out to build my own system, Perennial Task, I knew I wasn't creating a "Taskwarrior killer." I was building something to solve the specific workflow problems I had that Taskwarrior, for all its might, couldn't fix.

The single biggest point of friction, and the primary reason Perennial Task exists, is my philosophical disagreement with how Taskwarrior handles recurring tasks. It’s a subtle difference in logic that has a massive impact on how you manage the routine chores of life.

Taskwarrior: The Power and the Paradox

First, credit where it's due. Taskwarrior is brilliant. Its ability to slice and dice your task list is unparalleled. You can add tasks with metadata galore:

$ task add Pay credit card bill project:Finances +bill due:eom recur:monthly

You can then generate complex reports, view tasks in different contexts, and integrate it with everything from calendars to bug trackers. Its power lies in its structured, database-like approach to your to-do list.

This structure, however, is what creates a paradox in its recurring task model. When you set a task to recur, you are essentially creating a template. When you mark a recurring task as done, Taskwarrior does the following:

  1. It marks the current task as completed (or deletes it, depending on configuration).
  2. It generates a brand new task based on the original template, calculating the new due date from the previous due date.

This is a schedule-based approach. If a task recurs weekly and was due on Monday, completing it on Wednesday still results in the next task being due the following Monday. The schedule is rigid, which is perfect for some scenarios, but deeply flawed for others.

The Recurring Task Dilemma: Schedule vs. Interval

In the real world, not all recurring tasks are the same. They generally fall into two categories:

  1. Schedule-Based Tasks: These are tied to a specific day or date. Examples include "Take out the trash every Tuesday night" or "Publish the weekly report every Friday." The timing is fixed. Taskwarrior excels at this.

  2. Interval-Based Tasks: These should occur after a certain amount of time has passed since the last time you did them. Examples include "Change the furnace filter every 90 days," "Get a haircut every 6 weeks," or "Check the mail every 7 days."

The due date for an interval-based task is relative to its last completion. If you get your haircut a week late, you don't need another one in 5 weeks; you need one in 6 weeks from the day you got it cut.

This is where Taskwarrior's model breaks down for me. If my "Check Mail" task (set to recur every 7 days) was due on Monday and I don't complete it until Thursday, Taskwarrior creates the next task due the next Monday. The system now thinks I only have four days until it's due again. Worse, if you miss a daily task for a week, you're greeted with a backlog of seven identical, overdue tasks you have to manually clean up. This isn't helpful; it's a nuisance that creates more administrative work.

The Perennial Task Approach: Simple and Stateful

I designed Perennial Task to handle interval-based chores flawlessly. It uses a stateful model instead of a template-based one. The task is a single, persistent entity, not a disposable template.

My recurring task for checking my mail is a simple XML file:

<?xml version="1.0"?>
<task>
  <name>Check Mail</name>
  <recurring>
    <completed>2025-06-29</completed>
    <duration>7</duration>
  </recurring>
</task>

The logic is beautifully simple: the next due date is always <completed> + <duration>.

The workflow is therefore adapted to reality:

  1. My daily prn report call checks the file. It sees the task was last completed on 2025-06-29, so it calculates the due date as 2025-07-06.
  2. If today is past July 6th, the task appears in my task report as OVERDUE.
  3. When I complete the task, I run prn complete and select it.
  4. The script asks me when I completed it. I can press Enter for today's date.
  5. It then updates the <completed> tag in that same file.

If I complete the task on July 11th (5 days late), the <completed> tag becomes 2025-07-11. The next due date is now correctly calculated as July 18th. The 7-day interval resets from the moment of completion. The schedule adapts to my actions.

Head-to-Head: A Practical Comparison

Let's put the two systems side-by-side with a clear scenario.

Scenario: A task to "Charge Car Booster Pack" recurs every 62 days.

ActionTaskwarriorPerennial Task
Status
ID Age   Due        Urg   Description
 1 4d    2025-08-11 12.0  Charge Car Booster Pack
OVERDUE: Charge Car Booster Pack (was due 4 days ago)
CompletionRun task <id> done.Run prn complete, select the task, and confirm today's date (Aug 15).
ResultA new task is created. Its due date is calculated from the original due date (Aug 11 + 62 days), making it due on October 12th.The same task file is updated. The <completed> date is now Aug 15. The next due date is calculated from completion (Aug 15 + 62 days), making it due on October 16th.
OutcomeThe system ignores your 4-day delay, pulling the schedule back into its rigid alignment.The system adapts the schedule to reflect reality. The 62-day interval is preserved perfectly.

The Right Tool for the Right Job

Taskwarrior is not a bad tool; it is an exceptional one for managing complex, schedule-driven projects. Its design philosophy prioritizes a strict adherence to a pre-defined plan.

Perennial Task, on the other hand, is designed with a different philosophy. It believes that for the routine, interval-based chores of life, the plan must adapt to human reality. It prioritizes maintaining the integrity of the interval over the integrity of a fixed schedule.

For me, this small change in logic makes all the difference. It turns my task manager from a rigid overlord that creates cleanup work into a flexible assistant that understands the ebb and flow of daily life. Building Perennial Task taught me that sometimes, the most powerful solution isn't the one with the most features, but the one with the right philosophy for the job at hand.

Tags: productivityworkflow design

← Automating My LifeBlog Index ↑