Self-hosted · Read-only · Open community

Know what changed in your financial data, and why.

FinDiff watches the database tables that quietly run your rates, fees and risk rules. Every insert, update and delete is caught, timestamped and explained, without FinDiff ever gaining the ability to write back.

Free to self-host · single Docker image · runs entirely on your own infrastructure

findiff — Diff Timeline
FinDiff Diff Timeline showing detected changes with an Expected badge
5Database engines supported
0Write permissions FinDiff ever needs
1Docker image to deploy
100%Self-hosted, your data stays put
Built for the people who own this problem

Not another dashboard nobody asked for

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.

Database administrators

Grant access without losing sleep

  • Generate the exact read-only GRANT SQL for your engine before connecting anything.
  • See the real scan footprint: queries run, duration, rows read, per table.
  • A statement guard, read-only transactions, and a dedicated role: three independent layers, not a promise.
Compliance & business

Stop chasing shrugs

  • Pre-declare a planned change and stop the false alarms it would otherwise trigger.
  • Export a date-ranged PDF report for an auditor in one click, no spreadsheet required.
  • Raw columns get real names: rate_code becomes "Interest Rate Table" in every report.
Engineering & platform

One binary, five engines, no agents

  • Postgres, MySQL, MariaDB, SQL Server and Oracle behind one interface, one deploy.
  • A live diff feed over WebSocket, plus alerts to Slack, Teams, email or any webhook.
  • Ask the AI copilot why something changed and get a plain-language answer with the query to check it.
Everything included

A complete observability layer, not a monitoring agent

No agents to install on the source database. No write access, ever. FinDiff sits next to your data and watches, the way an auditor would.

Read-only, structurally

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.

Schema mapping

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.

Live diff timeline

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.

Drift view

Compare two environments side by side, staging against production, region against region, and see exactly which rows disagree.

Data integrity checks

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.

Table groups

Cluster related tables into a named module, loan origination, pricing, risk, with one-click suggestions built from real foreign keys.

Alerting & retention

Slack, Microsoft Teams, email or a generic webhook on every change, plus a configurable retention window that exports before it prunes.

Built for scale

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.

AI copilot

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.

Built for scale

A 2 billion row table costs the same to watch as a 50 row one

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.

1st snapshot 100th snapshot
Naive full-copy-every-snapshot approach FinDiff
  • 01
    Bounded memory, always

    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.

  • 02
    One round trip beats a full read

    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.

  • 03
    Storage tracks your data, not your schedule

    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.

From zero to watching

Four steps, no schema changes required

FinDiff never issues a single ALTER against a database it monitors. Everything below is additive, on your side.

01

Connect with a read-only role

Generate the exact GRANT SQL for your engine, run it yourself, and connect FinDiff with credentials that structurally cannot write.

02

Map your schema

Scan the database once, then label tables and columns in language your team already uses, in-app or through the Excel round trip.

03

Let it watch

FinDiff snapshots on a schedule you set and catches every insert, update and delete the moment it happens.

04

Get the proof

Live alerts, a full audit trail, and a signed-off PDF report the moment someone asks who changed what.

A closer look

The product, not the pitch

Real screenshots, running against a seeded lending-platform dataset.

Schema Manager

Turn raw tables into a business glossary

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.

  • In-app mapping, or an Excel template a business owner can fill in
  • Table groups suggested automatically from real foreign keys
  • Per-column monitoring, so noisy audit columns don't drown the signal
findiff — Schema Manager
Schema Manager mapping raw tables to business labels and groups
Table Groups

The groups suggest themselves

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.

  • One click turns a suggestion into a real, named group
  • Works across all 5 engines, each with its own foreign-key query
  • Create a group by hand any time, suggestions are a shortcut, not a requirement
findiff — Schema Manager
Schema Manager suggesting a table group based on foreign keys
Diff Timeline

Every change, timestamped, and sorted from noise

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.

  • Live over WebSocket, filterable by table, type, database and date
  • Old and new values, side by side, down to the column
  • Expected-change windows that expire loudly if nothing happens
findiff — Diff Timeline
Expected changes panel showing a matched window and an expired window
Read-only role generator

Prove it. Literally.

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.

  • Correct syntax for Postgres, MySQL, MariaDB, SQL Server and Oracle
  • Scoped to monitored tables only, or every mapped table
  • No password is ever invented or stored. You fill that part in.
findiff — Read-only role SQL
Generated read-only GRANT SQL for a Postgres database
Per-engine connections

Real fields for Oracle, not a connection-string riddle

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.

  • Oracle: Service Name or SID, whichever your DBA actually gave you
  • Postgres, MySQL, MariaDB and SQL Server each get their own matching fields
  • Editing a database later can leave credentials untouched, only what you change gets sent
findiff — Add database
Add database form with Oracle-specific Service Name and SID fields
Data Integrity

See exactly what FinDiff is doing to your database

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.

  • Orphaned foreign keys, flagged automatically
  • Per-table scan duration and rows scanned, updated every run
  • Invalid compiled objects on Oracle, an honest "not applicable" elsewhere
findiff — Data Integrity
Data Integrity page showing referential integrity and scan footprint
Alerting

Slack, Teams, email, or your own endpoint

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.

  • Slack and Microsoft Teams webhooks, out of the box
  • SMTP email, or a generic HTTP webhook for anything else
  • A canonical payload shape, so parsing it once means parsing it everywhere
findiff — Settings
Alert channels configured for Slack and Microsoft Teams
AI Copilot

Ask why. Get an answer you can check yourself.

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.

  • Multi-turn, named, persistent conversations
  • File uploads, including PDF, folded into the context
  • Any OpenAI-compatible endpoint, or a fully local model, your choice
findiff — AI Copilot
AI Copilot answering a question about a loan status change with a SQL code block
Compliance export

One click, and the auditor has what they need

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.

  • Summary counts by change type, expected versus unexpected
  • Business labels pulled straight from Schema Manager
  • Generated on demand, nothing pre-stored or scheduled to leak
View a sample report
findiff — Export report
Export report modal for generating a compliance PDF
One interface, five engines

Wherever your configuration actually lives

PostgreSQLFull support
MySQLFull support
MariaDBFull support
SQL ServerNative change tracking
OracleNative SCN scanning
SQLiteMonitored source
Gallery

More of the interface

Use the arrows, the dots, or the left and right arrow keys. Click a shot to enlarge it.

Dashboard
FinDiff dashboard with an activity chart and recent system events
Dashboard: activity chart, and a live feed of what FinDiff itself is doing
Dashboard, table view
Dashboard activity chart switched to a table view with exact counts
Same data, as exact numbers, one click away from the chart
Databases
Databases page listing five engines
Every registered database, its engine, and its snapshot cadence
Table Groups
Tables organized into named business groups
Loan Origination, Risk & Compliance: tables grouped the way the business thinks about them
Drift View
Drift View comparing two Postgres environments
Drift View: two environments, compared table by table
System Health
System Health feed showing auth, webhook and adapter events
System Health: the whole app's diagnostic trail, not just data diffs
Settings
Settings page with users and alert channels
Users, alert channels, retention: all in one place
Sign in
FinDiff login screen
Self-hosted, read-only, your data never leaves this server
Get started

Running in under two minutes

One container, one environment variable that matters, no database migrations to run by hand.

docker run
# 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

Open documentation, self-hosted forever

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.