FinDiff now exports and imports full database dumps, encrypted at rest, on PostgreSQL, MySQL, MariaDB, SQL Server, Oracle and SQLite, with live progress and logs, schedules, and expiring share links. Monitoring stays strictly read-only; importing is a separate, opt-in write path that you control.
Free to self-host · single Docker image · runs entirely on your own infrastructure Latest v1.1.1
Watch the demo · English voice-over, French subtitles, about 2½ minutes
Export any database to a dump encrypted at rest, import it into another one of the same engine, schedule both, and hand a dump to an auditor through a link that expires. Everything below runs on real data: a 163,043-row lending dataset on PostgreSQL and on Oracle.
Measured on the demo dataset shown in the screenshots below: PostgreSQL production to staging, and Oracle production to staging.
Pick a database and all tables or a selection. FinDiff only reads.
A dry run verifies the dump and compares it with the target schema. Nothing is changed.
Append or replace, in one transaction. Any error rolls everything back.
Schedules with retention, and share links with a limit, an expiry and an emailed code.
Export one table or the whole database. The table list is read live, with the owner shown for Oracle, and the job runs in the background so you can close the page and come back.

Importing writes, so the wizard says so up front and offers a check that validates the dump and the target schema and changes nothing. Replace mode asks you to type the database name before it deletes a single row.


Every job has a live log and a progress bar over a streaming connection. It resumes if the page reloads, and the full log stays with the job afterwards. Here is the real log of the Oracle import: nine tables cleared and loaded in one transaction.

Schedule an export every night with retention, or refresh staging from production every week. Imports only work on databases where an administrator has set up a separate write connection; the monitoring connection is never used to write.


Create a link that expires, allows a fixed number of downloads and can be revoked. Add a recipient and they must also enter a code emailed to that address. Editors cannot create links themselves: they ask, with a reason, and an administrator approves.


The link opens a small public page that says what it contains, when it expires and how many downloads are left. The file is a FinDiff dump that can be imported from the Dumps page of any instance.


The statement guard and read-only role are unchanged. Import uses its own connection that you add per database.
An import is a single transaction. If anything fails, the target is exactly as it was.
Exports, imports, shares and approvals land in the audit log with who did it and when.
Oracle is not an afterthought here. The screenshots in this release run against a real Oracle 23ai database, with the same 163,043 rows as on PostgreSQL and identical data-quality results.


| Engine | Export | Import | Good to know |
|---|---|---|---|
| PostgreSQL | Yes | Yes | Keys are read from the catalog, so a SELECT-only role still gets parents-first ordering |
| MySQL | Yes | Yes | Binary-log change feed available for monitoring |
| MariaDB | Yes | Yes | Same binary-log change feed as MySQL |
| SQL Server | Yes | Yes | Native change tracking for monitoring |
| Oracle | Yes | Yes | Owner-qualified table lists; new tables get their identity advanced, existing ones need a manual step |
| SQLite | Yes | Yes | Handy for local copies and tests |
Import runs on the same engine as the dump. Cross-engine type mapping is not supported yet.
A responsive interface with a slide-in menu, tables that scroll inside their card, and dialogs that fit a small screen. Approve a share request or check a dump from anywhere. Tap a phone to enlarge it.











This release lets you share data without the personal parts, send dumps to S3, Azure, SFTP or a NAS, and see your estate at a glance. It also adds single sign-on, two-factor sign-in, roles, an audit log, scheduled compliance reports, data quality rules and exact change feeds for large tables.
Companies often need to give an editor, a vendor or an auditor a copy of the data without the confidential parts. Tick Anonymise in an export, pick a template, and the personal columns are replaced while the dump is written: the original values never reach the file.

A template is a named set of rules. Pick it in a manual export or in a schedule, and the same people get the same protection every night. A schedule always uses the template as it is today, so fixing a rule fixes every future dump.

Copy every finished dump to an S3-compatible bucket (AWS S3, Cloudflare R2, MinIO, Backblaze, Wasabi), Azure Blob Storage, a NAS or server over SFTP, or a mounted folder. Choose destinations per export or per schedule, or push an existing dump with one click.

The dashboard now answers three questions: is everything being scanned, what changed, and are my dumps safe. A Needs attention list ranks problems by severity, each database has a health card with a daily sparkline, and administrators see the state of dumps and storage.

The version is shown in the sidebar and on the About page. When a newer release is published, administrators see a banner with the release notes and the two commands to update; everyone sees an update note in the sidebar.
FINDIFF_UPDATE_CHECK=false on networks that must not call out
Define unique, required and range checks per database and run them on demand. Results are real counts: here 2,432 loans are outside the policy range and 20 customer names are duplicated, on PostgreSQL and on Oracle alike. Monitoring coverage flags tables that cannot be diffed reliably.

Detected changes can be assigned, linked to a ticket, commented and acknowledged. Schema changes (DDL) and statistical anomalies have their own tabs next to data changes.

Sign in with your identity provider through OpenID Connect with PKCE, map provider groups to roles, and keep local accounts with two-factor sign-in where you need them. Every sensitive action is written to the audit log.


Schedule the compliance PDF for any database, weekly or monthly, and email it to the people who need it. Alert channels cover Slack, Teams, email, PagerDuty, Opsgenie and any webhook.


