Your state file forgets. Stategraph remembers.
Terraform state is a single overwritten snapshot; there's no built-in history of who applied what, when.
❯ stategraph tx list { "results": [ { "id": "102881bb-686b-49a0-a0ff-fce0ab3050ea", "created_at": "2026-06-08T19:35:57Z", "created_by": "f6eca568-3097-442c-bfe0-6b3593407feb", "state": "open", "params": {}, "tags": {} }, { "id": "…", "created_at": "2026-06-08T19:35:44Z", "completed_at": "2026-06-08T19:35:44Z", "created_by": "f6eca568-…", "state": "completed" } ] } ❯ stategraph tx logs list --tx 102881bb-… { "results": [ { "action": "create", "object_type": "resource", "state_id": "a3f1c0d2-…", "user_id": "f6eca568-…", "created_at": "2026-06-08T19:35:57Z" }, { "action": "update", "object_type": "output", "state_id": "a3f1c0d2-…", "user_id": "f6eca568-…", "created_at": "2026-06-08T19:35:57Z" }, { "action": "lock", "object_type": "state", "state_id": "a3f1c0d2-…", "user_id": "f6eca568-…", "created_at": "2026-06-08T19:35:57Z" } ] }
every apply · an immutable transaction · attributed to a user, queryable forever
A lock file is not an audit log
What you get
Immutable log
Every apply is written once as an append-only transaction. Nothing overwrites history — the past stays the past.
Full attribution (who)
Each change carries the user who made it. No more guessing who touched production at 2am.
Point-in-time view
Walk the timeline to see exactly what your infrastructure looked like at any moment in the past.
Query with SQL
The log lives in Postgres, so you ask questions in plain SQL. Pairs perfectly with SQL inventory.
Per-transaction tags
Attach tags and params to each transaction — ticket IDs, change windows, environments — and filter on them later.
Conflict detection metadata
Lock and unlock events are recorded inline, so you can see exactly when state was held and by whom.
Get a real audit trail
Stop bolting on external logging. Get an append-only, fully attributed, SQL-queryable history of every change — built into the state backend itself.