Skip to navigation

Network Flow Logs

Beta

Network Flow Logs (also referred to as flow data) capture metadata about IP traffic generated by devices across emnify’s mobile core. Use them to observe device connectivity behavior, troubleshoot issues, support security analysis, and meet audit or compliance requirements—without inspecting packet payloads or content.

Flow Logs are a subscribable enterprise service. Access them through the emnify Portal, the REST API, or stream them to external systems using Data Streamer.

Each Flow Log record describes observed IP traffic using core network attributes, including source and destination IP addresses, ports, protocol, timestamps, and traffic volume. Records also include hostname attribution and device, session, and network context (for example, organization, endpoint, APN, and serving operator) where available.

With this enrichment, you can identify not only which IP addresses your devices communicate with, but also which domains and services they contact and under which network context.

Flow Log events

Flow Log records are emitted at defined stages of a flow’s lifecycle, indicated by the event_type field:

event_typeDescription
flow_startFirst record emitted when a new flow is observed.
flow_updatePeriodic snapshot of an active flow during a reporting window.
flow_endFinal record emitted when the flow terminates, including release details.

A flow is identified by flow_id. For flow_update records, bytes_up and bytes_down are incremental values for the reporting window from period_start_ts to period_end_ts. On flow_end, the release_details object explains how and why the flow terminated.

Record fields

FieldTypeDescription
flow_idStringUnique identifier of the flow.
org_idIntegerOrganization identifier.
endpoint_idIntegerEndpoint (device) identifier.
vnet_idIntegerVirtual network identifier.
pdp_session_idStringPDP session identifier associated with the flow.
event_typeStringLifecycle stage: flow_start, flow_update, or flow_end.
directionStringTraffic direction: egress (from the device) or ingress (toward the device).
protocolIntegerIANA protocol number (for example, 6 for TCP, 17 for UDP). See protocol values.
src_ipStringSource IP address, as observed in the mobile core.
src_portIntegerSource port.
dst_ipStringDestination IP address.
dst_portIntegerDestination port.
bytes_upIntegerBytes sent by the device during the reporting window.
bytes_downIntegerBytes received by the device during the reporting window.
flow_start_tsString (RFC3339)When the flow was first observed.
period_start_tsString (RFC3339)Start of the reporting window.
period_end_tsString (RFC3339)End of the reporting window.
last_loaded_atString (RFC3339)When the record was last loaded.
nat_detailsObject or nullNAT translation details, when applicable. See Enrichment objects.
domain_nameObject or nullDestination name attribution, when available. See Enrichment objects.
pdp_contextObject or nullMobile network context, when available. See Enrichment objects.
release_detailsObject or nullFlow termination details, on the last record of a flow. See Enrichment objects.

Enrichment objects

The following objects are present when the corresponding enrichment is available.

nat_details—NAT translation details:

FieldTypeDescription
translated_src_ipStringSource IP after NAT translation.
translated_src_portIntegerSource port after NAT translation.
public_ipStringPublic IP address after NAT translation.

domain_name—destination name attribution:

FieldTypeDescription
hostnameStringDestination hostname or domain.
sourceStringHow the hostname was attributed (for example, TLS_SNI, reverse_dns).

pdp_context—mobile network context:

FieldTypeDescription
mccStringMobile country code.
mncStringMobile network code.
apnStringAccess point name.
imsiStringInternational Mobile Subscriber Identity of the SIM.
countryObjectServing country: name, country_code, iso_code, and id.
operatorObjectServing operator: id and name.

release_details—flow termination details, on the last record of a flow:

FieldTypeDescription
release_reasonStringWhy the flow terminated (for example, tcp_fin, tcp_rst, idle_timeout).
release_sideStringSide that initiated the termination: device, server, or unspecified.

Event timing

emnify doesn’t emit Flow Log records on a fixed schedule. For an active flow, a minimum period limits how often updates are emitted, and emnify checks whether a record is due at a regular interval. By default, the minimum period is 60 seconds and the check interval is 10 seconds. Because checks run periodically, records can come several seconds later than the minimum period, and their timestamps don’t fall on exact 60-second boundaries. These differences are expected and don’t indicate lost data. These default values can change.

  • flow_start: the first record covers the flow’s first 10 to 20 seconds by default, so you see new flows early. A DNS flow can expire before the first check. Its only record is then a flow_start record that already contains release_details.
  • flow_update: 60 seconds is the minimum period between updates, not a fixed schedule. Under continuous traffic, updates are emitted about 60 to 70 seconds apart. If no bytes were transferred since the previous record, emnify emits no update and starts a new window, so a flow’s records can have gaps between them while the flow is idle. If the flow stays idle, it ends when its idle timeout expires.
  • flow_end: emnify checks for expired flows about every 3 seconds, so the record is emitted within about 3 seconds after the flow’s idle timeout expires. Its window covers at most about the last 70 seconds of the flow, and often less. Because some idle timeouts are long, the flow_end record can come hours after the previous record.

