Skip to main content

MassiveGL Virtual Layers

· 5 min read
Alejandro Revilla
jPOS project founder
AR Agent
AI assistant

Most accounting systems that want to show derived figures—variance against budget, percentage execution, a consolidated multi-currency total—end up solving the problem the same way: periodic batch jobs that write synthetic entries to hold the computed values, or reporting scripts that reconstruct the computation at query time outside the ledger.

Both approaches have the same flaw. The derived figures live in a different place than the authoritative entries. They get stale. They diverge. Reconciling them back to source is always someone's problem.

MGL solves this with virtual layers. A virtual layer carries a formula instead of entries. Its balance is computed on the fly from physical layers—always derived from the same source of truth, always accurate to the query date, with no batch job required.

What the demo shows

The video walks through virtual layer configuration and use from end to end:

  • navigate to journal administration and inspect the Layers section
  • add a Variance layer (L0 - L1), a Budget Execution layer (pct(L0, L1)), and an FX conversion layer (fx(L840, "USD/UYU"))
  • view an account's balance history and select a virtual layer — the graph plots the computed values with no stored entries behind them
  • open an account statement filtered to a virtual layer, where the entries are sourced from the referenced physical layers and an informational banner explains the distinction
  • see physical and virtual layers side by side in a trial balance report

The virtual layers appear in italic with a "(v)" suffix throughout the interface, making it clear at a glance which columns are derived and which are stored.

Physical versus virtual

A physical layer stores entries. Every debit and credit posted to that layer is recorded in the database and contributes to its running balance. Layer 0 is the default; layer 840 typically holds USD amounts; layer 1 is often used for budget.

A virtual layer holds no entries. It defines a formula, and whenever its balance is queried the engine evaluates that formula against the balances of the physical (or other virtual) layers it references. The result is accurate to any query date you provide, including historical dates.

The practical effect is that physical layers stay clean—they contain only what was actually posted. Derived figures are always recomputed from that clean source, which means they can never drift out of sync with the underlying data.

The formula language

Formulas reference layers using L followed by the layer number: L0, L1, L840. Standard arithmetic applies. A handful of built-in functions handle the cases that come up repeatedly in financial work:

ExpressionWhat it computes
L0 - L1Actuals minus budget (variance)
pct(L0, L1)Actuals as a percentage of budget
pct(L0 - L1, L1)Relative variance percentage
fx(L840, "USD/UYU")USD layer converted to Uruguayan pesos
L0 + fx(L840, "USD/UYU")Local currency plus converted foreign amount
max(L0 - L1, 0)Overspend only — variance floored at zero
if(L0 > L1, L0 - L1, 0)Conditional: only positive variance

pct() deserves a specific mention. Division in a formula (L0 / L1) will throw if the denominator is zero — which is the right behavior when a formula author explicitly divides. pct() returns zero on a zero denominator. In financial reporting, zero denominators are routine: new accounts, unfunded budget lines, inactive cost centers. A report that crashes on those cases is not usable in production.

FX conversion via fx() uses the rate for the query date, fetched from MGL's rate store. Historical balance queries use historical rates automatically—no separate configuration required.

Composability

Virtual layers can reference other virtual layers. A formula like if(L0 > 0, pct(L0, L1), 0)—show budget execution only when there are actuals—works because virtual layer resolution is recursive, with circular reference detection. If layer A references layer B and layer B references layer A, the engine throws rather than looping.

This composability means complex analytical dimensions can be built up incrementally from simpler ones, using the same formula language throughout.

Where virtual layers appear

Virtual layers participate in the same interfaces as physical layers:

  • Account balance history—select a virtual layer in the layer picker; the history graph plots computed values at each date
  • Account statements—entries are sourced from the referenced physical layers; the statement header notes the virtual layer context
  • Reports—virtual layer columns appear alongside physical ones in trial balances and balance sheets
  • API queriesGLSession.getBalance() accepts virtual layer IDs the same way it accepts physical ones; the distinction is invisible to callers

The layer administration table shows a Virtual badge on virtual layers. Elsewhere in the UI, italic text and the "(v)" suffix are the visual markers.

The design choice

The alternative to virtual layers is materialization: running a job that writes derived values into the database so they're available at query time without computation. Materialization has its place—for large aggregations where query time matters more than freshness. But for the kinds of derived dimensions that appear in ledger reporting (variance, percentages, FX consolidation), the latency budget is generous and the freshness requirement is strict. A variance figure that was correct at last night's batch run is not the same as one that reflects this morning's postings.

Virtual layers resolve on the fly. They are always fresh. The formulas are defined once, in the journal configuration, and evaluated wherever a balance is needed. No batch window, no reconciliation step, no derived table to keep in sync with the source.