ChistaDATA · Data fabric engineering on 100% open-source, cloud-native ClickHouse

A data fabric is the layer that lets an organisation treat data from OLTP databases, event streams, lakes and SaaS tools as one queryable estate, with the same governance, the same freshness guarantees and the same access path everywhere. ChistaDATA designs and operates data fabric platforms with ClickHouse as the serving core, deployed cloud-natively on Kubernetes in your own account, for real-time analytics, artificial intelligence and machine learning workloads.

This page is the engineering description of that platform: the six layers of the data fabric, the ingestion paths and the consistency guarantee each one gives, the Kubernetes and object-storage topology, the physical ClickHouse design, the governance model, how features and embeddings are served to machine learning, and how every layer is measured.

6Layers in the ChistaDATA data fabric reference architecture, each with its own SLO
4Ingestion paths, chosen per dataset by freshness and replay semantics
15 minSeverity 1 response for ChistaDATA support customers, 24×7×365
100%Open-source ClickHouse, operator-managed on your Kubernetes, no proprietary layer

Definition

What a data fabric is, and what a ClickHouse data fabric is not

The term is used loosely, so it is worth being exact. A data fabric is a metadata-driven integration and serving layer that spans distributed sources without forcing them into one physical store. It has six responsibilities that always travel together.

They are: connecting to sources without rewriting them, ingesting with a declared freshness and consistency contract, serving queries at the latency the consumers need, exposing a semantic layer so consumers do not need to know where a column came from, governing access and retention uniformly, and observing itself so freshness and cost are measured per dataset. Remove any one of those and what remains is a set of pipelines.

ChistaDATA’s data fabric puts ClickHouse at the serving core because the consumers that justify the investment, real-time dashboards, embedded product analytics, feature reads for machine learning, ad-hoc exploration over years of events, all need sub-second answers over columnar data at high concurrency. ClickHouse delivers that on commodity hardware and object storage, in your own cloud account, with no proprietary format between you and your data.

It is equally important to say what this data fabric is not. It is not a replacement for the transactional databases that own writes; those stay where they are and are read through change data capture. It is not a lakehouse replacement; Iceberg and Delta tables on object storage remain the long-term store of record for cold data and are queried in place or loaded from. And it is not a data mesh organisational model; a data fabric is the platform that a mesh, a central team or a single product team can run on. The distinction matters because the most expensive platform failures we review are platforms that tried to be all three.

Illustrative sizing appears throughout this page (two shards, three replicas, a 90-day hot tier). Nothing here is a benchmark claim; every figure that matters is measured on your workload during the assessment. Test every change on a staging cluster before production and keep a tested backup and DR posture throughout.

Reference architecture

Data fabric reference architecture on cloud-native ClickHouse

The diagram below is the topology ChistaDATA deploys. Sources on the left are owned by their teams and are never rewritten by the data fabric. The ingestion layer lands data through one of four paths, each with a declared contract. The serving core is a ClickHouse cluster managed by an operator on Kubernetes, with hot partitions on local NVMe and cold partitions on object storage. The semantic layer carries dictionaries, catalog metadata and the access endpoints, including the ChistaDATA Fabric gateway. Consumers are analytics tools and the artificial intelligence and machine learning stack. Governance and observability span every layer.

Data fabric reference architecture on cloud-native ClickHouse: sources, ingestion, serving core, semantic layer, consumers, and governance and observability spanning every layer
Fig. 1 — Data fabric reference architecture. Six layers with one metadata-driven control plane; every path from a source to a consumer crosses ingestion, serving, semantic and governance layers.

Three properties of this design carry most of its value. Sources are read-only to the platform, so adopting it never puts a transactional system at risk. Every dataset carries a written contract (append-only events or upserted entities, freshness target, owner, retention, PII classification) that the ingestion, serving and governance layers all enforce. And the serving core is plain ClickHouse: any client that speaks its native or HTTP protocol, or the MySQL and PostgreSQL wire protocols it also understands, can use the platform without a vendor SDK.

