Software & AIJuly 14, 2025

PostgreSQL for SaaS platforms: how we manage data, users and credits in LetsAI

Choosing the database for a multi-user SaaS platform isn't trivial. PostgreSQL for LetsAI: after two years zero regrets. Users, credits, generation history and analytics — all in one database that never let us down.

PostgreSQL for SaaS platforms: how we manage data, users and credits in LetsAI - Software & AI | i3k

Why PostgreSQL and not MongoDB or MySQL

We've used MongoDB in past projects. Convenient for prototypes, but when data has relationships (users → plans → credits → generations → invoices) a relational database is more natural. JOINs are what you need. PostgreSQL has two differentiators: JSONB for semi-structured data (generation metadata changes per provider) and extensions — pg_stat_statements, pg_trgm, pgcrypto. All built in. In two years: 400,000+ generation records. Aggregate analytics queries respond under 200ms.

Multi-tenant with Row Level Security

LetsAI is multi-tenant: each user sees only their data, shared database. Every table has user_id and an RLS policy. Even if a bug forgot the WHERE, PostgreSQL blocks access to other users' data at database level. RLS saved us at least twice from potential data leaks during development. Performance cost: under 1%.

Credits: ACID transactions where they really matter

The most delicate part: the credit system. Buy a package, generate, credits decrease. If something goes wrong mid-generation, credits must not decrease. Flow: BEGIN → verify credits → SELECT FOR UPDATE (locks the row) → call AI provider → COMMIT or ROLLBACK. SELECT FOR UPDATE prevents two simultaneous requests from spending the same credits. In 400,000+ transactions: zero lost or duplicated credits.

JSONB for variable metadata

Every generation has different metadata. Video: resolution, duration, frame rate. Image: dimensions, model, seed. Columns for every field? Insane. JSONB solves it: save structured JSON but run efficient queries — metadata->>'model' = 'stable-diffusion-xl'. With GIN index, queries are almost as fast as regular columns. Advice: fields for frequent JOINs and filters (user_id, created_at, type) stay as normal columns. JSONB only for variable data.

Backup and monitoring: the routine that saves us

pg_dump every 6 hours, 30-day retention. WAL archiving for point-in-time recovery. Weekly restore test — a backup you can't restore isn't a backup. pg_stat_statements for slow queries (alert if >500ms). PgBouncer for connection pooling: database accepts 100 connections, app sees 500. Cost: under €50/month on dedicated VPS. Handles all LetsAI traffic.

Related Services

See how we apply these technologies in our enterprise projects.

Interested?

Contact us to receive a personalized quote.

All articles

Securvita S.r.l. — i3k.eu