Node.js / TypeScript · recipe

Subscribe to data changes in Node.js

Create a subscription with the publishing interval your consumer needs, then monitor items with their own sampling interval, queue size and filter. node-opcua exposes every parameter that matters, including the deadband most wrappers hide.

Stacknode-opcua
Version2.181.1

The code

const {
  OPCUAClient, AttributeIds, TimestampsToReturn,
  DataChangeFilter, DataChangeTrigger, DeadbandType,
} = require("node-opcua");

(async () => {
  const client = OPCUAClient.create({ endpointMustExist: false });
  await client.connect("opc.tcp://opcua.umati.app:4840");
  const session = await client.createSession();

  const subscription = await session.createSubscription2({
    requestedPublishingInterval: 1000,   // what the consumer needs
    requestedLifetimeCount: 100,
    requestedMaxKeepAliveCount: 10,
    maxNotificationsPerPublish: 100,
    publishingEnabled: true,
    priority: 10,
  });

  subscription.on("keepalive", () => console.log("keepalive"));
  subscription.on("terminated", () => console.log("subscription terminated"));

  const item = await subscription.monitor(
    { nodeId: "i=2258", attributeId: AttributeIds.Value },
    {
      samplingInterval: 250,
      queueSize: 10,
      discardOldest: true,
      filter: new DataChangeFilter({
        trigger: DataChangeTrigger.StatusValue,
        deadbandType: DeadbandType.Absolute,
        deadbandValue: 0.5,
      }),
    },
    TimestampsToReturn.Both
  );

  item.on("changed", (dv) => {
    console.log(dv.value.value, dv.statusCode.toString(), dv.sourceTimestamp);
  });

  setTimeout(async () => {
    await subscription.terminate();
    await session.close();
    await client.disconnect();
  }, 5000);
})();

What it prints

2026-09-08T03:45:00.102Z Good (0x00000000) 2026-09-08T03:45:00.102Z
2026-09-08T03:45:01.104Z Good (0x00000000) 2026-09-08T03:45:01.104Z
keepalive

Notes

  • requestedPublishingInterval is the delivery rate; samplingInterval is how often the server looks. Set the first from what the consumer needs, not from the fastest the server can manage.
  • The server may revise your parameters. Read subscription.publishingInterval after creation to see what you actually got.
  • Percent deadband requires EURange on the node. Absolute is the safe default.
  • Listen for `terminated`. A subscription deleted server-side is a silent data stop otherwise.
  • Keep the number of distinct publishing intervals small: each one is another subscription on the server.

What breaks first

Data arrives but with gaps, and every status code is Good GoodOverload
The queue overflowed between publishes. Raise queueSize, slow the sampling interval, or add a deadband so fewer notifications are generated.

Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.

Free download
OPC UA Troubleshooting & Integration Checklist
The field-tested checklist engineers use to diagnose certificates, ports and namespace problems fast, plus a Python (asyncua) client template.
Get the free checklist →
Free, no course, no login