How eddy works

From a changed record to a customer answer.

Define the reporting model and eddy keeps its results updated as source records change. Your app and agents can query the data, or eddy can send it to another system.

Example screens and data. Our recorded query benchmark includes its workload and test setup.

01 · Using the data

Your app and agents use the reporting data.

Query the models through Postgres, HTTP or MCP, or push results to other systems. The example shows a SQL client and an agent reading the same report. Your app checks who can see each customer's data.

02 · Customer data

Keep track of each customer's data.

Shared source tables can feed separate reporting state for each customer. See how far each has updated and query their results. Your app decides who may access them.

  1. 1Customer list. See activity, rows and storage for each customer.
  2. 2Separate state. Each customer has a store and a log position, sharing one replication slot.
  3. 3One customer's results. Query that customer's store through the API.

03 · Define the model

Define the model in SQL or dbt.

A model defines the data behind the report. In the editor, see the SQL as steps and inspect each step's rows. Edits to the steps and SQL stay in sync. Preview support before building the model.

  1. 1Dependencies. See the tables and models this view uses, and which models use it.
  2. 2Query steps. Read the query top to bottom and inspect each step's rows.
  3. 3Step details. Open the join conditions, calculations and update costs.
  4. 4Editable SQL. Edits to a step change the corresponding SQL text.

04 · Corrections

A correction should reach the report.

A March refund is amended in April, from $1,200 to $3,600. Burnaby's March total rises to $8,400 and moves ahead of Vancouver. Follow the change into the model, report and agent answer.

1 · The source row

One March refund is amended.

Refund
#102 · account 42
Location
Burnaby
Refund date
March 11, 2026
Amount
$3,600 CAD

Amended in the source on April 2 at 10:00 UTC. The refund still belongs to March.

2 · The reporting model

Keep the definition in SQL.

select account_id, month, location,
       sum(amount) as refunded
from refunds
group by account_id, month, location

The source stores a reporting month for each refund. The model totals refunds by account, month and location.

3 · Your customer report

March refunds by location.

Account 42 · March 1–31, 2026
Source changes through April 2, 10:00 UTC

March refunds by location in Canadian dollars
LocationRefunded
Burnaby$8,400
Vancouver$6,200
North Vancouver$1,400

4 · Your customer agent

The same model answers the question.

Which of my locations had the most refunds in March?

“Burnaby had the most March refunds: $8,400 CAD. Account 42, March 1–31. Source changes included through April 2, 10:00 UTC.”
See the query for this account

Your app checks access to account 42 first. The dashboard and agent query the same model for that account and month. Parameters: 42 and 2026-03-01.

select location, refunded
from refunds_by_location
where account_id = $1 and month = $2
order by refunded desc, location

Example data and interfaces. The values are checked with reference SQL in SQLite. Sample rows, correction and SQL.

The report still covers March, but now includes the change saved in April. How reporting time works · Recorded SQL correctness checks.

05 · Change safely

See what a model change will do.

Compare the old and new definitions. See which rows change and which other results need rebuilding, then apply the replacement alongside the running system. The history records who asked for the change.

  1. 1The edit. Change a condition in the model's SQL.
  2. 2The comparison. Compare the old and new results over the same source rows.
  3. 3Changed accounts. See whose answer changes before applying the model.
  4. 4Online replacement. The new model builds alongside the running system and swaps in between update batches.

06 · Following updates

See how data reaches the report.

The graph connects source tables, models and the results your product uses. Follow a change through the models it affects, or open a customer's state to check their progress.

  1. 1Source updates. See Postgres commits and their positions in the replication log.
  2. 2Affected models. A change lights up the edges it crosses.
  3. 3Update delay. Compare the time from source commit to updated results with a plain Postgres view.
  4. 4Reporting results. See the rows available to your app and the engine's measurements.

More detail · Time and alignment

March's report, as it stood on April 2.

A correction saved on April 3 should be left out of a report queried as of April 2, even if the invoice is dated March 10. By default, time travel follows when changes were saved in the source system.

Business time

The business dates you filter, such as the invoice dates selected in a date picker.

Source persistence time

When the source system saved a change. The default timeline for time travel and alignment.

Arrival time

When eddy received the change. This may be later than when it was saved upstream.

Choose which inputs move forward together.

Each view or materialized view can align its inputs, with a database-wide default. An aligned view waits for all inputs to reach the same point in time. Newer changes wait until then. Unaligned inputs advance independently.

For example, query invoices and payments as of April 2 to compare them at the same point in time. The result tells you its as-of timestamp and timeline. You can configure which timeline to use.

For your pilot, confirm how much history is available and what happens if a query asks for a moment the data hasn't reached yet.

More detail · Contributing rows

See the rows behind a number.

For supported queries, follow a result back through joins and aggregates to its contributing rows. The lens shows the path and samples from current state.

  1. 1The selected result. Follow supported operators back to contributing rows.
  2. 2Its path. Highlight the parts of the graph that contributed.
  3. 3Sample rows. Inspect samples and counts from the rows currently stored at that step.
  4. 4Source records. See the current seat records contributing to this account's utilization.

More detail · Transaction tracing

Follow a source transaction through the models.

See the source commit and its changed rows, then follow the operators and results it affected. The trace helps explain how a correction reached the report.

  1. 1The commit. See the Postgres transaction, log position and SQL.
  2. 2Changed rows. See changes by table; a delete has weight −1.
  3. 3Affected operators. Follow which operators ran and what they emitted.
  4. 4Served. See the views changed by the transaction after the update batch finishes.

Let's look at your report.

Book a demo and bring the report, its source data and the questions customers ask.