Skip to main content

InfluxDB Line Protocol (Ingest)

The IoT de-facto ingest path: devices, Telegraf and collectors already speak it. TCP, newline-delimited, fire-and-forget.

<table>,entity=<device> <field>=<value>[,<field>=<value>...] [<timestamp-ns>]
# config: listen.ilp = ":9009", listen.ilp_db = "acme"
printf 'telemetry,entity=veh-1 speed=52.5,status="moving" 1700000000000000000\n' | nc host 9009

Semantics

  • the entity tag is required; other tags are ignored
  • timestamps are nanoseconds (converted to the engine's milliseconds); omitted = server time
  • unknown tables and channels are auto-registered in the catalog: kind inferred from the first value, FILL NONE — mechanics only, never meaning. Declare channels properly via CREATE TABLE when you want HOLD/staleness, or fix an auto-registered one afterwards with ALTER TABLE.
  • value syntax → frozen types: "..." → string; 4.2, 42i → f64; true/false → f64 1/0. A first boolean value auto-registers the channel as semantic bool (later writes must be true/false/1/0; reads render booleans); a first 42i-style value auto-registers it as semantic int (later writes must be whole numbers; reads render integers)
  • a malformed line is dropped; the stream lives on (per-line contract). A type conflict with the catalog is an error, not a coercion.

Security model

ILP carries no credentials. One listener binds to one database (-ilp-db); run one listener per database and firewall it to that tenant's devices. For authenticated ingest, write over pg-wire (INSERT, SCRAM-authenticated) instead.