Two flavours of derived columns
A generated column derives its value from other columns in the same row. STORED generated columns are written to disk on every insert/update — they take space but can be indexed. VIRTUAL generated columns (PG 18+) are computed on read — no storage, always current, cannot be indexed.
Pick STORED if you'll index it
Indexing a virtual column is impossible (the value isn't stored). Indexing a stored column works exactly like indexing any other column. So the decision is usually: "will I query/filter/sort by this derived value?" — if yes, STORED; if no, VIRTUAL is cheaper.
Use cases that pay off
- Slugs computed from titles.
- Search-friendly normalised text (lowercased, accent-stripped).
- Pre-computed totals (price × quantity, before-tax + tax).
- tsvector for full-text search (always STORED + GIN).