IoT & Tracking

Build real-time IoT applications and tracking systems with NoLag.

Overview

NoLag is ideal for IoT applications that require real-time data streaming from devices. Whether you're tracking vehicles, monitoring sensors, or controlling smart devices, NoLag provides the low-latency infrastructure you need.

App Setup

Rooms never exist implicitly, so create the app, its room, and its actors before any device or dashboard connects. Give each vehicle its own device actor and the dashboard its own user actor: publishers never receive their own messages, so a dashboard that reused a device's token would never see that device's updates.

import { NoLagApi } from '@nolag/js-sdk'

const api = new NoLagApi(process.env.NOLAG_API_KEY) // nlg_live_...

// 1. Create the app and declare the topics it allows. The slug that comes back
//    has a random suffix, so read it from the response.
const app = await api.apps.create({
  name: 'Fleet Tracker',
  slug: 'fleet-tracker',
  topics: ['location', 'telemetry'],
})
console.log(app.slug) // e.g. "fleet-tracker-a3f9": this is your APP_SLUG

// 2. Create the room. Room slugs are kept exactly as you supply them.
await api.rooms.create(app.appId, { name: 'Vehicles', slug: 'vehicles' })

// 3. One device actor per vehicle, and a user actor for the dashboard.
//    Each access token is shown once; keep them.
const truck42 = await api.actors.create({ name: 'truck-42', actorType: 'device', externalId: 'truck-42' })
const dashboard = await api.actors.create({ name: 'fleet-dashboard', actorType: 'user' })
console.log(truck42.accessToken, dashboard.accessToken)

Fleet Tracking Example

The dashboard connects with its user actor and subscribes to every vehicle's updates in the vehicles room.

import { NoLag } from '@nolag/js-sdk'

const APP_SLUG = 'fleet-tracker-a3f9' // the slug returned when you created the app

interface Location {
  vehicleId: string
  latitude: number
  longitude: number
  heading: number
  speed: number
  timestamp: number
}

interface Telemetry {
  vehicleId: string
  fuelLevel: number
  engineStatus: string
  batteryVoltage: number
}

const client = NoLag('dashboard_access_token')
client.on('error', (err) => console.error(err)) // unknown_topic etc. arrive here
await client.connect()

const fleet = client.setApp(APP_SLUG).setRoom('vehicles')

// Subscribe to all vehicle updates
fleet.subscribe('location')
fleet.subscribe('telemetry')

// Handle location updates. Payloads arrive as `unknown`; name the shape you expect.
fleet.on<Location>('location', (data) => {
  updateMapMarker(data.vehicleId, {
    lat: data.latitude,
    lng: data.longitude,
    heading: data.heading,
    speed: data.speed
  })
})

// Handle telemetry data
fleet.on<Telemetry>('telemetry', (data) => {
  updateVehicleStatus(data.vehicleId, {
    fuel: data.fuelLevel,
    engine: data.engineStatus,
    battery: data.batteryVoltage
  })
})

Device Publishing

On the IoT device, connect with that device's own actor and publish updates at regular intervals:

import { NoLag } from '@nolag/js-sdk'

const APP_SLUG = 'fleet-tracker-a3f9' // the slug returned when you created the app
const DEVICE_ID = 'truck-42'

// On the IoT device: its own device actor
const client = NoLag('truck_42_access_token')
await client.connect()

const device = client.setApp(APP_SLUG).setRoom('vehicles')

// Publish location updates every 5 seconds
setInterval(() => {
  const location = gps.getLocation()

  device.emit('location', {
    vehicleId: DEVICE_ID,
    latitude: location.lat,
    longitude: location.lng,
    heading: location.heading,
    speed: location.speed,
    timestamp: Date.now()
  })
}, 5000)

Use Cases

  • Fleet management - Track vehicles, deliveries, and drivers
  • Asset tracking - Monitor equipment and inventory location
  • Sensor networks - Collect data from environmental sensors
  • Smart home - Control and monitor IoT devices
  • Wearables - Stream health and fitness data

Best Practices

  • Use one device actor per device, and a separate actor for anything that needs to see what the devices publish
  • Batch telemetry data to reduce message frequency; the broker accepts 50 publishes per second per connection
  • QoS 1, the default, acknowledges each publish on the broker hop. It is not an end-to-end guarantee, so deduplicate on a reading's timestamp if a message must not be applied twice. See Quality of Service
  • Reconnection is built in. Every SDK reconnects automatically after a drop (reconnect defaults to true) and the broker restores the connection's subscriptions. Tune the cadence for unreliable networks instead of writing your own loop: reconnectInterval in JavaScript (milliseconds, with backoff up to 30 seconds), reconnect_interval and max_reconnect_attempts in Python, ReconnectInterval and MaxReconnectAttempts in Go (-1 retries forever). The default is 5 seconds and 10 attempts
  • Consider data retention and historical storage needs. NoLag delivers live readings and does not keep a history for you; a trigger webhook receives every publish and can write it to your own store

Next Steps