Skip to main content
SDK · NETWORK · INTERNET · RADIO · v1.0

Sync that holds when the network doesn't.

Ara is the SQLite sync engine for field operations — Search & Rescue, expeditions, disaster response. Write to a local database. State converges across the team over Internet, Network, or Radio, whatever link is up.

ara · a path, route, way through.
Built in Aotearoa New Zealand.
FIG. 01 · MESH TOPOLOGYICPMQTTT-1UDPT-2MQTTT-3LoRaT-4LoRaMQTT · UDPLoRa−39.62°S · 176.84°E
SYNC LATENCY< 1 sover WiFi / MQTT
LORA RANGE5–15 kmno infrastructure
OFFLINE TOLERANCEdays, weeks, indefinite
LORA THROUGHPUT~5 KB/min*burst; sustained ~110 B/min, varies by region

What's in the box.

Six properties that distinguish Ara from a sync queue or a centralised backend. None of these require code in your application — they are properties of the engine.

F-01

CRDT merge

Vector-clock delta sync. Conflicts resolve deterministically — no merge handlers in your application code.

F-02

Plain SQL

SQLite is the source of truth. Ara instruments tracked tables via virtual tables; your schema and queries are unchanged.

F-03

Multi-transport

Network, Internet, and Radio attach as siblings. The engine syncs over every available link and deduplicates changesets.

F-04

Schema versioning

Additive migrations, version negotiated on handshake. Older nodes keep working until you choose to upgrade.

F-05

Delay-tolerant

Hours or days offline. State converges when any link comes back — no replay coordination, no manual reconciliation.

F-06

Observable

OpenTelemetry traces on every sync operation. Drop a collector at the Incident Command Post; see the whole mesh.

Three calls. One database.

Open a node, attach a transport, run SQL. No new query language, no merge handlers, no peer discovery code. The rest is the engine's problem.

Go quickstart →
main.gogo run · CGO_ENABLED=1
node, _ := ara.Open(ctx, ara.Config{
    Path: "./ara.db",
    Migrations: []ara.Migration{{
        Version: 1,
        SQL: `CREATE TABLE positions (
            id          TEXT PRIMARY KEY,
            device_id   TEXT NOT NULL,
            lat         REAL NOT NULL,
            lon         REAL NOT NULL,
            recorded_at INTEGER NOT NULL
        ) STRICT;`,
        Sync: []string{"positions"},
    }},
})
defer node.Close()

// attach a transport — sync starts immediately
node.AddTransportUDP(7946)

// write — propagates to every peer automatically
node.Exec(ctx,
    "INSERT INTO positions (id, device_id, lat, lon, recorded_at) VALUES (?,?,?,?,?)",
    "pos-1", "unit-42", 37.7749, -122.4194, time.Now().UnixMilli(),
)

// read locally — always available, even offline
rows, _ := node.Query(ctx,
    "SELECT device_id, lat, lon FROM positions ORDER BY recorded_at DESC",
)

A reach ladder.

Attach any combination to a single node. The engine syncs over all available links simultaneously and deduplicates changesets. Network when you have a subnet. Internet when you have a broker. Radio when you have neither.

Network
UDP

Works on any subnet. No infrastructure required — nodes discover each other via broadcast.

  • RangeNetwork
  • BandwidthUnconstrained
  • InfrastructureNone
  • Latency< 1 s
Internet
MQTT

Works wherever a broker is reachable — LAN, cell, or Starlink at the ICP.

  • RangeInternet
  • BandwidthUnconstrained
  • InfrastructureMQTT broker
  • Latency< 1 s
Radio
LoRa

Works when neither Network nor Internet does. 5–15 km, no infrastructure, sub-watt power. Actual bandwidth depends on your regional band and duty-cycle limit.

  • Range5 – 15 km
  • Bandwidth~110 B/min – 5 KB/min*
  • InfrastructureNone
  • Latency~20 s per packet

Ready to go offline?

Read the Go quickstart to get a node syncing in minutes.