pg_dump ergonomics for production-like test data
feint is a single Rust binary for Postgres. Generate schema-aware synthetic data from nothing, clone a real database with sensitive columns masked as it streams, or mask a database's own columns in place. No ORM, no config server, no Docker stack, and no Postgres extension to install.
15/15 nasty schemas handled correctly · No Postgres extension · MIT licensed
$ feint init postgres://localhost/myapp 6 tables 5 foreign keys Sensitive fields detected: users.email email users.phone phone payments.card_last4 potential_identifier Generated feint.yaml $ feint up postgres://localhost/myapp ✓ 6 tables, 600 rows generated ✓ All foreign keys valid
Three modes, one binary
Generate
feint init / plan / up build synthetic data straight from your schema. Nothing real is ever involved.
Clone
feint clone copies real rows from a source database to a target, keeping keys intact and masking sensitive columns as it streams.
Mask
feint mask rewrites a database's own sensitive columns in place, batched and resumable, for a database that already has a full copy of production.
Built for real schemas, not toy demos
feint understands foreign keys, enums, arrays, JSONB, UUIDs, domains, and cyclic references. It never guesses wrong about your constraints; if a run succeeds, your data is valid.
Extension-free
feint connects like any client. It runs unmodified against RDS, Aurora, Cloud SQL, or Neon, none of which grant superuser or install extensions.
Deterministic
Every run is seeded. The same seed and the same schema produce byte-for-byte identical output, every time, across generate, clone, and mask alike.
Fail-closed masking
A classification lockfile and --strict refuse to run when the live schema drifts from what was reviewed, so a new column nobody classified never quietly passes through unmasked.
Coming from somewhere else?
feint reads another tool's config and converts what it mechanically can, flagging the rest for a manual look, so a migration starts from something real instead of a blank file.
Frequently asked questions
Is feint free and open source?+
Yes. feint is MIT licensed and hosted on GitHub. There is no paid tier, no account, and no hosted service required to use it.
Does feint need a Postgres extension?+
No. feint connects like any normal Postgres client and does everything from the client side, so it runs unmodified against managed Postgres that will not grant superuser or install extensions, such as RDS, Aurora, Cloud SQL, or Neon.
What is the difference between generate, clone, and mask?+
"feint up" generates synthetic data from your schema alone, with nothing real involved. "feint clone" copies real rows from a source database to a target database, masking sensitive columns as it streams. "feint mask" rewrites a single database’s own sensitive columns in place, with no second database, which is the right tool after a cloud snapshot restore.
Is the generated or masked data actually valid?+
feint reads your schema’s foreign keys, enums, arrays, JSONB, UUIDs, domains, and cyclic references before writing anything, so a run either succeeds with constraint-valid data or fails with a clear error — it does not guess and silently produce broken rows.
Is masking deterministic?+
Yes. Every run is seeded, so the same seed and the same input always produce the same output, and a masked column maps the same source row to the same fake value whether you reach that row through clone or mask, today or next month.
Install feint
Linux and macOS, one line, no dependencies to manage first.
curl -fsSL ewry.net/feint.sh | sh