Layer 2 · Ingestion

Four ingestion paths into the data fabric, and what each one guarantees

Ingestion is where these platforms most often go wrong, usually by treating every source the same way. ChistaDATA classifies each dataset by two questions: how fresh must it be, and how can the source be replayed if the pipeline fails? The answers select one of four paths, shown below with the consistency guarantee each actually provides rather than the one its documentation implies.

Data fabric ingestion paths into ClickHouse: Kafka engine with materialized view, Kafka Connect sink, batch from object storage, and federation, with the consistency guarantee of each
Fig. 2 — Data fabric ingestion paths. Streaming through the Kafka engine or the Connect sink, batch from object storage, and federation without a copy; all four land in the same physical design.

Path A: Kafka engine table with a materialized view

ClickHouse consumes the topic itself. A table with ENGINE = Kafka holds no data; a materialized view attached to it receives every polled block and writes it into a MergeTree table. Delivery is at-least-once: if a replica crashes between committing the Kafka offset and completing the insert, or the reverse, a block can be replayed. The platform handles that by declaring the dataset’s contract up front. Append-only events rely on insert-block deduplication (a block with the same hash is dropped by the replicated engine), and upserted entities use ReplacingMergeTree with a monotonic version.

-- ClickHouse 25.x / 26.x LTS: streaming ingestion for the data fabric
CREATE TABLE fabric.events_kafka ON CLUSTER '{cluster}'
(
    event_id    UUID,
    tenant_id   UInt32,
    entity_id   UInt64,
    event_type  LowCardinality(String),
    event_time  DateTime64(3, 'UTC'),
    payload     String
)
ENGINE = Kafka
SETTINGS
    kafka_broker_list        = '${KAFKA_BROKERS}',
    kafka_topic_list         = 'events.v2',
    kafka_group_name         = 'fabric-events-v2',
    kafka_format             = 'JSONEachRow',
    kafka_num_consumers      = 2,
    kafka_max_block_size     = 65536,
    kafka_handle_error_mode  = 'stream';