For very large tables, read PostgreSQL logical decoding or the MySQL and MariaDB binary log instead of scanning, with a safe fallback to a full scan.
pg_logical · mysql_binlogReference secrets from files or environment variables instead of storing connection passwords, and set TLS per connection.
FINDIFF_SECRETS_DIRA plain-language digest of the last 24 hours of changes, sent through your alert channels. Option to leave the actual values out.
OpenAI · Anthropic · Gemini · localDownload a consistent copy of FinDiff’s own store from Settings while it runs.
Liveness and readiness endpoints, and a token-protected metrics endpoint.
FINDIFF_METRICS_TOKENRuns as a non-root user with a built-in healthcheck, and an end-to-end browser test suite guards every release.
Keyboard navigable, screen-reader labels, light and dark themes, English and French.
Oracle-maintained schemas and objects are excluded so your results show your own data.
Create users as editor or viewer, force a password change on first sign-in, and manage everyone from one page.
FinDiff was built around three real conversations: the DBA asked to grant access, the compliance officer asked "who changed this," and the engineer asked to explain it all after the fact.
No agents to install on the source database. Monitoring never writes: FinDiff sits next to your data and watches, the way an auditor would. Importing a dump is a separate, opt-in path.
A statement guard rejects anything that isn't SELECT, read-only transactions where the driver allows it, and a generator for the dedicated database role to run it all under. Dump import uses its own, separate write connection that is off until an administrator adds it.
Map raw tables and columns to business labels in-app, or export an Excel template, hand it to a business owner, and re-import their answers with per-row validation.
Row-level SHA-256 diffing between snapshots, streamed to the UI over WebSocket the moment a change is detected. Filter by table, change type, date range or database.
Compare two environments side by side, staging against production, region against region, and see exactly which rows disagree.
Referential integrity across every foreign key, invalid compiled objects on Oracle, and a scan footprint report showing exactly what FinDiff's own jobs cost you.
Cluster related tables into a named module, loan origination, pricing, risk, with one-click suggestions built from real foreign keys.
Slack, Microsoft Teams, email or a generic webhook on every change, plus a configurable retention window that exports before it prunes.
Keyset pagination, in-database checksums, and watermark or native change-tracking incremental scans keep a billion-row table just as cheap to watch as a small one.
Ask questions in plain language over both the diff history and FinDiff's own health events. Works with OpenAI, Anthropic, Gemini, or a fully local Ollama or LM Studio model.
Most drift-detection scripts get quietly abandoned the day someone points them at a real production table. FinDiff was designed around the opposite assumption from the start: tables get big, and snapshots happen often.
FinDiff pages through a table by primary key, one fixed-size page at a time. Scanning row one million costs exactly the same as scanning row one.
Most engines let FinDiff ask "did anything change" with a single lightweight database-side checksum, so an untouched table is skipped entirely instead of re-compared row by row.
FinDiff keeps one current state per row, updated in place. Snapshot every five minutes for a year and the count barely moves, unlike a tool that copies the whole table each time.
FinDiff never issues a single ALTER against a database it monitors. Everything below is additive, on your side.
Generate the exact GRANT SQL for your engine, run it yourself, and connect FinDiff with credentials that structurally cannot write.
Scan the database once, then label tables and columns in language your team already uses, in-app or through the Excel round trip.
FinDiff snapshots on a schedule you set and catches every insert, update and delete the moment it happens.
Live alerts, a full audit trail, and a signed-off PDF report the moment someone asks who changed what.
Real screenshots, running against a seeded lending-platform dataset.
rate_code and tier_id mean nothing to a compliance officer. Map them once to "Interest Rate Table" and "Risk Tier," group related tables into modules, and every future report speaks the business's language, not the schema's.
Click "Suggest" and FinDiff reads the live foreign keys already in your schema, clusters tables that reference each other, even transitively, and offers them up as a ready-made group. Loan, payment, and status-history tables that nobody explicitly linked in FinDiff show up bundled together anyway, because the database already told us they belong together.
A quarterly rate reset and an unexplained Friday-afternoon edit used to look identical in the log. Pre-declare the ones you expect, and every matching change gets flagged, so what's left is what actually needs a look.
Every DBA has heard "don't worry, it's read-only" before. FinDiff generates the exact CREATE ROLE and GRANT SELECT statements for your engine, scoped to only the tables you've mapped, so you can verify the claim instead of trusting it.
Oracle asks for a host, port, and a Service Name or a SID, two genuinely different things that a single freeform connection string always gets wrong for someone. FinDiff's Add Database form asks each engine for exactly what it needs, Oracle included, and builds the correct connection string for you.
Referential integrity checks catch orphaned rows across every foreign key. The scan footprint report goes further: real run counts, durations and rows read per table, so "it's lightweight" is a number, not a promise.
The moment a change is detected, FinDiff can push it wherever your team already looks. Configure as many channels as you need, each one is independent, so a critical rate table can alert a Slack channel while everything else just accumulates quietly in the timeline.
The copilot reasons over both the diff history and FinDiff's own operational events, so "why did this change" and "why did the connection start failing" are answered by the same feature. Every answer that matters comes with the query to verify it.
Pick a date range and get a PDF: every change, its business label, whether it was expected, and a summary count by type. No CSV to reformat, no manual pull from the audit log the night before a review.
Use the arrows, the dots, or the left and right arrow keys. Click a shot to enlarge it.
One container, one environment variable that matters, no database migrations to run by hand. Optional settings for dumps, SSO and secrets are in the manual.
# pulls the official image and starts FinDiff on port 8080 docker run -d --name findiff \ -p 8080:8080 \ -e FINDIFF_MASTER_KEY="$(openssl rand -base64 32)" \ -e FINDIFF_ADMIN_USERNAME=admin \ -e FINDIFF_ADMIN_PASSWORD=change-this-immediately \ -v findiff_data:/data \ oubaidhl/findiff:latest
The community repository has the full README, deployment templates, and a Discussions board for questions, feature ideas, and bug reports. FinDiff ships as a versioned Docker image so every install is a tested build.