The product, up close
See every change, and why.
eddy is a live system you can look inside: the graph as it runs, each model as steps, a change reviewed before it is made, any number traced to its rows.
Renderings of the product’s own screens with example data. The measured numbers are on the overview.
01 · Pipeline
The whole system, running.
Postgres on the left, every model in the middle, what your readers see on the right. Each change is visible on the edges it crosses.
where account_id=57
and id > 14;
| account_id | name | mrr | seats | risk |
|---|---|---|---|---|
| 42 | Northwind | 14,420 | 39 / 40 | low |
| 57 | Contoso | 8,900 | 14 / 40 | high |
| 88 | Glenmore | 22,150 | 71 / 80 | low |
| 103 | Inkwell | 3,600 | 9 / 20 | watch |
| 131 | Meridian | 41,300 | 188 / 200 | low |
| 164 | Brightline | 12,800 | 21 / 50 | watch |
| 201 | Kestrel | 6,250 | 12 / 25 | watch |
| 233 | Halden | 18,700 | 60 / 60 | low |
| 260 | Norrland | 2,900 | 4 / 10 | high |
| 287 | Corvid | 9,450 | 30 / 30 | low |
| 301 | Tallis | 5,100 | 11 / 15 | low |
| 322 | Ashgrove | 27,600 | 90 / 120 | low |
| 345 | Verity | 1,800 | 2 / 5 | watch |
| 371 | Fernwood | 4,400 | 14 / 15 | low |
| 398 | Lumen | 15,050 | 49 / 60 | low |
| 412 | Orbis | 7,700 | 21 / 40 | watch |
- 1Postgres, as it happens. every commit through the slot, with its LSN and what it took; run a scene or your own SQL
- 2The graph, live. every model and the operators under it; a change lights only the edges it crosses
- 3Fresh, and how fresh. commit to every model current, against the same report as a plain Postgres view
- 4The view itself. the rows your app, dashboards and agents read, and the engine’s own numbers underneath
02 · Model workspace
A model is SQL you can read as steps.
Every step shows the rows it outputs. Change a step or the SQL; they stay in sync, and the SQL stays the source of truth.
| account_id | name | used | seats | events_30d |
|---|---|---|---|---|
| 42 | Northwind | 39 | 40 | 1,904 |
| 57 | Contoso | 14 | 40 | 31 |
| 88 | Glenmore | 71 | 80 | 2,377 |
| when | events_30d < 50 and used·2 < seats | 'high' |
| when | events_30d < 200 | 'watch' |
| else | 'low' |
- 1Where it sits. what the model reads, its stages, and what reads it
- 2Every step, with its rows. the query read top to bottom, each step checked by the planner
- 3The step, opened. conditions as rows, a CASE as a table, and what it costs to keep fresh
- 4The SQL stays the truth. an edit to a step is a splice of the text it changes, never regenerated
03 · Review
Know what a change does before it ships.
Both definitions run over the data as it is. You see the rows that would move, what rebuilds, and how long it takes — then apply it while everything keeps running.
+ case when u.events_30d < 80
| w | account_id | name | events_30d | risk |
|---|---|---|---|---|
| −1 | 164 | Brightline | 66 | watch |
| +1 | 164 | Brightline | 66 | high |
| −1 | 201 | Kestrel | 72 | watch |
| +1 | 201 | Kestrel | 72 | high |
| −1 | 345 | Verity | 58 | watch |
| +1 | 345 | Verity | 58 | high |
- 1The edit. one condition changed, in the model’s own SQL
- 2What it does to the data. both definitions run by Postgres over the tables as they are, compared row for row
- 3The rows that move. every account whose answer changes, before anything changes
- 4Applied while it runs. the build happens beside the running tenant, and Postgres judges it from its first change
04 · Provenance
Every number explains itself.
Click a row and eddy walks it back through the joins and aggregates to the source rows that made it, lighting the path on the graph.
viewaccount_health
| account_id | name | used | events_30d | risk |
|---|---|---|---|---|
| 57 | Contoso | 14 | 31 | high |
aggregateusage_30d · group 57
| account_id | events_30d |
|---|---|
| 57 | 31 |
joinseat_utilization · key 57
| account_id | used | seats |
|---|---|---|
| 57 | 14 | 40 |
sourceseats · account 57
| w | id | account_id | removed_at |
|---|---|---|---|
| −1 | 15 | 57 | Sep 22 14:02 |
| −1 | 16 | 57 | Sep 22 14:02 |
| −1 | 17 | 57 | Sep 22 14:02 |
sourceusage_events · account 57
| event | user | at |
|---|---|---|
| report.viewed | u_1182 | Sep 25 09:14 |
| export.run | u_0413 | Sep 24 16:40 |
- 1Click any row. in any view, and the lens walks the plan back to the tables
- 2The path, lit. only the operators this row came through; the rest of the graph dims
- 3Real rows at every step. read from each operator’s own state, never a summary
- 4Down to the source. the fourteen seats removed on Sep 22 — the answer to “why is this high?”
05 · Trace
One transaction, end to end.
Follow a single commit from Postgres through each operator it reached to the views it changed, each one judged by Postgres.
delete from seats where account_id = 57 and id > 14;Remove seats · run from this page
| w | id | account_id | role |
|---|---|---|---|
| −1 | 15 | 57 | viewer |
| −1 | 16 | 57 | viewer |
| −1 | 17 | 57 | editor |
| … |
- 1The commit. as Postgres saw it: transaction, position, SQL
- 2The rows it carried. per table, each with its weight: a delete is −1
- 3Only what it reached. the operators that did work, in order, and what each emitted
- 4Judged. every view that changed, recomputed by Postgres and compared
06 · Customers
A thousand customers, each on its own.
Shared tables in, a store per customer out. See which customers are busy, what each one costs, and read any one of them alone.
| account_id | name | rows served | store | ticks / h | last hour |
|---|---|---|---|---|---|
| 131 | Meridian | 1.9M | 58 MB | 412 | |
| 322 | Ashgrove | 1.1M | 31 MB | 377 | |
| 88 | Glenmore | 842k | 22 MB | 301 | |
| 42 | Northwind | 610k | 17 MB | 288 | |
| 398 | Lumen | 402k | 11 MB | 240 | |
| 233 | Halden | 377k | 9.8 MB | 203 | |
| 164 | Brightline | 291k | 7.6 MB | 177 | |
| 412 | Orbis | 188k | 4.1 MB | 131 | |
| 57 | Contoso | 164k | 3.9 MB | 118 | |
| 287 | Corvid | 120k | 2.7 MB | 96 | |
| 201 | Kestrel | 96k | 2.2 MB | 71 | |
| 301 | Tallis | 61k | 1.4 MB | 52 | |
| 371 | Fernwood | 33k | 720 KB | 31 | |
| 103 | Inkwell | 19k | 440 KB | 18 | |
| 345 | Verity | 6k | 160 KB | 4 |
Northwind
| account_id | name | mrr | risk |
|---|---|---|---|
| 42 | Northwind | 14,420 | low |
- 1Every customer, one row. the most active first: rows served, store size, ticks
- 2Its own state. a store and a position in the log per customer, one replication slot for all
- 3Read one alone. the same API, scoped to one customer, from that customer’s store
07 · Agents and SQL
Read it from an agent, or from psql.
The same live views over MCP for agents and over the Postgres protocol for everything else. An agent can act through your own API and read the result on its next step.
select account_id, name, mrr from eddy.account_health
where risk = 'high' order by mrr desc limit 5
→ 2 rows · Contoso 8,900 · Norrland 2,900{ "view": "account_health", "row": { "account_id": 57 } }
→ seats: 14 rows removed Sep 22 · usage_events: 31{ "account_id": 57, "removed_at": "2026-09-22T14:02" }
→ committed · 14 seats{ "view": "account_health", "where": "account_id = 57" }
→ used 28 / 40 · risk: watch · as of the commitacme=> \timing on acme=> select account_id, name, mrr, risk from eddy.account_health where risk <> 'low' order by mrr desc limit 6; account_id | name | mrr | risk ------------+------------+--------+------- 164 | Brightline | 12,800 | watch 57 | Contoso | 8,900 | watch 201 | Kestrel | 6,250 | watch 103 | Inkwell | 3,600 | watch 260 | Norrland | 2,900 | high 345 | Verity | 1,800 | watch (6 rows) Time: 0.4 ms acme=> select count(*) from eddy.mrr_by_plan; count ------- 4 (1 row) Time: 0.2 ms
See it on your own schema.
Tell us a metric you’d want live. We’ll show it running, with every step visible.