PostgreSQL development
Put the rules in the database, and the app gets simpler.
Acasa Labs designs and builds on PostgreSQL. Eight of the nine systems on our work page run on it, and we use more of Postgres than tables: row-level security in GymFast, a skip-locked job queue in SigmaCPM, pgvector and PostGIS in Acasa Sentinel, and plan limits enforced by a database constraint in Pullsy.
The problem
The database is the part that is hardest to change later.
Screens get redesigned and services get rewritten. The schema stays. A missing constraint lets bad data in for two years. A permission rule written in app code is skipped by the next app someone builds. A background job table without proper locking runs the same job twice. Postgres can enforce most of these rules itself, which is cheaper than enforcing them in every client. It only works if someone designs the schema with that in mind from the start.
What we build with PostgreSQL
- 01
Schemas that hold their shape
Constraints, foreign keys, and checks that make bad data impossible to save, and migrations that run without taking the app down.
- 02
Security in the database
Row-level security policies for multi-tenant and multi-role apps, tested by reading and writing as each role.
- 03
Queues and jobs in Postgres
Job tables with leases and SKIP LOCKED, so workers share work safely without another broker to run and monitor.
- 04
Search, vectors, and geography
Full-text search, pgvector embeddings, and PostGIS for location data, in the same database as the rest of the product.
From production
Postgres features doing real work in our systems.
A queue with no broker
SigmaCPMSigmaCPM's job queue is a Postgres table with leases, orphan reclaim, and skip-locked selection. A crashed worker's job is reclaimed, two workers never pick up the same one, and there is no extra service to run.
Roles enforced by policy
GymFastGymFast's six role levels, from owner to member, are enforced with row-level security in Supabase Postgres, so the web dashboard and every app follow the same rules.
Plan limits as a constraint
PullsyPullsy's per-seat and per-storefront plans are enforced down to a database constraint, so a limit holds even when a piece of application code forgets to check it.
Vectors next to the sightings
Acasa SentinelAcasa Sentinel stores a 768-dimension DINOv2 embedding for every sighting in Postgres with pgvector, with PostGIS alongside it. Appearance search runs in the same database as the sightings themselves.
One events table
Acasa SentinelPlates, crowd counts, and zone intrusion all land in one events table, so a new kind of alert needs no schema change.
Honest trade-offs
When Postgres is not the answer
For short-lived data, rate limits, and fast queues, Redis is the better tool, and most of our systems run it next to Postgres. For large analytical scans over time-series data, columnar files win: the trading platform keeps its tick archive in Parquet and queries it with DuckDB and Polars. And when vector search is the main workload rather than a feature, a dedicated engine can be the better fit. NoteTube uses Qdrant.
What we reach for
- PostgreSQL
- Row-level security
- pgvector, PostGIS
- SKIP LOCKED job queues
- Supabase, Cloud SQL, Neon, RDS
- SQLAlchemy, Drizzle, Django ORM
- Alembic and Django migrations
Proof
Shipped, not pitched.
01Our product
SigmaCPM
Construction project management where AI reads the tender and shows its work.
One project record for civil contractors, from tender to closeout: bids, contracts, RFIs, vendor quotes, and drawings. The AI pulls line items and bond terms out of tender PDFs and cites the page for every value.
Web · API · Chrome extension
02Our product
GymFast
Members, billing, classes, and workout plans for a gym, in one platform and three apps.
Gym management software for gym owners and personal trainers. A web dashboard and a staff app run members, plans, invoices, enquiries, and classes; members get their own branded app; GymFast Pro gives independent trainers the same tools for their clients.
Web dashboard · iOS · Android · Staff, member, and trainer apps
03Our product
Pullsy
Instagram analytics that keep the numbers Instagram throws away.
Analytics for creators. Pullsy keeps insights Instagram discards after about 90 days, explains what each number means, grades the account, and turns it into a media kit a brand can verify.
Web · iOS (native SwiftUI) · REST API
04Case study
Acasa Sentinel
Give it a number plate. It returns the vehicle's route across a CCTV network.
A vendor-neutral video analytics system built for the Gujarat Police Hackathon Innovation Challenge 2026. It reads number plates, re-identifies vehicles by appearance across cameras, reconstructs routes, and raises watchlist alerts for an operator to confirm.
Operator console (web) · API
Questions
PostgreSQL questions we get asked.
Postgres or a NoSQL database?
If your data has relationships, such as customers, orders, invoices, and roles, Postgres is simpler over the life of the product. It also stores JSON well when part of the data has no fixed shape.
Can Postgres be our job queue?
Yes, up to a fairly high volume. With leases and SKIP LOCKED, SigmaCPM runs its job queue in Postgres with no separate broker. We move to Redis or a dedicated queue when the volume calls for it.
Can you fix our slow queries?
Usually. We read the query plans, add the indexes they ask for, rewrite the worst queries, and fix the ORM patterns that fire one query per row.
Is pgvector enough, or do we need a vector database?
pgvector is enough for many products and keeps vectors next to the data, as in Acasa Sentinel. A dedicated engine like Qdrant makes sense when vector search is the core workload, as in NoteTube.
Where should our Postgres run?
In a managed service in your account, such as Supabase, Google Cloud SQL, Neon, or AWS RDS, chosen by what else you run and where your users are.
PostgreSQL development
Show us the schema before it gets harder to change.
A free 30-minute review of your Postgres schema, queries, or plans. You leave with what we would change first.



