How to add a formula

Open a database, click + at the end of the header row, choose Formula and give it a name. Paste the formula into the editor. The prop("Name") parts turn into grey property chips, and a preview of the result shows under the editor. If a property in the formula does not exist in your database, the editor says so before you save.

  • Property names must match exactly, including capitals and spaces.
  • Numbers and text cannot be added together directly. Wrap the number in format() first.
  • A formula always answers per row. To add up a whole column, use the calculation at the bottom of the column instead.

1. Join text and a number

Useful for gallery cards, where you want one readable line instead of three properties.

prop("Course") + " · " + format(prop("Hours")) + " h"

What it does: writes something like "Calculus I · 2.5 h". format() is what lets the number sit inside text.

2. Round to one decimal

round() only rounds to whole numbers, so multiply first and divide after.

round(prop("Hours") * 10) / 10

What it does: turns 2.4666 into 2.5. Use 100 instead of 10 for two decimals.

3. Days left until a date

The most used formula in Notion. Works for deadlines, exams, trips and bills.

dateBetween(prop("Due"), today(), "days")

What it does: counts the days from today to the Due date. It goes negative once the date has passed.

4. Days since something happened

Swap the two dates around and the same function counts forwards instead.

dateBetween(today(), prop("Last contact"), "days")

What it does: shows how many days ago Last contact was. Handy for people you mean to keep in touch with, or a plant you water.

5. Day of the week

Date properties show the date but not the weekday. This adds it.

formatDate(prop("Date"), "dddd")

What it does: writes Monday, Tuesday and so on. Use "ddd" for the short form (Mon, Tue).

6. Your own date format

formatDate() accepts a pattern, so you can write dates the way you read them.

formatDate(prop("Date"), "D MMMM YYYY")

What it does: writes 11 October 2026. "MMM" gives Oct, "YYYY-MM-DD" gives 2026-10-11.

7. Is this date in the current month?

A formula that returns true or false shows as a checkbox, which you can then filter on.

formatDate(prop("Date"), "YYYY-MM") == formatDate(today(), "YYYY-MM")

What it does: ticks itself for every row dated this month and unticks itself when the month changes.

Notion's own filter has "is within this month" for most views, so you only need this formula when you want the answer as a column, for example to count this month's rows in a rollup.

8. Week number

For weekly reviews, training logs or anything you group by week.

week(prop("Date"))

What it does: gives the week of the year, from 1 to 53, using the ISO standard where weeks start on Monday.

9. Age or years since

Change "years" to "months" or "weeks" for other units.

dateBetween(today(), prop("Birthday"), "years")

What it does: works out someone's age from their birthday, in whole years.

10. An overdue checkbox

Three conditions in one and(): not done, has a date, and the date is in the past.

and(not(prop("Done")), not(empty(prop("Due"))), prop("Due") < today())

What it does: ticks itself when a task is late. Make a view filtered to Overdue is checked and late work has nowhere to hide.

11. A coloured due label

A longer one, but it replaces a date with words you can read at a glance. It expects a Done checkbox and a Due date.

if(prop("Done"), style("Done", "gray"), if(empty(prop("Due")), style("No date", "gray"), lets(d, dateBetween(prop("Due"), today(), "days"), if(d < -1, style(format(abs(d)) + " days late", "red"), if(d == -1, style("1 day late", "red"), if(d == 0, style("Due today", "orange"), if(d == 1, style("Tomorrow", "yellow"), style(format(d) + " days left", "green")))))))))

What it does: shows "3 days late" in red, "Due today" in orange, "Tomorrow" in yellow and "6 days left" in green. lets() stores the day count as d so it is only worked out once.

12. A status in words

ifs() checks conditions in order and stops at the first one that is true, so put the highest threshold first.

ifs(prop("Progress") >= 100, "Done", prop("Progress") >= 70, "On track", prop("Progress") >= 40, "At risk", "Behind")

What it does: turns a percentage into Done, On track, At risk or Behind. The last value is what you get when nothing above matched.

13. Progress towards a target

For goals with a number: books read, kilometres run, money saved.

if(prop("Target") > 0, min(100, round(prop("Current") / prop("Target") * 100)), 0)

What it does: shows how far Current is towards Target as a percentage, stops at 100, and shows 0 until a target is set.

To draw it as a bar, open the property, choose Show as: Bar and set Divide by to 100.

14. Progress from linked tasks

Formulas can read through a relation. This one goes on a Projects database that has a relation called Tasks, where each task has a Done checkbox.

if(prop("Tasks").length() > 0, round(prop("Tasks").filter(current.prop("Done")).length() / prop("Tasks").length() * 100), 0)

What it does: counts the linked tasks, counts the ones that are done, and shows the share as a percentage.

A rollup can do the same without a formula: Relation Tasks, Property Done, Calculate Percent checked. Use the formula when you want to change the rule, for example to leave out cancelled tasks.

15. A text progress bar

For places where Notion's bar does not show, such as a gallery card title or a formula that combines several values. It expects a Progress number from 0 to 100.

repeat("■", round(prop("Progress") / 10)) + repeat("□", 10 - round(prop("Progress") / 10))

What it does: draws ten squares and fills one for every 10%, so 60 becomes ■■■■■■□□□□.

16. One line for a card

Combines two formulas from above into a single line that fits on a gallery card.

format(prop("Progress")) + "% done" + if(prop("Days left") > 0, " · " + format(prop("Days left")) + " days left", "")

What it does: writes something like "57% done · 149 days left", and drops the second half once there are no days left.

17. Add up a column through a relation

For a Customers database related to Orders, where each order has a Total.

prop("Orders").map(current.prop("Total")).sum()

What it does: adds up the Total of every order linked to that customer, which gives you lifetime value per customer.

18. Count linked rows that match a rule

For a Courses database related to Assignments, where each assignment has a Status.

prop("Assignments").filter(current.prop("Status") != "Submitted").length()

What it does: counts the assignments that are still open for that course. Change the rule inside filter() to count anything else.

19. What a subscription costs per year

For a Subscriptions database with Cost and a Billing select (Monthly or Yearly).

if(prop("Billing") == "Yearly", prop("Cost"), prop("Cost") * 12)

What it does: puts every subscription on the same yearly scale. Sort by it and the expensive ones are at the top.

20. A price that covers the platform fee

If a marketplace takes 10%, adding 10% to your price is not enough, because the fee is taken from the bigger number. Divide instead.

round(prop("Cost") * (1 + prop("Markup %") / 100) / (1 - prop("Platform Fee %") / 100) * 100) / 100

What it does: adds your markup to the cost, then grosses it up so that what is left after the fee is still the price you wanted, rounded to cents.

When a formula shows an error

Most errors come from one of four things:

  • A renamed property. Formulas follow renames made after they were written, but a name typed wrong in the first place shows as an error.
  • Text and numbers mixed. "Total: " + prop("Total") fails; "Total: " + format(prop("Total")) works.
  • A select compared to the wrong word. prop("Status") == "done" is false if the option is called Done.
  • Two different types from one if(). Both answers must be text, or both numbers. Use format() or toNumber() to make them match.