Get in touch
Engineering

Postgres tricks we reach for

Four features we use on nearly every project, and the one we stopped using after it bit us.

By Ovadev2 min read

All posts
  • postgres
  • sql
  • januna

We are not database maximalists. But a rule that lives in application code is a rule that holds until the second service arrives, and every product eventually gets a second service — a cron, an import script, an admin tool written in a hurry.

The four we reach for

  • Row-level security
  • Generated columns
  • Partial indexes
  • Advisory locks

Row-level security, for real tenancy#

Januna is multi-tenant. Every query in the application filters by tenant_id, and every one of those filters is a chance to forget. Row-level security turns that from a convention into a constraint the database enforces regardless of who is asking.

sql
alter table sale enable row level security;

create policy tenant_isolation on sale
  using (tenant_id = current_setting('app.tenant', true)::uuid);

-- the app sets this once per connection checkout
set local app.tenant = '…';

Generated columns, for things that must not drift#

Anything derived — a search vector, a lowercased email, a total with tax — is a chance for two code paths to disagree. A generated column can only have one answer, and it is computed by the thing that stores it.

sql
alter table product
  add column search tsvector
  generated always as (
    to_tsvector('simple', coalesce(name,'') || ' ' || coalesce(sku,''))
  ) stored;

create index product_search_idx on product using gin (search);

Partial indexes, for the query you actually run#

Most tables are read with a filter attached — open orders, active sessions, unarchived rows. A partial index covers exactly that slice and skips the rest, which on Januna's sales table means an index a twentieth of the size answering the query that runs a thousand times an hour.

sql
create index sale_open_idx on sale (tenant_id, created_at desc)
  where closed_at is null;

Advisory locks, for the job that must not run twice#

Before reaching for a queue or a scheduler with leader election, try the lock the database already has. A session-level advisory lock gives you mutual exclusion across every process pointed at the same database, and it disappears when the connection does.

sql
select pg_try_advisory_lock(hashtext('nightly-rollup'));
-- false → someone else is already doing it, go home

The one we stopped using#

listen/notify for cache invalidation. It is elegant, it is instant, and it silently drops everything on a reconnect — which means the cache is correct until exactly the moment the network is not, and then it is wrong with no signal at all. We moved to short TTLs plus a version column. Less elegant, no failure mode that requires you to notice.

Ovadev

A software company in Baar, Zug. We build our own products, run them afterwards, and write down what that teaches us.

Get in touch
Read next

More from the studio — engineering first, then the rest of the feed.

All posts
© 2026 Ovadev GmbHMade in Switzerland