The reactive data plane

One change.
Every answer.

CalcGraph turns business logic into a living dependency graph. Publish once, and every affected value is invalidated, recomputed, and made consistent—automatically.

$192.84 +0.18%
Option Value $10.55
Desk Risk $81.4m
Monte Carlo VaR $2.80m

All prices, positions, risk figures, and event activity shown on this page are simulated for demonstration purposes and do not reflect actual market conditions.

Live dependency graph

Watch change find
its consequences.

CalcGraph follows only the affected edges, keeps the order deterministic, and ensures every result is up to date.

Reactive market risk dependency graph Four symbol-specific instances of MarketTick, Position, VolSurface, OptionValue, Exposure, Greeks, and MonteCarloVaR flow through one shared DeskRisk aggregate. SOURCE MarketTick 192.84 SOURCE Position +25k SOURCE VolSurface 24.6% CALCULATION OptionValue $10.55 CALCULATION Exposure $5.29m CALCULATION Greeks Δ 0.62 Γ 0.019 Θ -0.038 V 0.112 ρ 0.047 AGGREGATE · 4 SYMBOLS DeskRisk $81.40m CALCULATION MonteCarloVaR $2.8m

The topology, values, and cascade timing are simplified and simulated to make propagation easy to follow. They do not represent a production model or workload.

Graph as code

The picture begins
with a schema.

cg-lang, CalcGraph's own language, defines identity, inputs, triggers, and outputs. Modular Python implementations plug in as calculators and run as part of the reactive graph.

source MarketTick {
  symbol      String @id
  price       Float
  currency    String
  observed_at Timestamp
}

source Position {
  desk     String @id
  symbol   String @id
  quantity Float
}

source VolSurface {
  underlying   String @id
  expiry       Date
  implied_vol  Float
}

node OptionValue(tick: MarketTick, vol: VolSurface) -> (value Float) {
  on update(tick)
}

node Exposure(position: Position, option_value: OptionValue) {
  on update(position)
  on update(option_value)

  return {
    desk         String = position.desk,
    market_value Float  = position.quantity * option_value.value,
  }
}

node Greeks(
  tick: MarketTick,
  position: Position,
  vol: VolSurface,
) -> (
  delta Float
  gamma Float
  theta Float
  vega  Float
  rho   Float
)

node DeskRisk(exposure: Exposure) {
  return exposure
    .group_by { desk }
    .map { g in {
        gross_exposure Float = g.sum { market_value },
      }
    }
}

node MonteCarloVaR(
  exposure: Exposure,
  greeks: Greeks,
  risk: DeskRisk,
) -> (
  var                Float
  expected_shortfall Float
)

The graph definitions and calculator implementations are intentionally simplified for clarity. They omit production modeling, validation, error handling, and operational concerns.

Queryable state

A graph you can
query like a database.

CalcGraph exposes every source, calculation, and aggregate as a table. Ordinary SQL joins their latest values from one pinned snapshot.

SQL query Latest · pinned snapshot
SELECT
  mt.symbol,
  mt.price AS market_price,
  p.quantity AS position,
  ov.value AS option_value,
  e.market_value AS exposure,
  dr.gross_exposure AS desk_risk,
  v.var AS monte_carlo_var
FROM market_tick AS mt
JOIN position AS p
  ON p.symbol = mt.symbol
JOIN option_value AS ov
  ON ov.symbol = mt.symbol
JOIN exposure AS e
  ON e.symbol = p.symbol AND e.desk = p.desk
JOIN desk_risk AS dr
  ON dr.desk = e.desk
JOIN monte_carlo_var AS v
  ON v.symbol = e.symbol AND v.desk = e.desk
WHERE p.desk = 'EQUITY-OPTIONS';
Result set Version 12,840,231
Live SQL result for the demo risk graph
symbol market_price position option_value exposure desk_risk monte_carlo_var
AAPL $192.84 +25k $10.55 $5.29m $81.40m $2.80m
NVDA $182.40 +18k $12.24 $4.41m $81.40m $3.15m
MSFT $512.20 +12k $21.65 $5.20m $81.40m $2.45m
AMZN $238.60 +20k $13.54 $5.42m $81.40m $2.65m
Live notifications

Subscribe to exactly
what matters.

Match graph events by definition, identity fields, and event kind. CalcGraph replays and delivers the resulting feed over one long-lived, bidirectional gRPC stream.

