Skip to content
Open beta — everything’s free right now, and your rate is locked when it ends.

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.

The formula builder open on the Orders table: the expression as pills, the live Reads-as line, the inferred result type, and the first record's worked answer.

What the language covers

Deliberately small, and checked before anything is saved:

  • Arithmetic+ - * /, parentheses, and & to join anything into text.
  • Comparisons and logicIF(condition, then, else) with = != > >= < <=, combined with AND, OR, NOT; nesting is fine, and SWITCH(value, case, result, …, default) reads better than a ladder of IFs. BLANK() tests an empty cell.
  • TextUPPER, LOWER, TRIM, LEN, LEFT, RIGHT, MID, SUBSTITUTE, FIND, CONCATENATE.
  • NumbersABS, ROUND, ROUNDUP, ROUNDDOWN, INT, CEILING, FLOOR, MOD, POWER, SQRT, VALUE, MIN, MAX.
  • DatesYEAR, 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} + 3 a date.
  • The recordRECORD_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, SQRT of a negative, and VALUE of 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() or NOW(). 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.

Tabla is the database we build these on.

A no-code database with real Postgres underneath: every feature on every plan, a million records per database, and your whole database back out in one file, any day.

More guides