---
title: "Digital Twin Architecture: The Database Guide"
description: " How to architect the database and data model behind a digital twin: schema, SQL examples, and a framework for choosing the right database. "
section: "Postgres for IoT"
---

> **TimescaleDB is now Tiger Data.**

This page covers the data-infrastructure layer underneath a digital twin. If you're shopping for twin-modeling or visualization software, Azure Digital Twins, NVIDIA Omniverse, and Ansys are the products to look at, and we'll point you back to them later in this guide. If you're the engineer who has to store and query the data those tools (or your own dashboards) run on, keep reading.

Digital twin architecture is the database and data layer that stores a physical asset's live sensor readings alongside its historical state, continuously reconciling what the twin expects against what's actually observed, so simulation, alerting, and dashboards can all query one synchronized source of truth.

That single database and data layer does two things at once: it holds the live, current state of the physical asset, and it holds the historical state used to train and validate the twin's model. It sits underneath the twin's simulation or machine learning logic. This guide covers the **database for digital twin** projects, meaning the storage and query engine, and the **digital twin data model**, meaning how asset metadata, real-time state, and historical state get structured within that engine.

A digital twin lives or dies on how well its data layer reconciles what the twin expects against what its sensors actually observed, in real time and against history, from one place. Get that reconciliation slow or split across systems, and the twin stops being a twin. It becomes a dashboard with a good name.

## Digital twin vs. simulation: why the distinction matters for the data layer

A simulation models a system in the abstract. It answers "what would happen under these conditions," using assumptions rather than live measurements. A digital twin is different: it's continuously synchronized to a specific physical asset's live sensor data, answering "what is happening right now, compared to what we expected."

That distinction has a direct data-layer consequence. A pure simulation doesn't need a continuous, high-frequency ingest path; it runs on parameters rather than streams. A digital twin does. Its database has to sustain ongoing writes from real sensors, hold enough history to know what normal looks like, and serve both at query time. Simulation software can be stateless between runs. A digital twin's data layer never is.

## What a digital twin's data layer actually has to do

Four jobs pull in different directions, and architecting for all four at once is the problem this page solves.

**Real-time state.** The live half of the twin: current sensor readings representing the physical asset's condition right now. This is what a dashboard or an alerting rule reads first.

**Historical state.** The half that trains and validates the twin's model. A model that has only seen a few days of data hasn't learned what "normal" or "failing" actually look like across the asset's operating range.

**High-frequency sensor and telemetry ingestion.** The continuous feed of vibration, temperature, pressure, and other readings that populates both of the above. This is the pipe everything else depends on.