Choose a subscription pattern Matched server-side
NotificationService.Subscribe gRPC stream
12840231:0 MarketTickSOURCE_PUBLISHED symbol=AAPL · price=$192.84
12840230:0 MarketTickSOURCE_PUBLISHED symbol=AAPL · price=$192.80
12840229:0 MarketTickSOURCE_PUBLISHED symbol=AAPL · price=$192.77
The complete system

No glue required.

CalcGraph sits between the data an organization publishes and every application that needs a fresh, consistent answer.

Inside your organization One deployment
Published data Market data Positions Curves & scenarios
CalcGraph Reactive data plane
Delivered to Risk APIs Dashboards Reports & alerts

One system owns the dependencies, recompute, history, and delivery.

Why we built CalcGraph

Essay · 5 min read

Complex systems eventually reveal themselves as networks of data, computation, and dependencies. CalcGraph began with a simple question: what if orchestration, computation, storage, history, and event propagation were designed as one graph from the start?

Read the full post Close the post

I often joke that nearly everything in the universe can be represented using graph theory. But think about it for a moment: since childhood, you’ve been surrounded by graphs. Your family tree. A sports tournament bracket. A subway map. Your network of friends. The roads connecting cities, the links between websites, the chain of dependencies in a software system, or the paths through which goods, money, and information move.

Human society itself has advanced by creating more connections. We build bridges between communities, open our economies to new participants, migrate across borders, exchange ideas across cultures, and ship products halfway around the world.

Asked to represent any of these systems with a pen and paper, you would probably begin by drawing a few points and connecting them with lines.

Nodes and edges.

Why am I bringing this up?

Because throughout my career as a software engineer, I’ve repeatedly encountered different versions of the same underlying problem and the industry as a whole has struggled with it too.

We’ve built databases that can answer complex queries in milliseconds. We’ve created reactive frameworks that fundamentally changed how applications are designed. We’ve built networks capable of moving enormous quantities of data at remarkable speeds.

And yet, once these pieces need to work together, we return to the same challenge: orchestration.

Orchestration may sound like a solved problem. For many products, it largely is. A few services, a job queue, some scheduled tasks, and a database may be all that is required.

But as a system grows, its complexity compounds. Computations begin to depend on other computations. Data arrives at different times and from different sources. A change in one part of the system must propagate through many others. Engineers must balance throughput, latency, data freshness, storage, reliability, and cost, often while maintaining infrastructure that was never designed for the scale it has reached.

What begins as a straightforward application gradually becomes a network of interconnected processes, dependencies, and data flows.

In other words, the problem becomes a graph.

Managing that network can require an entire team of engineers spending weeks or months designing, operating, and continuously repairing the machinery that keeps it all coordinated.

What begins as a simple workflow can quickly become an operational disaster. A batch job that completed in ten minutes six months ago may now require an entire night to run. And what happens when it fails halfway through? Will your team have enough time to diagnose the problem, fix it, and rerun the job before your users expect fresh data the next morning?

So why not solve the problem at its foundation?

Why not build a system that understands the relationships between processes and data, while embedding computation and logic directly into that model, so it can determine what needs to happen, when it needs to happen, and execute it as efficiently and granularly as possible?

That is what CalcGraph is: an orchestration engine and a computation engine built as a single system.

CalcGraph models the relationships between data, computations, and processes, then uses that model to determine what must run, when it must run, and what must be recomputed when something changes.

It provides its own declarative language, cg-lang, while remaining modular enough to execute business logic written in languages such as Python and Rust. Applications can subscribe to changes through its notification system, allowing updates to be broadcast as soon as new data arrives, a computation completes, or the state of the graph changes.

CalcGraph is also a database. It supports bitemporal data natively, allowing you to query not only what the system currently knows, but what it knew at any point in the past, and when that information became effective in the real world. This makes historical analysis, corrections, and auditing part of the data model rather than features that must be reconstructed afterward.

Its storage engine manages data across multiple tiers, keeping frequently accessed data close to computation while moving colder historical data to more cost-efficient, durable storage. The underlying storage location remains transparent to the application, so recent and historical data can be queried through the same interface.

Finally, CalcGraph is designed to scale without sacrificing availability or durability. Data and computation are partitioned into shards that can be dynamically redistributed across a cluster and coordinated through consensus. The system can scale vertically or horizontally while it is running, apply configuration and topology changes without requiring a restart, and recover safely from machine and network failures. Through replication, consensus, and durable storage, CalcGraph is designed to preserve committed data even when individual machines fail.

Orchestration, computation, storage, history, and event propagation are not separate systems stitched together around the edges. In CalcGraph, they are different parts of the same graph.