TL;DR: Most agency Notion setups fail because they're built as a pile of disconnected databases (one for clients, one for tasks, one for invoices) with no relationships between them. The 4-database setup below is the spine: Clients, Projects, Tasks, Time Entries, all related. Built right, it replaces Asana, ClickUp, and Harvest for an agency under 10 people. Built wrong, it becomes the database soup you bounce off of in week three.
I tried to run my agency in Notion three times before it stuck. The first attempt was one giant page with everything inline. The second was eight unrelated databases that I had to manually update in three places when anything changed. The third time I started with relationships and worked outward. That one stuck.
I'm Sammie Oku, founder of Eximius Studio, a web design and dev agency in Tyler, TX. This post is the 4-database setup I run Eximius on today. It replaces Asana for project management, replaces a separate CRM for client tracking, and replaces Harvest for time tracking. One workspace, one source of truth, no syncing.
For the bigger picture, how to run a web design agency covers the seven systems an agency operating system needs to support. Project management is the spine that holds them together.
Why most agencies fail at Notion project management (database soup)
The most common Notion failure pattern: 12 databases, none of them related, all of them requiring manual sync. You add a new client to the Clients database. You don't think to add a project for them. The next morning you can't remember whether they have a project active or not. You check three places. You give up. By month two, you're back in Asana.
The fix is to start with relationships first, content second. Four databases, all connected, in a hierarchy. Once the relationships exist, everything else (statuses, dashboards, custom views) becomes a question of filtering and rolling up.
The four databases:
- Clients (top of hierarchy)
- Projects (linked to a Client)
- Tasks (linked to a Project)
- Time Entries (linked to a Task and a Project)
That's it. Everything else (retainers, change orders, invoices, leads) either lives inside one of these four or links to them.
Database 1: Clients (one source of truth)
The Clients database is the parent. Every other database links back to it. Get this one right and the rest is downstream.
Properties (the columns):
- Name (Title) — Company name, not contact name
- Primary Contact (Text) — Single named decision-maker
- Email (Email) — Primary contact email
- Phone (Phone) — Primary contact phone
- Status (Select) — Lead / Active / Retainer / Paused / Churned
- Onboarding Date (Date) — When the engagement started
- Stripe Customer ID (Text) — For billing reference
- Industry (Select) — For filtering and case study tagging
- Time Zone (Select) — Avoids scheduling errors
- Notes (Text) — One-line note, not a novel
- Projects (Relation → Projects) — Auto-populated by Projects DB
- Retainers (Relation → Retainers) — Auto-populated
- Total Revenue (rollup) (Rollup from related Projects + Retainers) — Lifetime revenue
Page template (inside each client record):
When you click into a client record, the page itself has a structured template:
- Contacts — All people at the client company, with roles
- Access credentials — Where to find passwords (use a password manager link, never store actual credentials in Notion)
- Brand assets — Logo files, brand guidelines, photography location
- Communication log — Meeting notes, key decisions, important emails
- Linked projects — Auto-populated via relation
- Linked retainers — Auto-populated via relation
The page template is the single most important piece of the Clients database. Build it once. Every new client gets the same structure automatically. After three months you can navigate any client's page without thinking.
Database 2: Projects (linked to clients)
Projects are one-time engagements with a defined scope, timeline, and end date. Retainers (recurring engagements) live in their own database. Don't conflate them. The reason: project pricing is fixed-fee against a defined scope, while retainer pricing is recurring against hours or deliverables, and the underlying data models look different.
Properties:
- Name (Title) — Format: "[Client] — [Project Name]" (e.g., "Acme Co — Marketing Site Rebuild")
- Client (Relation → Clients) — Required
- Status (Select) — Discovery / Design / Build / QA / Launch / Warranty / Complete / Archived
- Phase (Select) — Current phase within Status
- Project Type (Select) — New Build / Redesign / Migration / Custom Dev / Brand
- Contract Value (Number, $) — Total project value
- Hours Budgeted (Number) — From the proposal
- Hours Used (rollup) (Rollup from Time Entries) — Auto-calculated
- Hours Remaining (formula) (Formula: Budgeted − Used)
- Start Date (Date)
- Target Launch (Date)
- Actual Launch (Date)
- Margin (formula) (Formula: revenue minus fully-loaded cost of hours used)
- Tasks (Relation → Tasks) — Auto-populated
- Change Orders (Relation → Change Orders) — Auto-populated. (For why every project needs a Change Order workflow, see how to stop scope creep.)
Page template inside each project:
- Scope summary — Bulleted list from the proposal
- Out of scope — What's explicitly excluded
- Kickoff notes — Meeting summary from the kickoff meeting
- Timeline — Milestone dates with current status (built off the 14-day onboarding checklist)
- Decisions log — Major decisions made and their date
- Linked tasks — Auto-populated via relation
- Risks and blockers — Live list, updated weekly
The Status field is where most agency setups go wrong. Use the same status options for every project, in a defined order. Don't let each project have its own custom statuses. Consistency lets you build a single dashboard that shows every project in flight.
Database 3: Tasks (linked to projects)
Tasks are individual units of work. Each task belongs to exactly one project. This is where you replace Asana.
Properties:
- Name (Title) — Verb-first task description (e.g., "Design homepage hero")
- Project (Relation → Projects) — Required
- Status (Select) — Backlog / In Progress / Review / Blocked / Done
- Assignee (Person) — Single owner per task
- Due Date (Date)
- Priority (Select) — Low / Medium / High / Urgent (use sparingly)
- Estimated Hours (Number)
- Actual Hours (rollup) (Rollup from Time Entries)
- Phase (Select) — Discovery / Design / Build / QA / Launch (matches Project phases)
- Dependencies (Relation → Tasks self-relation) — What blocks this task
- Time Entries (Relation → Time Entries) — Auto-populated
Views to build on the Tasks database:
- My Tasks — Filtered by Assignee = me, Status ≠ Done, sorted by Due Date
- This Week — Filtered by Due Date this week
- Blocked — Filtered by Status = Blocked (review weekly)
- By Project — Grouped by Project relation
- By Phase — Grouped by Phase
The "My Tasks" view is the one you'll open every morning. Make sure it loads in under 2 seconds. If it's slow, you have too many properties or filters. Trim.
Database 4: Time Entries (linked to tasks and projects)
This is the database most agencies skip. It's also the one that makes the entire system work for margin tracking, retainer reporting, and invoicing.
Properties:
- Description (Title) — What you did, in one sentence
- Project (Relation → Projects) — Required
- Task (Relation → Tasks) — Optional but recommended
- Date (Date) — When the work was done
- Hours (Number) — Time spent
- Billable (Checkbox) — Defaults to true; uncheck for internal work
- Hourly Rate (Number, $) — Pulled from the project or set manually
- Revenue (formula) (Hours × Rate)
- Team Member (Person) — Who did the work
- Logged Via (Select) — Manual / Timer / Imported
The discipline that makes this work: log time the same day, in 30-minute increments. Don't aim for perfect minute-tracking. Aim for consistent same-day logging. The discipline matters more than the precision.
Views to build:
- Today — Filtered by Date = today
- This Week — Grouped by Project, summed by Hours
- By Project — All time entries for each project, used for client billing
- Unbilled — Filtered by Billable = true and not yet on an invoice
- Goodwill — Filtered by Billable = false and Notes contains "absorbed scope"
The Goodwill view is the one from the margin leak post that tells you how much unbilled work you absorbed last month.
How the four databases connect
The hierarchy:
Clients (1)
└─ Projects (many per client)
└─ Tasks (many per project)
└─ Time Entries (many per task)
The relations flow both directions. From a Client record, you can see all their Projects. From a Project, you can see all its Tasks and Time Entries. From a Time Entry, you can navigate back up to the Task, Project, and Client.
Rollups push aggregated data up the hierarchy:
- Time Entries → Tasks: Actual Hours rollup
- Tasks → Projects: Hours Used rollup
- Projects → Clients: Total Revenue rollup, Active Project Count rollup
This is what makes margin per client calculable without any external tool. The Time Entry has the hours and the rate. The Project rolls them up. The Client rolls up across all projects. One Notion formula away from "this client has generated $X of revenue at Y% gross margin over the engagement."
The 5 views every PM dashboard needs
Build these views as a single dashboard page. This is where you actually run the agency.
1. Active Projects. Every project where Status ≠ Complete or Archived. Grouped by Status. Shows: project name, client, target launch, hours used vs. budgeted, current margin. This is the page you open Monday morning.
2. My Tasks (Today). Personal task view filtered to today's work. Sorted by priority then due date. Limit to 5 to 7 tasks visible. More than that is a planning problem.
3. Retainer Health. Every active retainer client. Shows hours used this month vs. allocated, renewal date, last report sent date. Flags retainers with renewal within 60 days.
4. AR Aging. Outstanding invoices grouped by age bucket (0 to 30, 31 to 60, 61 to 90, 90+). Anything past 30 days gets a follow-up note inline.
5. Weekly Margin Review. Time entries from the past 7 days, grouped by Project, showing total billable hours, billable revenue, and goodwill hours. This is the view that surfaces scope creep absorption in real time.
Bookmark this dashboard. Make it your Notion home page. Open it first every morning.
When Notion isn't enough (and when it is)
Notion handles agency project management well up to a clear ceiling. Past that ceiling, the friction starts costing more than the consolidation saves.
Notion is enough when:
- You're 1 to 10 people
- Revenue is under $1M annually
- You have under 30 active projects at any given time
- You're comfortable with manual time entry
- Reporting needs are internal, not enterprise-grade
Notion isn't enough when:
- You have 15+ people who need granular permissions
- You need automatic time tracking with start/stop timers across multiple tools
- Clients require platform-specific reporting (e.g., enterprise dashboards)
- You're running formal Agile with sprint velocity tracking
- You need deep integrations with accounting software for automatic invoice generation
Most web design agencies under $1M revenue land squarely in "Notion is enough" territory. The shift to Asana, Productive, or Scoro usually happens around the $1.5M to $2M revenue mark, often coinciding with the first non-founder hire on operations.
Migrating from Asana / ClickUp / Trello in one weekend
If you're moving from another tool, here's the 8-hour migration plan that works most of the time.
Hour 1: Build the four databases empty. Just structure, no data. Confirm the relations work.
Hour 2: Create the page templates. Client template, Project template, Task template. These will save you time on every future addition.
Hour 3 to 4: Migrate Clients. Export from your current CRM (or copy-paste manually if you only have 10 to 30 clients). Add only active clients. Don't migrate dead leads from 2022.
Hour 5 to 6: Migrate Projects. Active projects only. Same logic: leave finished and abandoned projects in the archive of the old tool. Don't carry dead weight into the new system.
Hour 7: Build the dashboard views. Active Projects, My Tasks, Retainer Health, AR Aging, Weekly Margin Review. Test that each one shows the right data.
Hour 8: Move yourself to Notion-only. Don't run two systems in parallel. Pick a date, switch, and force yourself to use only the new one. Two systems guarantees the new one fails.
The migration usually goes faster than expected if you stay disciplined about not importing everything. Start with active work only.
Building this from scratch is doable but slow. The 4-database structure, page templates, dashboard views, and roll-up formulas are inside Agency Operations OS, pre-built and ready to deploy. $79. Link at the end.
What this looks like in practice (a day in the workflow)
Monday 9 AM. Open the Active Projects dashboard. Scan: 4 projects in build phase, 1 in QA, 2 in design. Acme Co's hours used is at 78% of budgeted with 3 weeks to launch. Note to self: tight, watch for scope creep.
Monday 9:15 AM. Open My Tasks. 6 tasks for today. Start the highest-priority one.
Monday throughout the day. Every time I finish a task, I log a Time Entry with date, hours, project, task, and 1-sentence description. Takes 15 seconds per entry. By end of day, my time is logged.
Friday 4 PM. Weekly review. Open Margin Review view. Verify every project's hours used is in line with revenue. Check Retainer Health for any clients approaching renewal. Check AR Aging for invoices past 30 days. 30 minutes total.
Monthly (5th of the month). Retainer reports. The Retainer Health view shows hours used per client. The Project hours roll up from Time Entries. Writing the monthly retainer report takes 25 minutes per client because the data is already there.
That's the rhythm. No data entry happening twice. No syncing between tools. One place, one source of truth, no friction.
Frequently asked questions
Can Notion really replace Asana for an agency?
For agencies under 10 people, yes. Notion handles project management, client tracking, time entry, and reporting in one workspace. The tradeoff: less polish on pure task-management UX, no native Gantt charts (though timeline views work), and slower performance at very high task counts (5,000+ tasks per database starts to lag). Most small agencies never hit those limits.
How many databases should a Notion agency setup have?
Four is the minimum for project management: Clients, Projects, Tasks, Time Entries. Add three more for a full operating system: Retainers, Change Orders, Financials. Seven total. Beyond seven, you're usually duplicating data or building dashboards that should be views, not databases. If you're at 12+ databases, the system has become the work instead of supporting it.
Should I track time in Notion or use a separate tool?
If your agency is under 5 people and tracks time manually, Notion is fine. If you have 5+ people and need automatic timer-based tracking with integrations (Toggl, Harvest, Clockify), use the dedicated tool and sync into Notion via Zapier or Make. The break point is usually around 5 people, where manual logging breaks down because not everyone has the same discipline.
How do you handle client portals in Notion?
You don't, for most agencies. Most clients don't actually log into portals. Instead, share specific pages with the client (the Project Home page, the monthly report) using Notion's share-to-web with a password or member access. For agencies that want a true client portal experience, AGENCY OS on the Notion Marketplace is a better fit than building one from scratch.
What's the biggest mistake in Notion agency setups?
Building databases without relations. Most agencies create separate, disconnected databases that require manual sync to stay aligned. Within two months, the system has drifted: clients in the Clients DB don't match projects in the Projects DB, time entries don't roll up to anything useful, and you've reverted to Asana. The fix is to start with the hierarchy (Clients → Projects → Tasks → Time Entries) and build everything else as relations or rollups against it.
The shortcut: Agency Operations OS
Building the 4-database structure, the page templates, the rollup formulas, and the dashboard views from scratch is a full weekend of Notion work. The pieces themselves aren't complicated. The relations and the formulas are where most builds break.
Agency Operations OS is the Notion template I use to run Eximius Studio. It includes:
- 7 core databases: Clients, Projects, Tasks, Time Entries (the four above) plus Retainers, Change Orders, Financials, AR Aging
- 5 dashboards: Weekly Owner Review, Pipeline, Active Projects, Retainer Health, Margin by Client
- 15 SOPs including time-logging discipline, weekly review process, and migration checklist from this post
- 5 bonus docs: Master Services Agreement, Retainer Agreement, Project Proposal template, Discovery Call script, and the 47-item Pre-Launch QA Checklist
One template, deploys in an afternoon, $79.
The 4-database setup above is the spine of agency project management in Notion. Build it right, build it once, and you have an operating system that scales to 10 people without needing to switch tools.
For the broader operating model, how to run a web design agency covers all seven systems, the 12 SOPs every web design agency needs covers the recipes that run inside this workspace, and the best Notion templates comparison ranks Agency Operations OS against the other options on the market.