CREATE TABLE fabric.events ON CLUSTER '{cluster}'
(
    event_id    UUID,
    tenant_id   UInt32,
    entity_id   UInt64,
    event_type  LowCardinality(String),
    event_time  DateTime64(3, 'UTC') CODEC(DoubleDelta, ZSTD(3)),
    payload     String               CODEC(ZSTD(6)),
    ingested_at DateTime DEFAULT now()
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/fabric/events', '{replica}')
PARTITION BY toYYYYMMDD(event_time)
ORDER BY (tenant_id, entity_id, event_time)
TTL toDateTime(event_time) + INTERVAL 90 DAY TO VOLUME 'cold',
    toDateTime(event_time) + INTERVAL 24 MONTH DELETE
SETTINGS storage_policy = 'tiered', index_granularity = 8192;

CREATE MATERIALIZED VIEW fabric.events_mv ON CLUSTER '{cluster}'
TO fabric.events AS
SELECT event_id, tenant_id, entity_id, event_type, event_time, payload
FROM fabric.events_kafka;

Rows that fail to parse are routed by kafka_handle_error_mode = 'stream' to virtual columns (_error, _raw_message) that a second materialized view captures into a dead-letter table, so a malformed producer never stalls the consumer. Consumer lag is read from system.kafka_consumers and exported to Prometheus; the alert threshold is the dataset’s freshness contract, not a fixed number.

Path B: Kafka Connect ClickHouse sink

When Kafka Connect is already the organisation’s integration hub and a schema registry governs the topics, the official ClickHouse sink connector is the better fit. Its tasks scale independently of the cluster, poison records go to a dead-letter topic, and recent versions provide exactly-once delivery through a Keeper-backed state table; the connector’s release notes are the authority on which guarantee applies to the version deployed. This path is preferred for Debezium CDC topics, because the Connect cluster is already running the source connectors.

Path C: batch from object storage

For datasets where hourly freshness is enough and the lake is the source of truth, the platform loads partitions with INSERT INTO ... SELECT FROM s3() or iceberg() under an orchestrator. The correctness rule is idempotency by partition: a reload drops or replaces the partition rather than appending to it, so a retried job cannot double-count.

-- Idempotent partition load into the data fabric from Parquet on S3
INSERT INTO fabric.orders_staging
SELECT *
FROM s3('https://${LAKE_BUCKET}.s3.amazonaws.com/orders/dt=2026-09-24/*.parquet', 'Parquet')
SETTINGS max_threads = 16, input_format_parquet_filter_push_down = 1;

-- Validation query BEFORE swapping: expected row count and checksum
SELECT count(), sum(cityHash64(order_id, status, total)) FROM fabric.orders_staging;

ALTER TABLE fabric.orders REPLACE PARTITION '20260924' FROM fabric.orders_staging;

-- Validation query AFTER: the live partition matches staging
SELECT count() FROM fabric.orders WHERE toYYYYMMDD(order_date) = 20260924;

Path D: federation without a copy

Some sources should not be copied: an Iceberg table that is petabytes and queried monthly, or a regulated PostgreSQL schema that legally must stay in place. ClickHouse’s Iceberg, Delta Lake, PostgreSQL and MySQL table engines let the platform query these in place, pushing predicates down where the engine supports it. Every such query pays the source’s latency and network cost, so federation is recorded in the catalog as a deliberate choice for cold or rarely used data, never as a default for anything a dashboard depends on.

Layer 3 · Serving core

The cloud native ClickHouse serving core of the data fabric

Everything a consumer touches is a ClickHouse table, and the physical design of those tables is where the platform’s latency and cost are decided. ChistaDATA derives it from measurement rather than convention: the top query fingerprints from the assessment choose the sort keys, the retention contract chooses the partitioning and TTL, and the column types choose the codecs. The DDL above shows the shape; the reasoning behind each decision is below.

The sort key leads with the columns that the most selective filters use, in order of cardinality, and ends with time.

With index_granularity = 8192, a point lookup by tenant and entity reads one or two granules; a time-range scan over one tenant reads a contiguous run of them. Partitioning by day aligns with the TTL move rule, so a whole partition ages from NVMe to object storage as one operation, and with retention deletion, so erasure of a day is a metadata change rather than a mutation. Codecs are chosen per column: DoubleDelta for timestamps that arrive in order, Gorilla for slowly varying floats, ZSTD at a higher level for payloads written once and read rarely, and LowCardinality(String) for enumerations, which turns string comparisons into integer comparisons.

Above the raw tables sit the serving structures. Materialized views into AggregatingMergeTree tables hold pre-aggregated states for the dashboards that run the same GROUP BY every minute, and projections give the same table a second sort order for a second class of query without a second pipeline. Skip indexes (minmax, set, bloom_filter) cover filters that the sort key does not. Each of these is validated with EXPLAIN indexes = 1 and EXPLAIN PIPELINE against the real fingerprints before it is deployed, and its benefit is recorded as read bytes before and after in system.query_log.

-- Tiered storage policy for the data fabric (config.d/storage.xml, all replicas)
<clickhouse>
  <storage_configuration>
    <disks>
      <nvme><path>/var/lib/clickhouse/</path></nvme>
      <s3_cold>
        <type>s3</type>
        <endpoint>https://${COLD_BUCKET}.s3.${AWS_REGION}.amazonaws.com/fabric/</endpoint>
        <use_environment_credentials>true</use_environment_credentials>
        <metadata_path>/var/lib/clickhouse/disks/s3_cold/</metadata_path>
      </s3_cold>
      <s3_cache>
        <type>cache</type>
        <disk>s3_cold</disk>
        <path>/var/lib/clickhouse/cache/s3_cold/</path>
        <max_size>200Gi</max_size>
      </s3_cache>
    </disks>
    <policies>
      <tiered>
        <volumes>
          <hot><disk>nvme</disk></hot>
          <cold><disk>s3_cache</disk></cold>
        </volumes>
        <move_factor>0.1</move_factor>
      </tiered>
    </policies>
  </storage_configuration>
</clickhouse>

The result is that the hot 90 days of a dataset answer from local NVMe while two years of history stay queryable from object storage through the same table, with a local cache absorbing repeated cold reads. Where a partition physically lives is visible in system.parts.disk_name, and the move itself in system.part_log, so the cost profile of the storage tier is always inspectable.

Cloud native deployment

Deployment topology: the data fabric on Kubernetes with object storage

Cloud native, for a data fabric, means something specific: the ClickHouse cluster is declared as a Kubernetes custom resource and reconciled by an operator; storage is split between local NVMe for hot data and object storage for cold data and backups; and every supporting component (Keeper, Kafka Connect, orchestrator, Prometheus) runs in the same cluster with its own scaling. The topology below is the one ChistaDATA deploys on EKS, GKE, AKS and on-premises Kubernetes alike.

Cloud native ClickHouse data fabric deployment topology on Kubernetes: operator, two shards of three replicas across zones, Keeper ensemble, tiered S3 storage, backups and ingestion pods
Fig. 3 — Data fabric deployment topology. Operator-managed shards and replicas across zones, a separate Keeper ensemble, and object storage for the cold tier, backups, the lake and training exports.
# ClickHouseInstallation (Altinity clickhouse-operator CRD), abbreviated
apiVersion: clickhouse.altinity.com/v1
kind: ClickHouseInstallation
metadata:
  name: fabric
  namespace: data-fabric
spec:
  configuration:
    zookeeper:
      nodes:
        - host: keeper-0.keeper.data-fabric.svc
        - host: keeper-1.keeper.data-fabric.svc
        - host: keeper-2.keeper.data-fabric.svc
    clusters:
      - name: fabric
        layout:
          shardsCount: 2
          replicasCount: 3
        templates:
          podTemplate: ch-pod
          dataVolumeClaimTemplate: ch-nvme
  templates:
    podTemplates:
      - name: ch-pod
        spec:
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                - topologyKey: topology.kubernetes.io/zone
                  labelSelector:
                    matchLabels: { clickhouse.altinity.com/chi: fabric }
          containers:
            - name: clickhouse
              image: clickhouse/clickhouse-server:${CH_LTS_VERSION}
              resources:
                requests: { cpu: "16", memory: "64Gi" }
                limits:   { cpu: "16", memory: "64Gi" }
    volumeClaimTemplates:
      - name: ch-nvme
        spec:
          storageClassName: local-nvme
          accessModes: [ReadWriteOnce]
          resources: { requests: { storage: 2Ti } }

A few of the rules encoded there deserve explanation. Requests equal limits so that pods get Guaranteed QoS and are never evicted under node pressure; inside the container, max_server_memory_usage_to_ram_ratio is kept below 0.9 so ClickHouse leaves headroom for the page cache. Anti-affinity is required, not preferred, across zones, so a zone failure costs one replica per shard and never quorum.

Keeper runs as its own StatefulSet on separate PVCs; co-locating Keeper with data pods is the single most common cause of replication stalls we see in reviews. A PodDisruptionBudget of two of three per shard lets node upgrades proceed without a read outage. Backups run clickhouse-backup from a CronJob to a versioned bucket with cross-region replication, and the restore is drilled quarterly with a timed RTO.

Scaling follows the measurement: replicas are added for read concurrency or availability, shards only when a single replica’s NVMe or merge throughput is the bottleneck, which shows as a growing system.merges backlog or a rising parts count per partition. Ingestion workers scale separately, so a Kafka surge never competes with query CPU.

Layer 4 · Semantic and integration

The semantic layer: how consumers use the data fabric without knowing its plumbing

A consumer should be able to join events to customers, products or regions without knowing that the dimension lives in PostgreSQL. ClickHouse dictionaries do that: a dictionary is loaded from the source on a refresh interval, held in memory in a layout chosen for the key type, and used through dictGet or a dictionary join. Credentials for the source live in a named collection, so no DDL or dashboard ever contains a password.

-- Named collection holds the source credentials once (server-side)
CREATE NAMED COLLECTION crm_pg AS
    host = '${PG_HOST}', port = 5432, database = 'crm',
    user = '${PG_RO_USER}', password = '${PG_RO_PASSWORD}';

-- Dimension dictionary refreshed from PostgreSQL every 5 minutes
CREATE DICTIONARY fabric.dim_customer ON CLUSTER '{cluster}'
(
    customer_id UInt64,
    segment     String,
    country     String,
    account_manager String
)
PRIMARY KEY customer_id
SOURCE(POSTGRESQL(NAME crm_pg TABLE 'customers'))
LAYOUT(HASHED())
LIFETIME(MIN 300 MAX 360);

-- Consumers join without knowing where the dimension lives
SELECT dictGet('fabric.dim_customer', 'segment', entity_id) AS segment,
       count() AS events
FROM fabric.events
WHERE event_time >= now() - INTERVAL 1 DAY
GROUP BY segment
ORDER BY events DESC;

The catalog is the second half of the semantic layer. Every table carries its owner, contract type, freshness target, retention and PII classification, stored as table comments and in a small metadata schema that the observability layer reads. Lineage falls out of the materialized-view graph in system.tables and system.dependencies, so the question “which dashboards break if this topic changes” is a query, not an investigation.

Access is the third. Consumers reach the serving core through the native protocol, HTTP, or the MySQL and PostgreSQL wire protocols ClickHouse also serves, which is what lets Tableau, Power BI and legacy JDBC tools connect unchanged. Where several backends are involved, the ChistaDATA Fabric gateway sits in front: it terminates TLS, holds the backend credentials, applies routing rules and a SQL blacklist, and logs every statement with its route, which is also how a row-store archival tier is folded into the same data fabric.

Layer 6 · Governance

Governance and security across the data fabric

Governance in a data fabric is only real if it is enforced by the serving engine rather than by convention in each tool. ClickHouse’s role-based access control gives the platform one model that every consumer inherits: identity from LDAP or SSO mapped to roles, grants per database and table, row policies that restrict what each role can see, settings profiles that cap what each role can spend, and quotas that cap how often. The audit trail is system.query_log and system.session_log, retained and shipped to the observability store.

-- Data fabric governance: one model, enforced by the engine
CREATE ROLE fabric_analyst ON CLUSTER '{cluster}';
CREATE ROLE fabric_ml_export ON CLUSTER '{cluster}';

GRANT SELECT ON fabric.* TO fabric_analyst;
GRANT SELECT ON fabric.events, fabric.features_daily TO fabric_ml_export;

-- Tenant isolation: analysts see only their tenant's rows
CREATE ROW POLICY tenant_scope ON fabric.events
    FOR SELECT USING tenant_id = toUInt32(getSetting('SQL_tenant_id'))
    TO fabric_analyst;

-- Spend limits per role
CREATE SETTINGS PROFILE analyst_limits
    SETTINGS max_memory_usage = 20000000000,
             max_execution_time = 60,
             max_result_rows = 1000000
    TO fabric_analyst;

CREATE QUOTA analyst_quota
    FOR INTERVAL 1 HOUR MAX queries = 5000, read_rows = 50000000000
    TO fabric_analyst;

-- Column masking for direct identifiers, exposed as a view
CREATE VIEW fabric.events_masked AS
SELECT event_id, tenant_id, cityHash64(entity_id) AS entity_key,
       event_type, event_time
FROM fabric.events;

Compliance obligations map onto the same primitives. Retention is a TTL expression, so the evidence that data older than the policy is gone is a query against system.parts. Erasure requests under GDPR or DPDP are lightweight deletes scoped by entity, followed by a proof-of-deletion query that is stored with the ticket. Encryption in transit is TLS on every port, including the Keeper ports; encryption at rest is the cloud KMS on the NVMe volumes and the buckets. SOC 2 and HIPAA evidence packs are generated from the same system tables the observability layer already reads.

Artificial intelligence and machine learning

The data fabric as the feature and embedding platform for machine learning

The same tables that serve dashboards serve models; what changes is the read pattern and the correctness rule. The platform provides four things machine learning teams otherwise build themselves: feature values that are fresh because they are computed by materialized views on insert, training sets that are leakage-free because they are assembled with point-in-time joins, embeddings stored next to the rows they describe with vector search over them, and exports to the formats training frameworks read.

Data fabric for artificial intelligence and machine learning on ClickHouse: feature materialized views, point-in-time training sets, online feature reads, embeddings with vector search, training exports and model monitoring
Fig. 4 — Data fabric for machine learning. Feature views, point-in-time joins, online reads, embeddings and vector search, Parquet exports and drift monitoring on one set of tables.
-- Feature view: per-entity daily aggregates kept as mergeable states
CREATE TABLE fabric.features_daily ON CLUSTER '{cluster}'
(
    tenant_id   UInt32,
    entity_id   UInt64,
    day         Date,
    events      AggregateFunction(count),
    purchases   AggregateFunction(sum, Decimal(18, 2)),
    distinct_types AggregateFunction(uniq, String)
)
ENGINE = ReplicatedAggregatingMergeTree('/clickhouse/tables/{shard}/fabric/features_daily', '{replica}')
PARTITION BY toYYYYMM(day)
ORDER BY (tenant_id, entity_id, day);

CREATE MATERIALIZED VIEW fabric.features_daily_mv ON CLUSTER '{cluster}'
TO fabric.features_daily AS
SELECT tenant_id, entity_id, toDate(event_time) AS day,
       countState()                          AS events,
       sumState(toDecimal64(JSONExtractFloat(payload, 'amount'), 2)) AS purchases,
       uniqState(event_type)                 AS distinct_types
FROM fabric.events
GROUP BY tenant_id, entity_id, day;

-- Point-in-time training set: features as they were at label time
SELECT l.entity_id, l.label_time, l.label,
       countMerge(f.events) AS events_30d
FROM fabric.labels AS l
ASOF LEFT JOIN
(
    SELECT entity_id, day, events
    FROM fabric.features_daily
) AS f
ON l.entity_id = f.entity_id AND f.day <= toDate(l.label_time)
GROUP BY l.entity_id, l.label_time, l.label;

-- Export for training, partitioned, read by Spark / PyTorch / Ray
INSERT INTO FUNCTION s3('https://${ML_BUCKET}.s3.amazonaws.com/training/churn/{_partition_id}.parquet', 'Parquet')
PARTITION BY toYYYYMM(label_time)
SELECT * FROM fabric.training_churn_v7
SETTINGS log_comment = 'model=churn_v7 export';

Embeddings are stored as Array(Float32) columns alongside the rows they describe, and similarity queries order by cosineDistance or L2Distance. The vector similarity index (HNSW via usearch) accelerates those queries; it has been available behind a feature setting since the 24.x releases and its status should be confirmed for the LTS version deployed. The practical rule for retrieval-augmented generation is to filter on the sort key first (tenant, document type, date) and rank only the survivors, which keeps recall high and latency predictable. Every training export carries the model name in log_comment, so lineage from a deployed model back to the exact rows it was trained on is a lookup in system.query_log.

ChistaDATA does not deploy a separate feature store by default. The feature values already exist as aggregate states in the serving layer, and a second system doubles the freshness and consistency problem; one is added only when online reads need sub-millisecond latency that ClickHouse’s point lookups, typically low single-digit milliseconds at scale, do not meet. Model monitoring closes the loop: predictions are written back as events, and feature distributions are compared daily against the training snapshot with quantile functions to detect drift.

Observability

How the data fabric measures itself

Every layer exports its health through ClickHouse’s own system tables and the Prometheus endpoint, rendered in Grafana and alerted against SLOs with error budgets. The metrics are per dataset, because a platform that is “99.9% healthy” overall can still be serving one stale dashboard to the board. The table below lists what is measured at each layer and where the number comes from.

LayerWhat is measuredSource of truth
IngestionFreshness lag per dataset against its contract; consumer lag; dead-letter rate; partition reload successsystem.kafka_consumers, connector metrics, orchestrator run logs
Serving corep95 and p99 per query fingerprint; read bytes per query; parts per partition; merge backlog; replication delay; Keeper latencysystem.query_log, system.parts, system.merges, system.replication_queue, Keeper 4lw commands
StorageBytes per tier per dataset; cache hit ratio; S3 request rate and cost; TTL moves completedsystem.parts.disk_name, system.part_log, cloud billing export
SemanticDictionary refresh success and age; gateway route share and rejected statementssystem.dictionaries, Fabric gateway query log
GovernanceQuota consumption per role; failed authentications; policy coverage (tables without an owner or classification)system.quota_usage, system.session_log, catalog schema
Machine learningFeature freshness; training-set build time; online read latency per model; vector recall@k; drift per featuresystem.query_log filtered by log_comment, drift tables
-- Data fabric serving SLO check: p95 per fingerprint over the last hour, worst first
SELECT
    normalizedQueryHash(query)               AS fingerprint,
    count()                                  AS runs,
    quantile(0.95)(query_duration_ms)        AS p95_ms,
    formatReadableSize(avg(read_bytes))      AS avg_read,
    any(substring(query, 1, 90))             AS sample
FROM system.query_log
WHERE type = 'QueryFinish'
  AND event_time > now() - INTERVAL 1 HOUR
  AND user NOT IN ('default', 'monitoring')
GROUP BY fingerprint
HAVING runs >= 10
ORDER BY p95_ms DESC
LIMIT 20;

Industry patterns

Where a ClickHouse data fabric fits, by industry

The architecture is the same across industries; what changes is which datasets are hot, which consumers are latency-critical, and which governance rules dominate. The patterns below are reference designs, not client claims, and each is sized during the assessment against the organisation’s own volumes.

Financial services

Transaction and market events through the Kafka engine, per-entity risk features as aggregate states, row policies per legal entity, seven-year retention on the cold tier with proof-of-deletion queries, and model exports with full lineage for audit.

E-commerce and SaaS

Clickstream and order events, customer-facing embedded analytics served through the gateway with per-tenant row policies, session and funnel features refreshed on insert, and recommendation embeddings queried with filter-then-rank retrieval.

Industrial and IoT

High-rate telemetry with DoubleDelta and Gorilla codecs, daily partitions tiered to object storage, predictive-maintenance features per asset, and federation over the historian’s Parquet exports rather than a second copy.

Healthcare and life sciences

Device and clinical event streams with column-masked views for research access, HIPAA evidence from system tables, and genomic or trial datasets queried in place on Iceberg with only the derived features copied into the serving tier.

Telecom and AdTech

Billions of events a day through multiple Kafka consumers per replica, projections for the two dominant query shapes, sampling for exploratory analysis, and quota-governed self-service access for hundreds of analysts.

Public sector and GCCs

Multi-department fabrics with strict data residency: one cluster per region, dictionaries for shared reference data, cross-region reads only through explicit federation, and a single governance model audited centrally.

Delivery

How ChistaDATA delivers a data fabric

Every engagement follows the same four phases, each with an exit gate the customer signs off. The elapsed time for a first production dataset set is typically eight to twelve weeks; most of that is measurement and validation, not engineering.

PhaseWhat happensExit gate
1 · AssessInventory of sources, consumers and their latency needs; query fingerprints and volumes from existing systems; retention and compliance obligations; a written contract per candidate datasetBaseline report with per-dataset freshness and latency targets, signed off
2 · DesignIngestion path per dataset; physical ClickHouse design (sort keys, partitions, codecs, TTL, projections); Kubernetes topology and storage policy; governance roles and policies; observability SLOsDDL and CRDs reviewed against the top twenty fingerprints with EXPLAIN; DR plan with RPO and RTO stated
3 · Build and validateCluster deployed by operator; pipelines running in parallel with existing systems; reconciliation of counts and checksums per dataset; load and failover tests; backup and timed restoreZero reconciliation mismatches for seven days; SLOs met under production-shaped load; restore drill within RTO
4 · OperateCutover by dataset; 24×7 consultative support with a 15-minute Severity 1 response; quarterly health checks, upgrade planning across LTS releases, and failover drillsMonthly SLO report; error budgets respected; capacity plan reviewed quarterly

ChistaDATA provides the phases as ClickHouse consulting for assessment and design, platform engineering for the build, and either 24×7 ClickHouse support for a customer-operated data fabric or ClickHouse managed services where ChistaDATA operates it. Migrations from Redshift, Snowflake, BigQuery, Druid, Elasticsearch or a legacy warehouse into the data fabric follow the ClickHouse migration method, one dataset at a time behind the same reconciliation gates.

FAQ

Data fabric questions we hear most often

Is a data fabric the same as a data lakehouse or a data mesh?

No. A lakehouse is a storage architecture (open table formats on object storage with a query engine); a data mesh is an organisational model (domain ownership of data products). A data fabric is the integration and serving layer that either can run on. In ChistaDATA’s design the lakehouse remains the long-term store for cold data and the data fabric serves the hot, governed, sub-second layer above it.

Why ClickHouse as the serving core rather than a cloud warehouse?

Because the consumers that justify a data fabric need sub-second answers at high concurrency over event-scale data, and they need it at predictable cost in the organisation’s own account. ClickHouse delivers that on open-source software with no proprietary storage format; a cloud warehouse can be a fine batch analytics engine, but it is rarely the right online serving tier. Where a warehouse already exists, the data fabric reads from it or feeds it rather than replacing it.

Does this data fabric require ClickHouse Cloud or a vendor licence?

No. The serving core is 100% open-source ClickHouse, deployed by an open-source operator on your Kubernetes, with your object storage. ChistaDATA’s role is engineering, support and, if you choose, operations; there is no proprietary layer between you and your data and nothing that prevents you from taking the platform in-house.

How fresh is data in the data fabric?

It depends on the path chosen per dataset: seconds through the Kafka engine or Connect sink, minutes to hours through batch loads, live for federated reads. Freshness is a declared contract per dataset, measured continuously, and alerted on when it is missed; the assessment phase sets the targets from the consumers’ real needs rather than from a blanket promise.

Can the data fabric support machine learning without a separate feature store?

In most estates, yes. Feature values are computed on insert by materialized views into aggregate-state tables, training sets are assembled with point-in-time joins, and online reads are sort-key point lookups. A separate feature store is added only when a model needs sub-millisecond lookups that the serving tier’s low-millisecond latency does not meet.

What does ChistaDATA operate after go-live?

Whatever the customer chooses. With 24×7 consultative support, the customer’s team operates the data fabric and ChistaDATA responds to incidents with a 15-minute Severity 1 SLA and runs quarterly health checks and drills. With managed services, ChistaDATA operates the platform end to end: upgrades across LTS releases, capacity, backups, DR drills and SLO reporting.

Next step

Start with the assessment, not the platform

A data fabric assessment from ChistaDATA inventories your sources and consumers, measures the query fingerprints and volumes that will drive the design, and produces per-dataset freshness and latency targets you can hold the platform to. If the numbers say a ClickHouse data fabric is the right architecture, the same engineers design it, build it in your account and stay on as 24×7 support or as the operating team. Wherever your data lives, on-premises, in your VPC or across clouds, the goal is the same: one governed, measured, sub-second serving layer for analytics, artificial intelligence and machine learning.

Further reading: ClickHouse Kafka engine · ClickHouse external and tiered storage · Altinity clickhouse-operator · ClickHouse row policies