**A reconciliation layer.** Comparing expected behavior against observed behavior is the core pattern behind a hybrid physics-plus-machine-learning digital twin. [<u>Mechademy's Turbomechanica platform</u>](https://www.tigerdata.com/blog/how-mechademy-cut-hybrid-digital-twin-infrastructure-costs), covered in the worked example below, runs exactly this pattern for turbomachinery.

Fast writes, long retention, and fast queries push against each other. A schema tuned for one while ignoring the others becomes a bottleneck the moment the twin scales past a handful of assets.

## Why this is harder than a normal time-series workload

Two consumption patterns run against the same underlying schema: a live query answering "what is this twin's state right now," and a historical export feeding model training and validation. That's the same pattern already established for [<u>predictive maintenance data</u>](https://www.tigerdata.com/learn/predictive-maintenance-database), where one schema serves both real-time alerting and training exports without an ETL step keeping two systems in sync. A digital twin adds a wrinkle predictive maintenance usually doesn't: many twins also carry a spatial or AI-driven-matching component.

Consider where geospatial and vector matching enter the picture. A 3D or spatial twin needs to store asset positions and geometry. An AI-driven twin needs to compare a live sensor reading against thousands of historical operating states to flag an anomaly, which is a similarity search. Running hypertables, PostGIS, and pgvector in the same Postgres instance means one stack handles time-series ingestion, spatial queries, and vector search together, rather than three separate systems bolted together with their own sync jobs and failure modes.

In a digital twin, the sensor feed itself looks like any other high-frequency industrial IoT stream. What's different is that a twin also has to hold a live, queryable model of "expected" state to compare that feed against, continuously, not just store it.

## Architecture: schema, continuous aggregates, and compression for digital twin state

The schema and SQL below run on Tiger Cloud or a self-hosted TimescaleDB instance, using hypertables, continuous aggregates, and hypercore columnstore compression on top of standard PostgreSQL. The plain CREATE TABLE statements are ordinary Postgres.

### Modeling twin state as time-series rows

Start with a metadata table for physical assets and their twins, and a narrow-row hypertable for state and sensor readings:

`CREATE TABLE assets (
    asset_id     TEXT PRIMARY KEY,
    twin_id      TEXT NOT NULL,
    asset_type   TEXT NOT NULL,
    install_date DATE
);

CREATE TABLE twin_state (
    time        TIMESTAMPTZ NOT NULL,
    asset_id    TEXT NOT NULL REFERENCES assets(asset_id),
    sensor_type TEXT NOT NULL,
    value       DOUBLE PRECISION NOT NULL,
    unit        TEXT
);

SELECT create_hypertable('twin_state', by_range('time'));`

`create_hypertable()` is the concrete first step: it partitions `twin_state` by time so queries stay bounded as the twin's history accumulates, instead of scanning further back with every added day of operation. The `assets` table carries the relational metadata (which twin, which asset type, when it went live) that the reconciliation queries below join against.

### Continuous aggregates for reconciling expected vs. observed state

Without a pre-computed rolling comparison, every "is this twin drifting from expected behavior" check re-scans raw high-frequency readings, and that gets slower as history grows. A continuous aggregate keeps that check fast regardless of how much history has piled up, because it reads pre-computed buckets instead of raw rows:

`CREATE MATERIALIZED VIEW twin_state_hourly
WITH (timescaledb.continuous, timescaledb.materialized_only = false) AS 
SELECT
    time_bucket('1 hour', time) AS bucket,
    asset_id,
    sensor_type,
    avg(value) AS avg_value
FROM twin_state
GROUP BY bucket, asset_id, sensor_type;

SELECT add_continuous_aggregate_policy('twin_state_hourly',
    start_offset      => INTERVAL '3 hours',
    end_offset        => INTERVAL '1 hour',
    schedule_interval => INTERVAL '1 hour');`

This is the SQL-level version of the reconciliation pattern from the previous section. A baseline table holding each asset's expected operating range turns the rollup into an actual comparison:

`CREATE TABLE twin_baseline (
    asset_id     TEXT NOT NULL REFERENCES assets(asset_id),
    sensor_type  TEXT NOT NULL,
    expected_avg DOUBLE PRECISION NOT NULL,
    PRIMARY KEY (asset_id, sensor_type)
);

SELECT h.asset_id, h.sensor_type, h.avg_value, b.expected_avg,
       h.avg_value - b.expected_avg AS deviation
FROM twin_state_hourly h
JOIN twin_baseline b USING (asset_id, sensor_type)
WHERE h.bucket > now() - INTERVAL '1 hour'
  AND abs(h.avg_value - b.expected_avg) > 0.1 * b.expected_avg;`

That last query is the reconciliation layer in practice: expected vs. observed, computed from a rollup instead of raw rows, filtered to whatever deviation threshold matters for the asset.

### Hypercore compression and tiered retention for long-run twin history

A twin's model needs years of history to stay accurate across an asset's lifecycle, and storing all of it at full resolution gets expensive fast. Apply columnstore compression (hypercore) after a short rolling window, commonly seven days, so recent data stays in row format for fast writes while older data converts to columnar storage for efficient scans:

`ALTER TABLE twin_state SET (
    timescaledb.enable_columnstore,
    timescaledb.segmentby = 'asset_id, sensor_type',
    timescaledb.orderby   = 'time DESC'
);
CALL add_columnstore_policy('twin_state', after => INTERVAL '7 days');`

Pair that with tiered retention: full-resolution recent data for immediate comparison, downsampled or compressed older data for the multi-year history a twin's model needs. See [<u>Time-Series Downsampling: The Complete Guide</u>](https://www.tigerdata.com/learn/time-series-downsampling) for the downsampling methodology itself. A retention policy on the raw table handles the far end of that tier:

`SELECT add_retention_policy('twin_state', INTERVAL '3 years');`

### Where PostGIS and pgvector fit for spatial and AI-driven twins

Two capabilities run in the same Postgres instance as the time-series data, and neither requires standing up a separate system. PostGIS handles spatial and geometric asset positions, relevant to a building, grid, or facility twin that needs to know where an asset physically sits. pgvector handles embedding-based anomaly matching, comparing a live sensor reading against thousands of historical operating-state embeddings.

Here's a clearly labeled hypothetical, not a real deployment: consider a building or grid-asset digital twin that needs to place assets on a floor plan or map.

`-- Hypothetical: spatial position for a facility-twin asset
CREATE TABLE asset_locations (
    asset_id TEXT PRIMARY KEY REFERENCES assets(asset_id),
    geom     GEOMETRY(Point, 4326)
);`

Now consider that same hypothetical twin needing to match a live sensor reading against thousands of historical operating states to flag an anomaly:

`-- Hypothetical: similarity search against historical operating-state embeddings
CREATE TABLE twin_state_embeddings (
    asset_id  TEXT NOT NULL REFERENCES assets(asset_id),
    time      TIMESTAMPTZ NOT NULL,
    embedding VECTOR(128)
);

SELECT asset_id, time
FROM twin_state_embeddings
ORDER BY embedding <-> '[...]'
LIMIT 10;`

That's a pgvector similarity search running directly against the same Postgres instance holding the time-series history, not a separate vector database bolted on. It's a "one stack" argument that most single-purpose time-series databases can't make as directly, since they don't carry spatial or vector search natively.

## Worked example: a hybrid digital twin for rotating industrial equipment

[<u>Mechademy</u>](https://www.tigerdata.com/blog/how-mechademy-cut-hybrid-digital-twin-infrastructure-costs) builds hybrid digital twins for the oil, gas, and LNG industry. Its Turbomechanica platform fuses physics-based turbomachinery models with domain-informed machine learning to model compressors, turbines, and full refrigeration trains, monitoring assets that represent roughly 6% of the world's LNG production.

Mechademy originally built its diagnostics platform on MongoDB, which fit the early priority: fast iteration on data structures while the diagnostics logic itself was still taking shape. As the platform matured, the fit broke down. Diagnostic tests needed time-aligned data at multiple resolutions, 15-second raw streams, 1-minute aggregates, hourly summaries, and MongoDB had no native way to produce those pre-aggregated rollups. The team built manual time-bucketing workarounds instead, which grew into deeply nested aggregation pipelines that became more brittle and expensive to operate as diagnostic volume grew. By the time CPU utilization was sitting above 95% at around 10,000 diagnostic tests per small tenant every half hour, the workarounds had become the bottleneck.

Mechademy migrated to Tiger Data. Hypertables replaced the manual time-bucketing, automatically partitioning diagnostic data by time. Continuous aggregates replaced the nested MongoDB aggregation pipelines, producing the same multi-resolution rollups the diagnostics needed, but as a background computation instead of a query-time pipeline reconciling expected turbomachinery behavior against observed readings.

The result: an 87% reduction in infrastructure costs, and a 50x increase in workload capacity, from 200,000 to 10,000,000 diagnostic tests per half hour, on hardware smaller than the prior MongoDB setup required.

While this use case is industrial IoT diagnostics for rotating equipment in oil, gas, and LNG operations, not a discrete-manufacturing or consumer-facing digital twin, the architecture pattern, reconciling expected against observed state from one time-series store, holds regardless of vertical. A grid digital twin runs the same pattern; [<u>Plexigrid's move from four databases to one</u>](https://www.tigerdata.com/blog/from-4-databases-to-1-how-plexigrid-replaced-influxdb-got-350x-faster-queries-tiger-data) for real-time grid visibility is a shorter version of the same story in a different industry.

## Digital twin data layer vs. generic relational databases, NoSQL, and data lakes

| **Digital twin data layer (Tiger Data’s TimescaleDB)** | **Generic relational database** | **NoSQL document store** | **Data lake / object storage** |
| --- | --- | --- | --- |
| **What it is** | Postgres extended with hypertables, continuous aggregates, and columnstore compression | Standard relational database with no native time partitioning | Schema-flexible document store (e.g., MongoDB) | Raw file/object storage for unstructured or semi-structured data |
| **Query language** | SQL | SQL | Vendor query language, aggregation pipelines | Depends on engine layered on top; not query-native |
| **Best-fit use case** | One schema serving live twin-state queries and historical export for model training | Low-volume transactional data without time-series access patterns | Early-stage prototyping with rapidly changing schemas | Raw waveform, thermal imagery, or point-cloud data for a spatial twin |
| **Strengths** | SQL joins between sensor readings and asset metadata; no ETL between real-time and historical views; PostGIS and pgvector in the same instance | Familiar, ACID-compliant, broad tooling support | Flexible schema during early iteration | Cheap storage at scale for unstructured data; pairs well with a relational layer for structured features |
| **Limitations** | Not a substitute for a dedicated 3D modeling or visualization platform; not a substitute for object storage on raw waveform data | No time-based partitioning or compression; queries slow down as history accumulates | Nested aggregation pipelines get slower as sensor volume and schema complexity grow, as Mechademy's migration shows directly | No native time-series query capability; not a fit for structured, timestamped readings |

TimescaleDB isn't a replacement for a dedicated twin-modeling or visualization platform like Azure Digital Twins or NVIDIA Omniverse; teams that need the twin's simulation logic or a 3D rendering layer still need that separately. And raw high-frequency waveform captures, thermal imagery, or point-cloud data for a spatial twin belong in object storage, not a relational time-series table, the same concession that applies to predictive maintenance workloads.

## Decision framework

What database should you use for a digital twin? Four axes decide it: the shape of your sensor data (structured and numeric vs. raw waveform, imagery, or point-cloud), whether live and historical queries need to run against one schema without an ETL step, whether SQL joins between sensor readings and asset metadata matter, and whether the twin carries a spatial or AI-driven anomaly-matching component. Weigh those four against your own system below.

**Choose a digital twin data layer built on Tiger Data if:**

- You need one schema to serve both live "current twin state" queries and historical export for model training and validation, without keeping two systems in sync
- Your twin's sensor data is structured or numeric (temperature, pressure, vibration features, positional data) rather than primarily raw waveform, imagery, or point-cloud capture
- You need SQL joins between sensor readings and asset or twin metadata without a separate ETL step
- Your twin has a spatial or AI-driven anomaly-matching component, and you'd rather run PostGIS and pgvector in the same database than bolt on a separate geospatial or vector store

**Choose a dedicated twin-modeling or visualization platform (e.g., **[**<u>Azure Digital Twins</u>**](https://azure.microsoft.com/en-us/products/digital-twins)**, **[**<u>NVIDIA Omniverse</u>**](https://www.nvidia.com/en-us/omniverse/)**) if:**

- Your primary need is the twin's modeling or simulation logic, or its 3D visualization, not the data layer underneath it. This page's architecture can sit behind either one, but doesn't replace them.

**Choose a data lake or object store for part of the workload if:**

- Your primary storage problem is raw high-frequency vibration waveforms, imagery, or point-cloud captures used for downstream signal processing. Route those separately; don't force them into a relational time-series database.

## Migration paths into a digital twin data layer

**From MongoDB or another NoSQL store.** Teams migrate once nested aggregation pipelines for reconciling sensor data against asset or twin metadata get slower, as both grow (the exact pattern behind Mechademy's move above).

**From a generic time-series database (e.g., InfluxDB).** Teams migrate when they need relational joins between sensor readings and asset or twin metadata that a pure time-series database can't do natively. InfluxDB's version fragmentation across 1.x, 2.x, 3.0, Cloud Serverless, and Cloud Dedicated tends to be an added consideration for teams standardizing long-term.

**From spreadsheet or manual twin-state tracking.** Teams migrate once a twin outgrows manual reconciliation of expected-versus-observed readings, typically as the number of monitored assets or the frequency of comparison grows past what's manually reviewable.

## Related Tiger Data industrial data resources

This page covers the digital-twin-specific reconciliation layer and the spatial and vector capability sitting alongside it. Two sibling pages share the same sensor-ingestion foundation from a different angle: the [<u>Manufacturing Analytics Database</u>](https://www.tigerdata.com/learn/manufacturing-analytics-database) pillar covers production-floor framing (OEE, downtime, quality), and the [<u>Predictive Maintenance Database</u>](https://www.tigerdata.com/learn/predictive-maintenance-database) pillar covers failure-prediction framing. All three build on the requirements laid out in [<u>IIoT Database Requirements</u>](https://www.tigerdata.com/learn/iiot-database-requirements).

A grid digital twin follows the same reconciliation pattern, real-time state compared against historical or expected state, just applied to distribution-grid assets instead of rotating equipment. Plexigrid's grid-visibility work is a real example of that pattern in production.