See it run.
How a message is handled.
A device sends a message over MQTT, HTTP, Sparkplug B or LwM2M. After decoding the message and identifying the device, DeviceChain passes the event to services that store it, update the device's current state and evaluate your rules. Matching rules trigger actions. The services communicate over NATS JetStream.
Customers or business units can share an install, with tenant isolation in the database and on the message bus. The operator manages the install and its tenants. The multi-tenancy page explains the isolation.
Ingest
MQTT on the built-in NATS broker, HTTP POST, a Sparkplug B host application and an LwM2M server over CoAP/DTLS. The last two are optional services. The transport matrix lists what each transport supports in each direction.
Detect
Rules are typed conditions such as threshold, duration or absence. Each is written as a simple comparison or as a CEL (Common Expression Language) expression, and is evaluated against events as they arrive from the devices you choose.
React
A rule can raise an alarm, send the device a command, call a webhook, or publish to MQTT, Kafka, Amazon SNS or Amazon SQS.
Command
Device profiles declare commands and their parameters. DeviceChain stores each request and tracks its status, including delivery, the device's response and failures.
Typed, versioned device profiles.
Device types describe equipment such as meters, freezers or trucks. Each type uses a profile that defines its measurements, commands and detection rules. Several types can share a profile. You can edit a draft, publish a version or roll back to an earlier one.
Relate a device to its customer, site or asset, then use those relationships to find its readings. Typed relationships also let you describe connections between devices and other entities.
- Device profiles
- Metrics, typed command definitions and detection rules, published as versions.
- Relationship graph
- Typed, directed relationships between entities. Attributes can be declared as facets, so you can browse and filter by several at once, such as site, product line and owner.
- Dynamic groups
- A CEL expression over entity attributes. Membership is worked out with an indexed database query each time the group is read.
- Customers, areas, assets
- Devices are assigned to customers, areas and assets. Assets nest in a parent/child tree. Areas are named locations, and their boundaries are drawn as separate geofences. Each event records the device's tracked relationships as they stood when it was written, so history stays correct after a device is reassigned.
- Credentials and replacement
- A device keeps a stable token, and its credentials are separate and rotatable. Replacing failed hardware is one operation that retires the old unit's credentials and keeps the device's history.
- Live state
- The latest value of each measurement and whether the device is online. MQTT, Sparkplug B and LwM2M report connects and disconnects directly. An HTTP device counts as online while it keeps sending.
Test a rule against stored history.
Preview a draft against stored events to see when its condition would have fired. Preview uses the same rule compiler and engine as live processing.
Run preview from the automation canvas before publishing. It starts with empty rule state, does not load device attributes or apply group scope, and reports readings it skips or limits it reaches. The detection engine page lists its limits.
- Three ways to write a rule
- A form on the device profile, a visual automation canvas, or a plain-language description when the optional AI service is on.
- Alarms
- Alarms track active, acknowledged and cleared states, and can change severity. Clearing behavior depends on the rule; some windowed rules need new events before they can clear.
- Eight kinds of rule
- Threshold, rate of change, repetition, duration, absence, windowed aggregate, area correlation and connectivity. Absence and connectivity rules catch a device that goes quiet or disconnects.
- Geofences
-
Draw them in the console or send polygons with holes over the API.
A rule's condition can test containment with
geo.inFence(...). Each location event carries the fence-set version in force when it arrived, so a replay uses the fences of its time. - Scope
- Rules live on a device profile, and most kinds can be narrowed to a dynamic group. Group membership is recorded on each event when it arrives.
Describe a rule in plain language.
With the optional AI service, type something like "raise a major alarm when a freezer stays above -15°C for ten minutes" and get a draft rule back. The draft goes through the same compiler as a hand-written rule. The service can use compiler errors to revise it, up to a fixed attempt limit. It returns a valid draft or the errors it could not resolve. Review the rule before publishing it; compilation checks its structure, not whether it matches your intent.
Published rules run without calling the model. To enable AI rule authoring, an operator registers the AI provider, makes a model available to the tenant and records the tenant's consent to external inference. Until all three are in place, the option is unavailable. You can leave the service off.
Versioned dashboards you can embed.
A dashboard belongs to a tenant and has drafts, published versions and rollback. You can build one against synthetic data before any device exists, then bind the same layout to a live fleet.
To show dashboards in your own React application, install the
runtime packages from npm (@devicechain/widgets,
@devicechain/dashboards and
@devicechain/client). A standalone viewer gives users
access to dashboards without the administration console.
Query your telemetry with SQL.
Telemetry is stored in TimescaleDB, a PostgreSQL extension. Query it
directly with a PostgreSQL-compatible tool such as Metabase,
Grafana, Power BI or psql, using a configured analytics
read role.
Each tenant can be given its own read role, which sees an analytics schema of views over events, measurements, per-minute rollups, locations, alerts and connection changes. The database itself filters these views to the reader's tenant. Location access requires a separate grant. The SQL and BI guide covers the setup.
- Read-only role
- A login role for each tenant, with read access to the analytics views. You choose which tenants get a reader.
- Or use the API
- Applications use the GraphQL API, which reads the same tables the analytics views are built on.
GraphQL, client SDKs and MCP.
The API is GraphQL, with one schema for each area of the platform,
and the schema files are published with the docs. Client SDKs are on
npm for TypeScript (@devicechain/client) and on NuGet
for .NET (DeviceChain.Sdk). The .NET SDK includes
ahead-of-time compilation checks, and a Unity package, built from
source, wraps it with Unity transports.
An optional Model Context Protocol server lets AI assistants such as Claude, Cursor or VS Code read devices, state, telemetry, alarms and commands. Calls use the signed-in user's token and permissions. The server exposes a selected set of read-only tools, not the full API.
- GraphQL
- One schema per platform area, with the schema files published.
- SDKs
- TypeScript on npm and C#/.NET on NuGet, plus the Unity package.
- MCP
- An OAuth 2.1 resource server with read-only tools, limited to the user's own tenant.
Runs on Kubernetes, with PostgreSQL and NATS.
Entities are stored in PostgreSQL and telemetry in TimescaleDB. NATS JetStream carries the internal messaging, serves as the MQTT broker and holds key-value state. The install sets up both for you.
dcctl is a single binary that carries the Helm chart and
the OpenTofu configuration. It drives docker,
kubectl, helm and OpenTofu (or Terraform),
which you install first, plus kind (Kubernetes in Docker) for a local
cluster. dcctl install prepares a cluster and
dcctl bootstrap creates an instance on it. Both commands
can target a cluster you already have. The install and bootstrap
workflows are tested end to end on kind, which also lets you run
DeviceChain on a laptop. The
repository also includes an OpenTofu configuration that creates a
Google Kubernetes Engine cluster with separate database and service
node pools.
On a Google Kubernetes Engine cluster of three 4-vCPU, 16 GB database nodes and three 4-vCPU, 8 GB service nodes, the v0.19.0 default HA install accepted 6,000 events a second for 10 minutes, twice. In those runs, event-by-event checks found no missing, duplicate or unexpected stored events. Each event carried one reading. The test used one tenant with its ingest ceiling raised for the test; at the default ceiling of 1,000 readings a second, one tenant's devices are admitted at most 5,000 a second. Service sizing documents the test conditions and resource settings. These results describe that workload and cluster, not a capacity guarantee.
The default cluster install also sets up Prometheus, Grafana and Alertmanager, with the platform's alert rules and dashboards. With backups enabled, both databases archive continuously for point-in-time restore. Restore and failover are tested with scripted drills on a running cluster, and the restore drill passes only if secrets stored before the backup still decrypt afterwards.
Operations and governance.
Alarm notifications, outbound delivery, audit, per-tenant limits, data retention and tenant deletion.
Notifications
Per-tenant policies route alarms by severity to email or webhooks, and escalate alarms nobody acknowledges. Escalation is safe to run on several replicas.
Outbound connectors
A separate service delivers rule actions to webhooks, MQTT, Kafka, Amazon SNS and Amazon SQS.
Egress boundary
Outbound connections block loopback, private, carrier-grade NAT, link-local and cloud metadata addresses by default. An operator can allow specific destination addresses or ranges for the instance.
Audit journal
The audit journal records changes to control-plane entities and who made them. Telemetry and derived state are excluded. When a tenant is deleted, its journal entries stay, with names and email addresses removed.
Governance
Per-tenant limits on ingest, outbound actions, AI requests and queued commands, which keep each tenant's load on a shared install within bounds you set.
Data lifecycle
TimescaleDB hypertables with compression, retention and continuous aggregates for per-minute rollups.
Tenant deletion
Deleting a tenant revokes sign-in at once and refuses new connections, ingest and commands within about a minute. It then erases the tenant's data from the database, telemetry store, broker, object store, key-value store and running rule engine, and records what each one did. Backups expire separately: by default, core data remains restorable for 30 days and telemetry for 7 days.
Secrets
Integration secrets are encrypted at rest, referenced by handle and write-only through the API.
White-labeling
Per-tenant branding that falls back to an operator default and then to the built-in look.
Device simulation
dcctl sim sets up a scenario, and the simulator,
which you build from source, creates its customers, areas, assets
and devices, then sends live telemetry over the same wire a real
device uses.
Edge agent
Buffers to disk through a network outage (1 GiB by default, dropping the oldest events when full) and forwards when the link returns. When it replays its buffer, JSON events are stored once. Other payload formats can be stored twice.
Try it on a laptop.
The
first-device quickstart
takes about half an hour, including bootstrap. Bring up an instance
on kind, create a device, send it a reading with
curl and see the reading in the console.
DeviceChain is pre-1.0. It is a rebuild of the SiteWhere IoT platform. The simulator and Unity package are built from source; client SDKs are distributed separately. Read the release notes before upgrading: some pre-1.0 changes require a fresh install. APIs and database schemas can still change, and the notes list breaking changes first (see pre-1.0 stability). If something breaks, send us the steps and what you expected. Get in touch.