Notion Formula Cheat Sheet for Developers (2026)
Notion formulas follow consistent patterns. Once you learn the pattern, most formulas become variations of something you've already seen.
Most formula guides organize by use case -- "formulas for project management," "formulas for habit tracking." This one organizes by pattern type, because understanding the structure is what lets you build formulas you haven't seen before, not just copy ones you have.
What this guide covers:
- Basic syntax rules that prevent 90% of errors
- Text, number, date, and boolean formulas
- Conditional logic patterns for if statements
- Rollup-based formulas
- Two complete production-ready formulas used in real developer workflows
- Troubleshooting reference for the most common Notion formula errors
Why Developers Need Notion Formulas
Standard Notion databases are static. You add data, you read data, nothing moves on its own. Formulas change that -- they turn your workspace into something that calculates, flags, labels, and responds to the data you enter.
For a developer productivity system specifically, formulas are what make the difference between a task list and a system. Without them, you're manually updating fields that could update themselves. With them, your workspace surfaces what needs attention, tracks progress automatically, and rewards completion without any extra input from you.
Part 1: Basic Syntax Rules for Notion Formulas
Three rules that prevent most Notion formula errors before they happen.
Rule 1: String Values Use Double Quotes
if(("Status") == "Done", "Incomplete", "Complete")
Text comparisons in Notion formulas always use double quotes. Single quotes throw an error with no helpful message.
Rule 2: Nested If Statements Close With Matching Parentheses
if (A, "x", if (B, "y", if (C, "z", "default")))
Every if( needs a closing ). Three nested if statements need three closing parentheses at the end. Count your opens and closes before saving -- this is where most Notion formula syntax errors hide.
Rule 3: Empty and Zero Are Not the Same
empty("Due Date") //true when the date is field blank
("Number Field") == 0 //true when the field contains zero
Use empty() to check for blank fields. Use == 0 to check for the number zero. Confusing these produces formulas that return wrong results silently -- no error, just incorrect output.
Part 2: Notion Text Formulas
Concatenate Two Properties
("First Name") + " " + ("Last Name")
Returns: Text -- "Alex Chen"
When to use: Combining name fields or any two text properties into a single display value.
Concatenate Text With a Number in Notion
"Level " + format("Level Number")
Returns: Text -- "Level 7"
When to use: Adding static text before or after a number. The format() function converts the number to text -- without it, Notion throws a type mismatch error.
Convert Text to Uppercase
upper("Status")
Returns: Text — "DONE"
When to use: Standardizing text display in headers or labels when source data has inconsistent casing.
Check if a Notion Text Field Contains a Keyword
contains("Tags"), "urgent"
Returns: Boolean — true or false
When to use: Filtering or flagging entries that include a specific word in a text field. Case-sensitive — "urgent" and "Urgent" return different results.
Show a Fallback When a Field Is Empty
if(empty("Project Name"), "No project assigned", "Project Name")
Returns: Text — the project name or the fallback string
When to use: Preventing blank cells on dashboards where every row should display something meaningful.
Count Characters in a Notion Text Field
length("Notes")
Returns: Number — 142
When to use: Tracking note length or flagging fields that are too short to be useful.
Part 3: Notion Number Formulas
Basic Arithmetic in Notion
("Revenue") - ("Cost")
Returns: Number
When to use: Any calculation involving two number properties. Supports +, -, *, /.
Round Numbers in Notion Formulas
round("Score")
Returns: Number — 73 from 72.8
When to use: Cleaning up decimal results from division. round() rounds to nearest, floor() always rounds down, ceil() always rounds up.
Calculate a Percentage in Notion
floor(("Completed" / "Total") * 100)
Returns: Number — 68
When to use: Progress percentages and completion rates. floor() prevents decimal output.
Clamp a Number Within a Range
min(max("Progress", 0), 100)
Returns: Number — always between 0 and 100
When to use: Preventing progress percentages from going below 0 or above 100 when source data produces out-of-range values.
Get the Maximum of Two Values
max("Estimated Hours", "Actual Hours")
Returns: Number — the larger of the two
When to use: Comparing two number properties and surfacing whichever is larger. min() works the same way for the smaller value.
Part 4: Notion Date Formulas
Get Today's Date in Notion
now()
Returns: Date — current date and time
When to use: As the reference point in any Notion date calculation. Updates automatically every time Notion recalculates.
Calculate Days Between Two Dates in Notion
dateBetween("Due Date", now(), "days")
Returns: Number — positive if Due Date is in the future, negative if it's in the past
When to use: Calculating days until a deadline or days overdue. Result is Due Date minus now() — so future dates give positive numbers.
Add Days to a Date in Notion
dateAdd("Start Date", 7, "days")
Returns: Date — seven days after the start date
When to use: Calculating end dates, review dates, or any date a fixed interval after another. Supports "days", "weeks", "months", "years".
Format a Notion Date as Readable Text
formatDate("Due Date", "MMM DD, YYYY")
Returns: Text — "May 23, 2025"
When to use: Displaying dates in a specific format inside concatenated strings. Format codes: MMM = short month name, MMMM = full month name, DD = day with leading zero, YYYY = four-digit year.
Extract the Month From a Date in Notion
month("Created Date")
Returns: Number — 1 through 12
When to use: Grouping entries by month or filtering for a specific month. day(), year(), and hour() work the same way.
Check if a Notion Date Is in the Past
dateBetween("Due Date", now(), "days") < 0
Returns: Boolean — true if the date has passed
When to use: The foundation of overdue detection in Notion. Combine with if() to label or flag entries automatically.
Days Since an Entry Was Created
dateBetween(now(), "Created time", "days")
Returns: Number — days since creation
When to use: Age tracking and stale entry detection. Note the reversed argument order — now() first gives a positive number for past dates.
Part 5: Notion Conditional Logic — If Statement Patterns
Basic Notion If Statement
if("Status" == "Done", "✓ Complete", "In progress")
Returns: Text — one of two values based on the condition
When to use: Any binary labeling in Notion — done/not done, overdue/upcoming, high/low.
Nested If Statement in Notion (Multiple Conditions)
if("Priority" == "High", "🔴 Critical",
if("Priority" == "Medium", "🟡 Normal",
if("Priority" == "Low", "🟢 Low",
"No priority")))
Returns: Text — one of four possible labels
When to use: More than two possible outputs. Each additional condition adds one more nested if(). Always end with a default value as the last argument.
Notion And Condition
if(and("Status" == "Done", "Priority" == "High"), "High value win", "")
Returns: Text — label only when both conditions are met
When to use: Flagging entries that meet multiple criteria simultaneously. Empty string "" leaves the cell blank when conditions aren't met.
Notion Or Condition
if(or("Status" == "Overdue", "Status" == "Blocked"), "⚠️ Needs attention", "")
Returns: Text — label when either condition is met
When to use: Surfacing entries that match any one of several problem states.
Notion If Statement With Empty Guard
if(empty("Due Date"), "No deadline",
if(dateBetween("Due Date", now(), "days") < 0, "Overdue", "On track"))
Returns: Text — three possible states
When to use: Always guard against empty dates first when using date properties in Notion — skipping this causes errors on any row without a date filled in.
Ternary-Style If in Notion Formulas 2.0
prop("Score") >= 80 ? "Pass" : "Fail"
Returns: Text — "Pass" or "Fail"
When to use: Simple binary conditions where the long-form if() syntax is unnecessary. Only works in Formulas 2.0.
Part 6: Notion Boolean Formulas
Check if a Checkbox Is Checked in Notion
("Done") == true
Returns: Boolean
When to use: Using a checkbox property as a condition inside a larger Notion formula.
Convert a Boolean to Text in Notion
if("Is Active", "Active", "Inactive")
Returns: Text — readable label from a checkbox value
When to use: Displaying checkbox state as text in a summary or label column.
Part 7: Notion Rollup-Based Formulas
Rollups pull aggregated data from related databases. Set up the rollup first, then reference its result inside a formula.
Progress Percentage From Rollup
if("Total Tasks" == 0, 0,
floor(("Done Tasks" / "Total Tasks") * 100))
Requires:
- Rollup "Total Tasks": Count all, relation to Tasks database
- Rollup "Done Tasks": Count values where Status = Done
Returns: Number — 0 to 100
Flag if Any Related Item Needs Attention
if("Open Issue Count" > 0, "⚠️ Has open issues", "✓ On track")
Requires:
- Rollup "Open Issue Count": Count values where Status = Open
Returns: Text — project-level health indicator that updates automatically
Average Score Across Related Entries
round("Average Score")
Requires:
- Rollup "Average Score": Average of Score property, relation to relevant database
Returns: Number — rounded average across all related records
Part 8: Two Complete Production-Ready Notion Formulas
Formula 1: Project Progress With Visual Bar
This Notion formula shows project completion as both a percentage and a visual progress bar. It handles empty projects, backlog items, and on-hold work automatically without errors.
Setup:
- Add Rollup "Total Tasks" — Count all from Tasks relation
- Add Rollup "Completed Tasks" — Count values where Status = Done
- Add a Formula property named "Progress"
if(Total Tasks > 0 and Completed Tasks == Total Tasks, "100%",
if(Status == "backlog" or Status == "on hold", "0%",
if(Total Tasks > 0,
let(
completed_val, if(empty(Completed Tasks), 0, toNumber(Completed Tasks)),
total_val, if(empty(Total Tasks), 0, toNumber(Total Tasks)),
percentage, round(completed_val / total_val * 100),
progress_blocks_count, floor(percentage / 10),
filled_bar, (substring("", 0, progress_blocks_count)),
empty_bar, (substring("", 0, 10 - progress_blocks_count)),
format(percentage) + "% " + filled_bar + empty_bar
),
"0%")))
Output example: 70% ███████░░░
Key behaviors:
- Projects where all tasks are done snap cleanly to 100% without rounding errors
- Backlog and On Hold projects always show 0% regardless of task count
- Empty projects return 0% without throwing a division error
-
let()scoping keeps each calculation readable and avoids redundant computation
One thing to watch: The Status check references your exact Status option names. If your options use different casing — "Backlog" vs "backlog" — update the formula strings to match character for character.
Formula 2: Automatic Task Value in Notion
This Notion formula assigns a point value to each task based on priority automatically — no manual entry required every time you create a task.
Setup:
- Confirm a Select property called "Priority" with options: Low, Medium, High
- Add a Formula property named "Task Value"
if(Priority == "High", 10, if(Priority == "Medium", 5, 1))
Output: High = 10 points, Medium = 5 points, Low or unset = 1 point
Low priority tasks return 1 rather than 0 — every completed task contributes something regardless of how it was prioritized.
Roll Task Value up to your Character Sheet:
- Relation: Tasks
- Property: Task Value
- Filter: Status = Done
- Calculate: Sum
This gives you a running total of points from completed tasks only — the foundation of a gamified developer productivity system.
One thing to watch: The formula matches exact string values. "HIGH" and "High Priority" won't match "High." Check your Priority option names and update the formula strings to match.
Part 9: Level Progression Formula for Notion (Complete 20-Level Version)
The full exponential level progression formula used in DevHub — 20 levels based on cumulative task points.
if("Total XP" >= 225000, "Level 20: Legendary 🏆",
if("Total XP" >= 185000, "Level 19: Celestial ☄️",
if("Total XP" >= 150000, "Level 18: Ascendant ⚡",
if("Total XP" >= 120000, "Level 17: Apex ⛰️",
if("Total XP" >= 97500, "Level 16: Paragon 💎",
if("Total XP" >= 78000, "Level 15: Oracle 🔮",
if("Total XP" >= 62500, "Level 14: Architect 🗺️",
if("Total XP" >= 50000, "Level 13: Vanguard 🏹",
if("Total XP" >= 40000, "Level 12: Luminary 🌟",
if("Total XP" >= 32000, "Level 11: Virtuoso 🗿",
if("Total XP" >= 25000, "Level 10: Grandmaster 👑",
if("Total XP" >= 18000, "Level 9: Master 🪨",
if("Total XP" >= 13000, "Level 8: Senior 🧭",
if("Total XP" >= 9000, "Level 7: Professional 🛡️",
if("Total XP" >= 6000, "Level 6: Specialist 🔎",
if("Total XP" >= 3500, "Level 5: Adept 🔩",
if("Total XP" >= 2000, "Level 4: Journeyman 📜",
if("Total XP" >= 1000, "Level 3: Apprentice 🛠️",
if("Total XP" >= 500, "Level 2: Novice 🔧",
"Level 1: Beginner ⚙️"))))))))))))))))))))
Requires: A rollup called "Total XP" that sums Task Value from completed tasks only.
Troubleshooting Common Notion Formula Errors
"Property not found"
Property name in the formula doesn't match exactly. Check capitalization and spacing — they must be identical character for character. Rename the property temporarily to something simple like "Test" while debugging to confirm the relation works.
"Type mismatch"
You're combining a number and text without converting. Wrap the number in format() before concatenating: format("Score") + " points"
"Division by zero"
You're dividing by a property that contains zero or is empty. Add a guard clause: if("Total" == 0, 0, "Done" / "Total")
Formula always returns the same value
Your condition is never being met. Test each part separately in a new formula property to isolate where the logic breaks. Check that property names match and that the values you're comparing exist exactly as written in your database.
Rollup shows the wrong count
The filter value on your rollup must exactly match the option name in your database. "Done" and "done" are different values. Open your Status property settings and copy the option name exactly into your rollup filter.
What to Build Next
These formulas work independently — add any one to an existing workspace without touching the others. But they're designed to work together.
The progress formula tells you where your projects stand. The task value formula rewards you for completing the work that moves them forward. The level progression formula turns that accumulated value into a visible measure of your growth as a developer.
That combination — visibility, reward, and progression — is what most productivity systems are missing.
If you want these formulas pre-configured and connected in a complete developer workspace, DevHub includes all of them out of the box. The free version has the full database structure with the formulas already in place.
Top comments (0)