Blog

Parent-Child Tasks: Master Project Hierarchies and Subtask Management

2026-01-23 · 13 min read · To-Track Team

Real projects aren't flat lists—they're hierarchies. "Launch website" breaks down into design, development, content, and testing. Each of those splits further: homepage design, about page design, blog template. And deeper still: wireframes, mockups, final designs.

Flat task lists force you to fake hierarchy with indentation, prefixes, or tags:

  • "Launch Website - Design"
  • "Launch Website - Design - Homepage"
  • "Launch Website - Design - About Page"

This is tedious, error-prone, and doesn't capture relationships. When the parent project is cancelled, you manually find and close every child task. When a child task activates, the parent's status doesn't reflect that work has started.

Parent-child task systems make hierarchy explicit:

  • Tasks have formal parent-child relationships
  • Visual tree structure shows dependencies
  • State changes cascade logically (close parent → close active children)
  • Project rollup becomes possible (total time spent = sum of child task times)

To-Track's parent-child system goes beyond basic subtasks with:

  • Automatic cascading state changes (close parent → close children, activate child → activate parent)
  • Circular reference prevention (can't set a child as parent of its ancestor)
  • Hierarchy visualization (task history timeline shows parent-child relationships)
  • Flexible depth (unlimited nesting levels)

This guide explains how to organize complex projects with parent-child tasks and leverage cascading logic for automatic workflow management.

Core Concepts

Parent Tasks

Top-level tasks representing projects, epics, or collections of work.

Examples:

  • "Website Redesign"
  • "Q1 Marketing Campaign"
  • "Thesis Research"
  • "Home Renovation"

Properties:

  • Can have multiple child tasks
  • Can also be a child of another task (nested hierarchy)
  • Closing a parent cascades to active children

Child Tasks

Subtasks that belong to a parent.

Examples (for parent "Website Redesign"):

  • "Design homepage mockup"
  • "Implement contact form"
  • "Write about page copy"
  • "Set up hosting"

Properties:

  • Have exactly one parent (or none)
  • Activating a child activates parent (if parent isn't already active)
  • Closing all children doesn't automatically close parent (manual decision)

State Cascading Rules

To-Track implements intelligent cascading to keep hierarchy consistent:

Rule 1: Close Parent → Close Active Children

  • When parent moves to CLOSED state (DONE, CANCELLED, ARCHIVED)
  • Active children (IN-PROGRESS, REVIEW, BLOCKED, etc.) also close
  • Open children (TODO, BACKLOG) remain unchanged

Why: Closing a project should close in-progress work, but preserve unstarted tasks (maybe they'll be useful later).

Rule 2: Activate Child → Activate Parent

  • When child moves to ACTIVE state (IN-PROGRESS, etc.)
  • If parent is OPEN, it also moves to ACTIVE
  • If parent already ACTIVE, no change

Why: Starting work on a subtask means the project is now in progress.

Rule 3: Deactivate Parent → Deactivate Active Children

  • When parent moves from ACTIVE to OPEN (e.g., IN-PROGRESS → TODO)
  • Active children also move to an OPEN state
  • Open children remain unchanged
  • Closed children remain closed

Why: Pausing a project should pause in-progress subtasks.

Rule 4: Target State Unavailable → First Available State

  • If cascading tries to move a task to a state it can't enter (due to tag requirements)
  • Task moves to the first available state in the target category instead

Example: Parent closes to CANCELLED, but child doesn't have required tags for CANCELLED state → child moves to DONE (first available CLOSED state).

Creating Parent-Child Relationships

Method 1: Assign Parent When Creating Child

  1. Create new task (tap + button)
  2. Fill in task details (name, tags, dates, etc.)
  3. Scroll to "Parent Task" section
  4. Tap "Select Parent Task"
  5. Modal opens showing available parent tasks
  6. Search or browse to find parent
  7. Tap parent to select
  8. Save task

Result: Task is created with parent relationship.

Visual indicator: Task detail page shows parent task name under "Parent Task" section.

Method 2: Add Children to Existing Parent

  1. Open parent task (tap to view detail page)
  2. Scroll to "Child Tasks" section
  3. Tap "Add Child Tasks" (if no children) or "Manage Child Tasks"
  4. Modal shows:
    • Selected child tasks (currently assigned) at top
    • Available tasks (orphaned tasks you can add) at bottom
  5. Tap an available task to add as child
  6. Tap a selected task to unassign (remove relationship)
  7. Changes save automatically when closing modal

Result: Child tasks appear in "Child Tasks" section of parent.

Method 3: Create New Child from Parent Context

  1. Open parent task
  2. Scroll to "Child Tasks" section
  3. Tap "Manage Child Tasks"
  4. In the modal, tap "Create New Child" button
  5. New task popup opens with parent pre-filled:
    • Parent task: Set to current parent automatically
    • Tags: Inherited from parent (editable)
    • Start/End times: Inherited from parent (editable)
    • Repeat rule: Inherited from parent (editable)
  6. Modify details as needed
  7. Save to create child task

Result: New task created with parent relationship and inherited attributes.

Why inheritance: Child tasks often share parent's tags, timeline, and recurrence—pre-filling saves time.

Hierarchy Visualization

To-Track displays parent-child relationships in multiple places:

Task Detail Page

Parent Task Section:

  • Shows parent task name (if assigned)
  • Tap to navigate to parent's detail page

Child Tasks Section:

  • Lists all child tasks using SelectableTodoItem design
  • Shows task name, state, and state color
  • Tap task to navigate to child's detail page (tap navigation currently disabled)
  • Displays state colors for visual status at a glance

Task History Timeline

  • Shows when child tasks were added
  • Displays when parent-child relationships changed
  • Visual indicator (icon + description) for hierarchy events

List View (Future Enhancement)

Currently, list view shows flat task list. Future updates may add:

  • Indented child tasks under parents
  • Collapsible/expandable project hierarchies
  • Visual tree structure

Use Cases & Examples

Use Case 1: Software Project

Parent: "Build Mobile App"

Children:

  • "Design UI mockups" (state: IN-PROGRESS)
  • "Set up backend API" (state: TODO)
  • "Implement user authentication" (state: BLOCKED)
  • "Write unit tests" (state: TODO)
  • "Submit to App Store" (state: TODO)

Scenario: Project gets cancelled (client pulls budget).

Action: Mark parent as CANCELLED.

Cascading result:

  • "Design UI mockups" → CANCELLED (was ACTIVE)
  • "Set up backend API" → remains TODO (was OPEN)
  • "Implement user authentication" → CANCELLED (was ACTIVE)
  • "Write unit tests" → remains TODO (was OPEN)
  • "Submit to App Store" → remains TODO (was OPEN)

Benefit: One action closes in-progress work, preserving unstarted tasks for potential future use.

Use Case 2: Content Creation

Parent: "Write Blog Post Series on AI"

Children:

  • "Research AI task generation" (state: DONE)
  • "Draft post 1: Introduction" (state: IN-REVIEW)
  • "Draft post 2: Use cases" (state: TODO)
  • "Draft post 3: Implementation" (state: TODO)
  • "Create social media graphics" (state: TODO)

Scenario: You start drafting post 2.

Action: Move "Draft post 2: Use cases" to IN-PROGRESS.

Cascading result:

  • Parent "Write Blog Post Series on AI" → IN-PROGRESS (was TODO, now activated by child)

Benefit: Parent automatically reflects that work is ongoing.

Use Case 3: Event Planning

Parent: "Plan Company Retreat"

Nested hierarchy:

  • Parent: "Plan Company Retreat"
    • Child: "Book Venue" (state: DONE)
    • Child: "Organize Activities"
      • Grandchild: "Research team building activities" (state: IN-PROGRESS)
      • Grandchild: "Book hiking guide" (state: TODO)
      • Grandchild: "Reserve kayaks" (state: TODO)
    • Child: "Arrange Catering" (state: IN-PROGRESS)
    • Child: "Send Invitations" (state: TODO)

Scenario: Client decides to pause retreat planning indefinitely.

Action: Mark parent "Plan Company Retreat" as TODO (move from IN-PROGRESS to OPEN).

Cascading result:

  • "Organize Activities" → TODO (was ACTIVE, deactivated)
    • "Research team building activities" → TODO (grandchild also deactivated)
    • "Book hiking guide" → TODO (already OPEN, no change)
    • "Reserve kayaks" → TODO (already OPEN, no change)
  • "Arrange Catering" → TODO (was ACTIVE, deactivated)
  • "Send Invitations" → TODO (already OPEN, no change)

Benefit: Entire project hierarchy pauses with one action.

Use Case 4: Personal Goal with Subtasks

Parent: "Learn Spanish (A2 Level)"

Children:

  • "Complete Duolingo lessons" (state: IN-PROGRESS, recurring: any-time)
  • "Watch Spanish TV shows 3x/week" (state: IN-PROGRESS, recurring: scheduled)
  • "Read Spanish news articles" (state: TODO, recurring: any-time)
  • "Practice with language partner" (state: BLOCKED, note: "Need to find partner")
  • "Take A2 certification exam" (state: TODO, end date: June 30)

Scenario: You achieve A2 certification early (May 15).

Action: Mark parent "Learn Spanish (A2 Level)" as DONE.

Cascading result:

  • "Complete Duolingo lessons" → DONE (was ACTIVE)
  • "Watch Spanish TV shows 3x/week" → DONE (was ACTIVE)
  • "Read Spanish news articles" → remains TODO (was OPEN)
  • "Practice with language partner" → DONE (was ACTIVE, even though BLOCKED)
  • "Take A2 certification exam" → remains TODO (was OPEN, you completed early without the exam)

Benefit: Closes active work, preserves unstarted tasks in case you continue learning.

Advanced Features

Circular Reference Prevention

To-Track prevents creating loops where A is parent of B, and B is parent of A.

How it works:

  • When selecting a parent for task X, the system excludes:
    • Task X itself (can't be your own parent)
    • All descendants of task X (children, grandchildren, etc.)

Example:

Task A (parent)
  ├─ Task B (child of A)
     └─ Task C (child of B, grandchild of A)

If you try to set Task C as parent of Task A, the system rejects it (would create a loop).

Implementation:

  • getRootAncestorId(taskId): Traverses hierarchy upward to find root
  • Infinite loop protection: Stops after 100 iterations (should never happen)

Orphaned Task Queries

Orphaned tasks: Tasks with no parent_id and no children.

Use case: When selecting available parents, exclude tasks that are descendants of the child (prevents loops).

Query: getOrphanedTodos({excludeId: childTaskId})

  • Returns tasks with parent_id IS NULL
  • Excludes root ancestors of the excluded task

Root Ancestor Calculation

Root ancestor: The top-most task in a hierarchy.

Algorithm:

1. Start with task ID
2. Query for parent_id
3. If parent exists, repeat from step 2 with parent's ID
4. If no parent, current task is root
5. Return root ID

Use: Prevents assigning a descendant as parent (check if candidate parent's root is the child task itself).

Best Practices

1. Keep Hierarchies 2-3 Levels Deep

Optimal:

Project (parent)
  ├─ Phase 1 (child)
     ├─ Task 1.1 (grandchild)
     └─ Task 1.2 (grandchild)
  └─ Phase 2 (child)
     ├─ Task 2.1 (grandchild)
     └─ Task 2.2 (grandchild)

Too deep (hard to navigate):

Project
  └─ Phase
     └─ Sub-phase
        └─ Work package
           └─ Activity
              └─ Task
                 └─ Subtask (7 levels!)

Guideline: 3 levels = sweet spot for most projects.

2. Use Tags for Cross-Cutting Concerns

Don't use parent-child for categorization—use tags:

Wrong (parent-child for categorization):

Work (parent)
  ├─ Task A
  └─ Task B
Personal (parent)
  ├─ Task C
  └─ Task D

Right (tags for categorization):

Website Project (parent)
  ├─ Design homepage (tag: work, design)
  └─ Write copy (tag: work, content)

Home Renovation (parent)
  ├─ Paint living room (tag: personal, diy)
  └─ Install shelves (tag: personal, diy)

Why: Tasks belong to projects (parent-child), but have attributes (tags).

3. Set Parent When Creating Child

If you know a task is a subtask, assign the parent immediately:

  • Avoids orphaned tasks
  • Ensures cascading logic applies from the start
  • Inherits parent attributes (tags, dates, repeat rules)

4. Review Child Tasks Before Closing Parents

Before marking a parent DONE or CANCELLED, review child tasks:

  • Check for valuable open children (preserve them?)
  • Ensure active children should close
  • Manually close children you don't want cascaded (to control which state they end in)

Why: Cascading is automatic—once you close the parent, active children close too. Make sure that's what you want.

5. Use Parent-Child for Sequential Dependencies

When task B can't start until task A finishes:

Option 1: Make B a child of A (if A is a project) Option 2: Use BLOCKED state + note ("Waiting for task A")

Guideline: Parent-child works best for "belongs to" relationships, not just "depends on" relationships.

Comparing Parent-Child Systems

Feature To-Track Todoist Things 3 Notion
Parent-child support ✅ Formal relationships ⚠️ Projects/sections ⚠️ Headings (visual only) ✅ Relational databases
Unlimited nesting ✅ Yes ⚠️ Projects → sections → tasks (3 levels) ⚠️ Projects → headings → tasks (3 levels) ✅ Yes
Cascading state changes ✅ Automatic ❌ No ❌ No ⚠️ Manual formulas
Activate child → activate parent ✅ Yes ❌ No ❌ No ⚠️ Manual
Close parent → close children ✅ Configurable (active only) ❌ Manual ❌ Manual ⚠️ Manual
Circular reference prevention ✅ Built-in N/A (no formal parent-child) N/A ⚠️ Manual checks
Visual hierarchy ⚠️ Detail page only ✅ List view ✅ List view ✅ Database views
Inherit parent attributes ✅ Tags, dates, repeat rules ❌ No ❌ No ⚠️ Formulas

Verdict: To-Track's cascading logic is unique and powerful, though visual hierarchy in list view lags competitors (future enhancement planned).

Limitations & Considerations

Current Limitations

No list view hierarchy: Child tasks appear as flat items in the main list, not indented under parents.

  • Workaround: Use tags to group related tasks
  • Future: Collapsible parent-child trees in list view

No auto-close parent when all children close: Closing all children doesn't automatically close the parent.

  • Reasoning: User should explicitly decide when a project is "done" (maybe you want to add more children)
  • Workaround: Manually review and close parent when ready

No dependency chains: Cascading only goes one level (parent → child or child → parent), not through entire hierarchy.

  • Example: Great-grandparent closes → cascades to grandparent → cascades to parent → cascades to child (only first two levels cascade)
  • Workaround: Manually close deeply nested hierarchies if needed

When NOT to Use Parent-Child

Don't use for:

  • Simple tagging: Use tags instead ("work", "personal")
  • Loose associations: "Related to project X" → use tags
  • Linear dependencies: "Task B after Task A" → use BLOCKED state + note

Do use for:

  • True decomposition: Project breaks into parts
  • Ownership: "This subtask belongs to this project"
  • Cascading logic: You want automatic state syncing

Conclusion: Organize Complexity with Hierarchy

Flat task lists fail for complex projects. Parent-child relationships bring structure:

  • Decompose large projects into manageable pieces
  • Visualize relationships between tasks
  • Automate state changes with cascading logic
  • Inherit attributes for faster child creation

To-Track's parent-child system goes beyond basic subtasks with intelligent cascading:

  • Close parent → close active children (but preserve open children)
  • Activate child → activate parent (projects start when work starts)
  • Deactivate parent → deactivate children (pause projects gracefully)

Whether you're managing software sprints, content calendars, event planning, or personal goals, parent-child tasks transform chaos into organized hierarchies.

Stop flattening your projects. Start organizing them with parent-child tasks.

FAQ

Q: Can a task have multiple parents? A: No—each task has at most one parent. For tasks that belong to multiple projects, use tags instead.

Q: What happens if I delete a parent task? A: Child tasks remain (they don't get deleted), but their parent_id becomes null (orphaned). You can reassign them to a new parent or leave them standalone.

Q: Can I move a child to a different parent? A: Yes. Open the child task, tap "Parent Task" section, select a different parent (or "None" to remove parent relationship).

Q: Do grandchildren cascade when closing a parent? A: Only direct children cascade. If you close a parent, its children close (if active), but grandchildren are not affected directly. However, if a child closes and has its own children, those grandchildren would cascade based on the child's closure.

Q: Can I prevent cascading for specific tasks? A: Not currently. Cascading is automatic based on state categories. If you don't want a child to close, manually reopen it after the parent closes.

Q: How do I see all tasks in a project hierarchy? A: Create a custom list filtering by the parent task ID or use a shared tag across all related tasks.

Q: Can parent-child relationships cross between recurring and non-recurring tasks? A: Yes, but be cautious. If a parent is recurring and resets, children remain as-is (they don't reset). This can create orphaned children over time.

Q: What's the maximum nesting depth? A: Unlimited technically, but 3-4 levels are recommended for usability.


Ready to organize complex projects? Download To-Track and master parent-child task hierarchies with intelligent cascading logic.

Try To-Track free

Offline-first tasks, custom states, time tracking. No account required.

Download for iOS