Formula fields: computed from the record itself
Arithmetic, text joining, date math, IF and SWITCH, computed by the database itself so results can never drift. The builder, the text mode, and the exact function list.
Updated August 2026
A formula field computes its value from the record's other fields. The demo shop's Orders table has one called To collect:
{Total} * (1 - {Discount} / 100)
Every order shows the discounted amount, nobody types it, and it is correct the instant either input changes — because the value isn't synced by the app, it's computed by the database itself. The column is a real Postgres generated column, maintained on every write. A stored total that drifts out of date is not a failure mode this field has.
The builder and the text mode
Add a field and choose Formula. The editor has two skins that hand off to each other losslessly:
- The builder — the default. You compose the expression as pills: fields, functions, operators, values. A "Reads as" line shows the text it amounts to, and beneath it the editor works the formula through your table's first record, step by step, so you see a real answer before the field exists.
- Edit as text — a plain expression box for typing and pasting. Reference fields as
{Field Name}; a one-word name works bare. Completion opens on any word you type — fields insert in their braces, functions with their parenthesis — and mistakes are marked at the exact spot, with the nearest real names offered as one-click repairs.
Either way the type of the result — number, text or date — is inferred from the expression and shown live. There is no type to pick, so none to get wrong.

What the language covers
Deliberately small, and checked before anything is saved:
- Arithmetic —
+ - * /, parentheses, and&to join anything into text. - Comparisons and logic —
IF(condition, then, else)with= != > >= < <=, combined withAND,OR,NOT; nesting is fine, andSWITCH(value, case, result, …, default)reads better than a ladder of IFs.BLANK()tests an empty cell. - Text —
UPPER,LOWER,TRIM,LEN,LEFT,RIGHT,MID,SUBSTITUTE,FIND,CONCATENATE. - Numbers —
ABS,ROUND,ROUNDUP,ROUNDDOWN,INT,CEILING,FLOOR,MOD,POWER,SQRT,VALUE,MIN,MAX. - Dates —
YEAR,MONTH,DAY,WEEKDAY,DATEADD,DATETIME_DIFF(units: days, weeks, months, years), plus plain date math:{Check-out} - {Check-in}is a number of days,{Placed} + 3a date. - The record —
RECORD_ID().
A long formula can be written as named steps, one per line, the result last:
nights = DATETIME_DIFF({Check-out}, {Check-in}, "days")
subtotal = nights * {Rate per night}
subtotal + subtotal * 0.14
A formula can read the record's text, number, date and single-select fields (a select reads as its choice's name). It can't read another formula, a lookup or a rollup — no chains in v1 — and both IF branches must produce the same type.
Editing after creation
The expression is editable after creation: open the field, change it, save. The result type re-infers from the new expression — a number formula edited into an IF that returns text becomes a text formula. The one refusal: if a lookup or rollup on another table depends on this field's current type, the type-changing edit is blocked by name until that dependent is adjusted.
What a formula field can't do is convert into an ordinary field or back — the column is a generated expression, not typed-in data. To keep computed values as plain data, add a plain field and paste the column in.
Honest edges
- Division by zero,
SQRTof a negative, andVALUEof text that isn't a number all produce a blank, never an error cell. - A date-and-time field is read in universal time (UTC) inside a formula — the editor discloses this whenever you reference one. A day it derives can differ from the grid near midnight.
- There is no
TODAY()orNOW(). A stored, database-maintained column cannot depend on the current moment — the API refuses it plainly (Unknown function "TODAY" in formula.). Formulas that know today's date are on the wishlist; today, "days until deadline" needs a tool that asks on a schedule, like a webhook consumer. - A formula that doesn't check out — a typo, a type mismatch — is refused at creation with the exact place named. It never half-exists.
Everywhere else, an ordinary field
A formula field filters, sorts, groups and feeds webhook payloads exactly like a plain field of its result type, and reads over the API under its own name:
"Total": 63,
"Discount": 10,
"To collect": 56.7
Writing to it is refused: "To collect" is a formula — it's computed automatically and can't be written to directly. The cell is read-only on screen for the same reason.
When you actually want a different field
A formula sees one record at a time. The moment the calculation crosses a link — the customer's total across orders, the latest delivery date across lines — you want a rollup, or a lookup for a single borrowed value. Formula, lookup or rollup sorts the three in two minutes.