field notes from the satus team.
- 6 min
Postgres extensions that trip up seeders
PostGIS wants valid geometries. pgvector wants meaningful embeddings. pgcrypto wants real ciphertext. None of the three accept random bytes.
- ·postgres
- ·extensions
- 5 min
What a bad profile looks like
Three profile drafts we threw away before shipping saas, ecommerce, and b2b. Too many knobs, distributions that did not compose, vertical leaks.
- ·profile
- ·methodology
- ·anti-pattern
- 8 min
Seeding Stripe-shaped data without Stripe
How to fill a billing schema with realistic Customer, Subscription, Invoice, and Charge rows locally, so dashboards render without touching test-mode Stripe.
- ·billing
- ·stripe
- ·patterns
- 7 min
When UUIDs aren't the answer
UUIDv7 made the primary-key debate interesting again. What v7 fixes, what it doesn't, and when bigserial or a composite key is still the honest choice for a Postgres schema.
- ·postgres
- ·primary-keys
- 11 min
What pg_dump doesn't tell you about your own schema
pg_dump is a backup tool, not a schema description. Three things it omits or reorders, and why a seeder should read pg_catalog directly instead.
- ·postgres
- ·introspection
- ·pg_dump
- 4 min
v0.3.5: automated npm publishing, two correctness fixes
satus 0.3.5 adds tag-triggered npm publishing with provenance, restores deferrable-FK detection in introspection, and fixes the Action selftest to validate the in-repo CLI.
- ·release
- ·ci
- ·github
- ·npm
- 6 min
v0.3.3: the GitHub Action, and opt-in failure fingerprints
satus 0.3.3 ships passkeybridge/satus-action@v1, a composite Action wrapping the CLI for PR-preview databases, plus opt-in schema-shape fingerprints for the v0.4.0 agent eval set.
- ·release
- ·ci
- ·github
- ·telemetry
- 10 min
Generated columns are load-bearing now
Postgres GENERATED columns moved from novelty to infrastructure once PG12 shipped STORED and PG18 shipped VIRTUAL. What that means for introspection, INSERT ordering, and seeders.
- ·postgres
- ·generated-columns
- ·schema
- ·seeding
- 12 min
Profile design 101: pick distributions, not values
The heuristic we use when adding a new vertical to satus. Name the distributions and the correlations first, then, and only then, sample values. An internal design doc, published.
- ·profile
- ·methodology
- ·distributions
- ·postgres
- ·seeding
- 7 min
Roadmap: v0.3.3 ships the GitHub Action, and v0.5 becomes v0.4
What the next satus release will and will not do, why the GitHub Action is a 0.3.x patch and not a 0.4 line item, and how the version numbers shift.
- ·roadmap
- ·ci
- ·github
- ·release
- 5 min
The 1am deploy that only failed in prod
A field note on why a query that ran in 4ms on a seeded dev database stalled the moment it hit real cardinality, and what the planner was actually looking at.
- ·postgres
- ·planner
- ·performance
- ·seeding
- 8 min
Arrays vs junction tables: when Postgres arrays are a smell
Postgres array columns are tempting, occasionally correct, and usually a junction table waiting to happen. A field guide to the three cases where arrays win and the four where they don't.
- ·postgres
- ·modeling
- ·seeding
- 15 min
Inside the saas-subscriptions profile: MRR, churn, and the dunning death spiral
Subscription lifecycles, plan changes, failed payments, and the states no one documents. What the satus saas-subscriptions profile recommends, and what it leaves to you.
- ·profile
- ·saas
- ·billing
- ·postgres
- ·seeding
- 10 min
Seeding into a multi-tenant schema without leaking tenants
Multi-tenant schemas leak in seed data through shared lookup tables, FK chains that drop tenant_id, and RLS bypassed by a superuser connection. Here is the discipline satus follows.
- ·postgres
- ·multi-tenant
- ·rls
- ·seeding
- ·security
- 7 min
Agent mode, postponed to v0.5
Why satus is shipping an opt-in agent mode in v0.5 instead of v0.3, what it will and will not do, and how the 90-day evidence window between now and then shapes the design.
- ·roadmap
- ·agents
- ·design
- ·postgres
- 9 min
Enum types that grew up
How Postgres enum types evolve in real schemas, why ALTER TYPE ADD VALUE is harder than it reads, and how satus picks realistic distributions over them.
- ·postgres
- ·enums
- ·schema
- ·seeding
- 5 min
v0.3.0: Anthropic as a first-class provider, and machine-readable output
Anthropic joins OpenAI as a peer provider via tool-use forcing. A new --json flag emits a single snake_case object on stdout so CI can parse it. Token counts are now persisted alongside cost.
- ·postgres
- ·satus
- ·release
- ·anthropic
- ·openai
- ·cli
- 4 min
A $0 dry-run that catches FK and constraint bugs before the LLM call
satus 0.3 ships an offline --dry-run that simulates LLM output and validates against your live Postgres metadata. No API key, no writes, no spend.
- ·postgres
- ·seeding
- ·validation
- ·ci
- 9 min
When faker.js is exactly the wrong answer
faker.js generates 10,000 plausible names. It does not generate 10,000 names whose foreign keys resolve. A field note on the gap between fake values and seed data.
- ·tooling
- ·faker
- ·postgres
- ·seeding
- ·philosophy
- 11 min
Check constraints that lie
Postgres CHECK constraints look like rules but often encode wishes. Where they leak (NULL, non-immutable expressions, NOT VALID, domains), why satus has to detect it, and what to write instead.
- ·postgres
- ·constraints
- ·schema
- ·seeding
- 14 min
Inside the e-commerce profile: SKUs, carts, and the long tail of returns
Catalog distributions, basket sizes, return rates, and seasonality the satus e-commerce profile encodes, what it leaves to the user, and why we do not ship a fashion-vs-electronics switch.
- ·profile
- ·ecommerce
- ·distributions
- ·postgres
- ·seeding
- 12 min
Three timezone bugs we found by seeding production-shaped data
Uniformly random timestamps hide timezone bugs. Business-hours-clustered timestamps surface them. Three bugs we have reproduced in support, and the catalog signals that predict each one.
- ·postgres
- ·timezones
- ·testing
- ·seeding
- 8 min
JSONB columns that are secretly relational
Half the JSONB columns we see are key/value bags. The other half are foreign keys in disguise — arrays of IDs pointing at real rows, with no constraint to prove it. How to tell them apart.
- ·postgres
- ·jsonb
- ·modeling
- ·seeding
- 7 min
v0.2.0: deferred constraints, faster planning, and a smaller binary
Cyclic foreign keys now seed end-to-end via deferred constraints and a post-insert wire-up pass. Catalog introspection drops from five round-trips to one. The npm tarball is 77.6% smaller.
- ·postgres
- ·satus
- ·release
- ·foreign-keys
- ·performance
- 8 min
The CITEXT trap
A seed job asked for 10,000 users and inserted 6,200. The unique index on a CITEXT column folded Alice and alice into one row. What CITEXT does, why new schemas avoid it, and what satus generates.
- ·postgres
- ·citext
- ·unique
- ·collations
- ·seeding
- 8 min
Partitioned tables meet RLS, and nobody wins
RLS policies on a partitioned parent do not protect the children. We hit this in two customer schemas last week. Here is what Postgres actually does, and the two-line workaround satus now prints.
- ·postgres
- ·rls
- ·partitioning
- ·seeding
- 11 min
Inside the medical-booking profile: why appointments are harder than they seem
Appointments cluster around mid-morning and afternoon, never at 3am, almost never on holidays, and trail a long tail of no-shows. What the satus medical-booking profile encodes, and why.
- ·profile
- ·medical
- ·distributions
- ·postgres
- ·seeding
- 7 min
NULL vs NOT NULL is not the question
A support ticket about a nullable column that broke an app. The real question is what NULL means to your code, and Postgres gives you three answers, not two.
- ·postgres
- ·null
- ·semantics
- ·seeding
- 2 min
Introducing the satus log
A plain-text changelog and field notebook for schema-aware seed data, written for engineers who read RFCs for fun.
- ·meta
- ·postgres
- 6 min
Cyclic foreign keys in the wild
Most seed-data tools pretend cycles don't exist. They do. Here is how satus splits the graph, inserts with NULLs, and back-patches in a second pass.
- ·postgres
- ·foreign-keys
- ·graphs
- ·seeding
RSS, no email required.
We do not run a newsletter. The full feed lives at /blog/rss.xml. Add it to any reader. There are no tracking pixels in the feed and no cookies on this site.