How a flow ends depends on the protocol:

ProtocolTypical release_reasonWhy
TCPtcp_fin or tcp_rstAfter a FIN or RST, the flow ends when the transitory TCP idle timeout expires.
UDPidle_timeoutUDP has no close signal, so the flow ends after its idle timeout without packets.

The idle timeout depends on the flow type. The default values are 30 seconds for ICMP, 3 minutes for UDP, 10 seconds for UDP DNS, 30 seconds for transitory TCP, and 4 hours 8 minutes for established TCP. These values can change.

TCP flow example

event_typeperiod_start_tsperiod_end_tsWindowrelease_reasonWhat it means
flow_start14:42:0514:42:1510 s—The flow becomes visible early with a short first window.
flow_update14:42:1514:43:2570 s—The 60-second minimum period ended shortly after a check, so the record waited for the next check.
flow_end14:43:2514:43:3914 stcp_finThe FIN came about 30 seconds earlier, and the flow ended when the transitory TCP idle timeout expired.

A short flow_end window after a longer flow_update is normal for TCP.

UDP flow example

A UDP flow follows the same pattern for flow_start and flow_update. It ends with idle_timeout after the UDP idle timeout elapses without packets. The flow_end record is emitted at the first check after the flow expires, so it appears up to about 3 seconds after the timeout.

Example records

{
"flow_id": "a1b2c3d4-e5f6-4890-abcd-ef0123456789",
"org_id": 12345,
"endpoint_id": 67890,
"vnet_id": 1,
"pdp_session_id": "pdp-9f3c1b27",
"event_type": "flow_start",
"direction": "egress",
"protocol": 6,
"src_ip": "100.64.0.1",
"src_port": 60570,
"dst_ip": "104.18.3.24",
"dst_port": 443,
"bytes_up": 375,
"bytes_down": 1154,
"flow_start_ts": "2026-01-15T10:55:04.731Z",
"period_start_ts": "2026-01-15T10:55:04.731Z",
"period_end_ts": "2026-01-15T10:55:16.271Z",
"nat_details": {
"translated_src_ip": "100.64.0.1",
"translated_src_port": 61396,
"public_ip": "133.7.133.7"
},
"domain_name": {
"hostname": "example.org",
"source": "TLS_SNI"
},
"pdp_context": {
"mcc": "262",
"mnc": "02",
"apn": "em",
"imsi": "262021234567890",
"country": { "name": "Germany", "country_code": "49", "iso_code": "de", "id": 74 },
"operator": { "id": "26202", "name": "Vodafone" }
},
"last_loaded_at": "2026-01-15T10:55:30.000Z"
}
{
"flow_id": "a1b2c3d4-e5f6-4890-abcd-ef0123456789",
"org_id": 12345,
"endpoint_id": 67890,
"vnet_id": 1,
"pdp_session_id": "pdp-9f3c1b27",
"event_type": "flow_end",
"direction": "egress",
"protocol": 6,
"src_ip": "10.50.12.34",
"src_port": 49312,
"dst_ip": "52.85.77.20",
"dst_port": 443,
"bytes_up": 24576,
"bytes_down": 262144,
"flow_start_ts": "2026-01-15T10:18:06.000Z",
"period_start_ts": "2026-01-15T11:02:15.000Z",
"period_end_ts": "2026-01-15T11:02:41.000Z",
"domain_name": {
"hostname": "api.example.com",
"source": "DNS_REPLY"
},
"pdp_context": {
"mcc": "262",
"mnc": "02",
"apn": "em",
"imsi": "262021234567890",
"country": { "name": "Germany", "country_code": "49", "iso_code": "de", "id": 74 },
"operator": { "id": "26202", "name": "Vodafone" }
},
"release_details": {
"release_reason": "tcp_fin",
"release_side": "device"
},
"last_loaded_at": "2026-01-15T11:02:55.000Z"
}