All numbers on this page are typical ranges from early-access measurements, taken
from the notarized
EDRApp.app build running with SIP enabled. macOS endpoint volume
is workload-dependent: a developer’s laptop running builds, containers, and IDEs
generates far more file_open traffic than a kiosk or an executive’s mail-and-browser
machine. Treat these as planning baselines, not SLAs. See
System requirements for the supported OS
matrix.Per-endpoint event rates
The macOS collector subscribes to 12 Apple Endpoint Security (ES) event types (mostly NOTIFY; a few AUTH for agent self-protection) plus a per-flow network source, and emits them as JSON lines that the forwarder ships to the Hiltedr-collector. The volume is heavily dominated by file_open — a
single macOS host routinely emits thousands of ES events per minute, and the vast
majority are file opens. Apple’s own framework guidance describes macOS as emitting
thousands of ES events per minute per host, and our live data confirms it.
The table below shows a representative 15-minute window from one enrolled developer Mac
(Zin's MacBook Pro, Apple Silicon), normalized to per-minute rates. file_open
accounts for roughly 95%+ of all telemetry.
Why
file_open dominates. Every process touch of the filesystem — dynamic library
loads, font and cache reads, plist lookups, IDE indexing, Spotlight, package managers —
surfaces as an open/create. A busy developer machine compiling or running containers can
spike file_open to tens of thousands per minute for short bursts. This is exactly
why the collector applies aggressive userspace filtering before anything leaves the
host (see Agent filtering).
The low-frequency events are the high-signal ones. exec carries argv, the
signing identity (signing_id, team_id, cdhash) and the code_signature trust
verdict; btm_add means a launch agent/daemon or login item was registered
(persistence); xattr_set/xattr_delete is Gatekeeper quarantine tampering;
signal is a kill attempt. These cost almost nothing in volume but are the events a
detection engineer queries. See the
Event data model for the full field inventory.
Event volume distribution
Because the distribution is so skewed, capacity planning is essentially afile_open
problem. Roughly 19 out of every 20 events a Mac ships are file opens; everything
else combined — process, network, persistence, device, signal, xattr — is a few percent.
A practical consequence: tuning the
file_open filter is the single highest-leverage
lever for controlling both endpoint CPU and ingest bandwidth. The other event families
can be enabled in full without materially moving the volume needle.
System Extension CPU and memory footprint
The collector ships as a notarized macOS app,EDRApp.app, that embeds two Apple
System Extensions running in user space (there is no kernel extension):
ESensor— the Endpoint Security system extension. This is the telemetry sensor that subscribes to the ES events above. Bundle idHilt.EDRApp.ESensor.NetFilter— a NetworkExtension content-filter system extension that provides per-flow network attribution. Bundle idHilt.EDRApp.NetFilter.
csrutil disable,
SIP enabled), the footprint is that of an ordinary hardened user-space process.
Notes on the footprint.
- macOS delivers ES events synchronously on the extension’s message queue. The sensor’s
job is to classify, filter, and enqueue fast so it never becomes the bottleneck for a
busy machine. Memory is dominated by the per-process and signing-identity caches that
let helpers fold to their owning app (e.g.
Google Chrome Helper→Google Chrome) and that propagateresponsible_pid/session_id. - The figures above are for a NOTIFY-only telemetry posture. The agent subscribes to
a few events as AUTH (
signal,unlink,rename) purely for self-protection (it can deny tampering with itself); AUTH handling adds negligible steady-state cost because these events are rare, but it does keep the sensor on the synchronous decision path for those specific operations. - CPU scales with un-filtered
file_openrate, not with shipped volume — the expensive work is inspecting the firehose. Filtering happens before serialization, so tightening the filter reduces both CPU and bandwidth at once.
These are early-access measurements. The collector does not apply a hard CPU or
memory ceiling to the System Extension itself; Apple manages the extension lifecycle.
If you require a strict ceiling for fleet policy, coordinate with your account team —
on-device resource caps are not part of the early-access shipping model.
Network bandwidth
The forwarder ships events as batched, compressed, outbound HTTPS to the configured Hilt ingest endpoint. There are no inbound sockets and no phone-home — only outbound HTTPS to the one configured endpoint (see Networking and security). Bandwidth is again a function offile_open volume after filtering. Each event is a
compact JSON line; the dominant file_open records are small (path, flags, actor,
signing identity, application attribution). Batching and compression are what make the
firehose affordable on the wire.
What drives the wire cost.
- Compression typically achieves a high ratio on this payload because event JSON is highly repetitive (the same paths, bundle ids, and signing identities recur), so the compressed egress is a fraction of the raw line volume.
- Batching amortizes TLS and request overhead: events are accumulated and flushed together rather than one request per event, which keeps connection overhead flat as volume rises.
- Filtering first — because aggressive userspace
file_openfiltering runs before the forwarder ever sees an event, the bytes on the wire reflect post-filter volume, not the raw ES firehose.
How the collector tier scales with host count
On the server side, macOS hosts flow through the same pipeline as Linux, with the macOS-specific enrichment platform:1
Forwarder → edr-collector
Each Mac’s forwarder LaunchDaemon ships compressed HTTPS batches to the Hilt
edr-collector. Connections are outbound-only and long-lived/batched, so the
collector sees a steady request rate proportional to host count, not to raw event
rate.2
edr-collector → MSK Kafka
The collector routes events to MSK Kafka topics by class:
dag.endpoint.exec, dag.endpoint.file, and dag.endpoint.net. Because
file_open is ~95%+ of volume, the dag.endpoint.file topic carries the bulk of
the partition load and should be sized first.3
Enrichment (ENRICH_PLATFORM=macos)
The enrichment service consumes the topics, stamps code-signing trust and
application attribution, and normalizes records. This is the consumer tier that
scales with aggregate events/sec across the fleet.
4
ClickHouse (endpoint_events)
Enriched rows land in the purpose-built, macOS-native
endpoint_events table.
Storage and query cost scale with total fleet event volume — again dominated by
file_open.5
Dashboard
macOS hosts appear in the Collectors fleet view with a
macOS host-type badge, and in the Investigate, Networks, Files, and Users views.
- Aggregate volume is what sizes the tier, not host count alone. A back-of-envelope fleet estimate: multiply your host count by a per-host steady-state rate (use ~5,000–15,000 events/min for a mixed workstation fleet, far higher for developer-heavy populations) to get aggregate events/sec for Kafka partition and enrichment-consumer sizing. One reference Mac alone produced ~844,000 rows in 15 minutes (~940/sec) during active developer use — so heavy hosts dominate the estimate.
- Size the
file_openpath first. Because the distribution is so skewed,dag.endpoint.filepartitions and the macOS enrichment consumers keyed to file events are the components that saturate first. Theexec/netpaths are comparatively light. - Egress is bounded by compression. Server-side ingest bandwidth scales linearly with the compressed per-host egress figures above; there is no fan-out amplification on the collector for macOS hosts.
- Per-host enrichment cost is uniform. Every macOS event carries the same code-signing and application-attribution enrichment, so enrichment CPU tracks aggregate event rate cleanly — there is no host-specific enrichment hot spot.
Tuning levers
When a fleet’s volume or egress is higher than budgeted, the levers — in order of leverage — are:- Tighten
file_openfiltering. This is ~95%+ of volume; excluding high-churn cache and build directories is the single biggest reduction in both endpoint CPU and egress. See Agent filtering. - Scope process events.
exec/forkare already low volume; no action needed in most fleets, but they are the highest-signal-per-byte events and should generally stay on. - Leave the security long-tail on.
btm_add,xattr_set/xattr_delete,mount, andsignalare event-driven and rare — they add negligible volume while providing persistence, quarantine-tamper, removable-media, and kill-attempt visibility.
What this collector does not do
Consistent with the rest of the macOS collector design:- No on-device resource cap on the System Extension. Apple manages the extension
lifecycle; the collector does not impose a hard
CPUQuota/MemoryMaxon the ES extension the way the Linux VM installer can on a systemd unit. On-device resource caps are not part of the early-access model. - No inbound listeners. Bandwidth is strictly outbound, batched, compressed HTTPS to the one configured ingest endpoint — there is no inbound socket to size for and no phone-home.
- No raw packet capture. Network bandwidth reflects
net_flowconnection metadata (destination, ports, byte counts, bundle id), not payload — so network telemetry adds only ~1–2% to volume, never a packet-capture-scale load. - No file-content shipping.
file_openis metadata (path, flags, actor, signing identity); the collector never reads or ships file contents, so file volume is bounded by event count, not by file size.
The macOS collector is in early access. The notarized
.pkg install with SIP
enabled described across these pages is the target shipping model; auto-update and
on-device quarantine response are not yet available on macOS. Sizing figures will be
refreshed as the fleet grows beyond early-access deployments.