§00|The log

field notes from the satus team.


  1. 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
    6 min
  2. 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
    5 min
  3. 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
    8 min
  4. 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
    7 min
  5. 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
    11 min
  6. 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
    4 min
  7. 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
    6 min
  8. 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
    10 min
  9. 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
    12 min
  10. 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
    7 min
  11. 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
    5 min
  12. 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
    8 min
  13. 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
    15 min
  14. 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
    10 min
  15. 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
    7 min
  16. 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
    9 min
  17. 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
    5 min
  18. 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
    4 min
  19. 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
    9 min
  20. 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
    11 min
  21. 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
    14 min
  22. 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
    12 min
  23. 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
    8 min
  24. 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
    7 min
  25. 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
  26. 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
    8 min
  27. 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
    11 min
  28. 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
    7 min
  29. 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
    2 min
  30. 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
    6 min
§01|Subscribe

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.