10 — DML Analysis and ELF

DML analysis and ELF

The DML tab is where you discover who is actually doing work in the org, and whose licence is fully wasted.

What ELF is

ELF = Event Log File. Salesforce records every API call, every login, every DML operation, every callout, every report run as a row in an hourly CSV log. The logs are exposed as the EventLogFile object — each record has LogDate, EventType (Login, API, RestApi, DatabaseSave, CalloutRequest, etc.), and a LogFile URL to download the actual CSV.

ELF is a permission-gated feature: the connected sf user needs the View Event Log Files permission, and the org needs to have the feature enabled (it's included on most editions but check). Without ELF, the DML tab has nothing to draw on.

Stood Flows downloads the relevant event types for the analysis period and aggregates them into a small set of JSON files under workspaces/<alias>/graphs/<slug>/elf-aggregates/:

The raw CSVs are kept in workspaces/<alias>/graphs/<slug>/cache/elf/ so re-running an analysis over the same dates is instant.

Triggering the analysis

Button: Analyze DML in the toolbar. You'll be asked for a date range — by default the last completed 17-day window. The first analysis on a fresh date range can take a few minutes (downloading dozens of MB of CSVs); subsequent runs over the same window use the cache.

The end result is license_drill.json and the renderable DML tree.

The six activity buckets

Every user in scope ends up in exactly one of these buckets per analysed period:

Bucket

Definition

active

Logged in AND produced ≥ a threshold of business DML rows. The "real" working users.

lowDml

Logged in AND produced some DML but below the threshold. Light users, dependents on the platform.

pseudoOnly

Logged in AND only produced "pseudo" DML — log objects (Log__c, Email_Status__c), Chatter feed items, admin objects (Profile, Group), etc. They appear in DML logs but their writes don't count as business activity.

noReal

Logged in but every DML row was admin-noise (system fields, audit objects). Even pseudoOnly is too generous a category.

noDml

Logged in but produced no DML at all. Read-only users, browsing-only users.

integration

Never logged in via UI but produced DML. API-only integration accounts, batch service accounts.

The thresholds and the pseudo-DML classification live in graph.json — there's a default list ((logs), (admin), (chatter)) which you can extend per-graph. Right-click a DML target name in the drill to add/remove it from the pseudo list.

The buckets are mutually exclusive and exhaustive — every user in licensingAnalysis.users lands in exactly one.

The drill

The DML sub-tab opens at the Bucket level. Three rows: Named, Community Login, Other. Each shows:

Expand a bucket to see its Licenses. Expand a licence to see its Profiles. Expand a profile to see its Users.

Each level has the same column set so you can compare consistently.

A user row in the drill has additional columns:

Click a user row to see their per-target breakdown.

Reading the buckets

Active

These users are why you have the licences. Look for outliers — a user with 10× the active median is probably running a batch job through a UI session.

lowDml

The "light" users. Common for executive read-mostly profiles. If a profile is mostly lowDml, ask whether they need a full Named seat or a Platform/Identity licence is enough.

pseudoOnly

Be careful with this bucket. Users that only produce log entries / admin changes / Chatter posts are often:

Right-click a target name and add it to the pseudo list to remove a false positive from "real" DML.

noReal

Strictly worse than pseudoOnly. The user logged in and the only DML the system recorded for them was platform noise — audit field updates, session reads. Often these are users whose work is entirely in reports, list views, or external systems that read from Salesforce.

noDml

Logged in, did nothing the platform could see. Pure consumers. Usually fine for portal / community access but for Named licences this is the bucket to scrutinise — paying for a full seat that doesn't write anything is expensive.

integration

API-only accounts. Often legitimate (Marketing Cloud, MuleSoft, custom batch jobs). The Drill expansion shows you the Connected App / External Client App responsible — anything you don't recognise is worth tracking down.

Cross-reference this bucket with the Inbound I/O tab — every integration row here should have a matching caller row there.

How "logged in %" is computed

Logged-in % = logged-in users / assigned users. The numerator is from ELF Login rows; the denominator is from User.IsActive = true + profile membership. A user with LastLoginDate but no Login event in the window doesn't count — only confirmed Login events do.

For Community Login profiles, assigned is pro-rated entitled logins for the window, not user count. So the percentage there reads against the pool, not the seats.

Cost columns

The same Actor $ / Non-actor $ / Unlogged math as the Profiles tab applies here. A user in the active bucket counts as an actor (they made real DML); users in noDml / noReal / pseudoOnly count as non-actors; integration users sit outside the seat-based cost math.

Anchoring evidence

Right-click any cell — bucket row, licence row, profile row, user row — to create an issue with an anchor. The issue body carries a comment like:

<!-- stood-anchor:graph=acme-prod,col=actor$,obj=profile,name=Concierge Agent -->

When you click View on the issue later, the app jumps back to the DML tab, expands the drill to that profile, and highlights the row. The anchor survives refreshes — even after the next ELF analysis overwrites the underlying data, the row is still found.

Common questions

Why is the Login count zero everywhere? You're missing the View Event Log Files permission, or the org doesn't have ELF enabled. The analysis runs but pulls no Login events.

The DML target says Log__c — that's our pseudo log, why is it counted as Real? Add Log__c to the pseudo-DML pattern list (right-click → "Mark as pseudo"). The aggregate will re-classify on the next analysis pass.

The same user appears as active in one bucket and integration somewhere else. That can't happen — buckets are mutually exclusive. What you're probably seeing is two different licences in the user's history within the period; only the current assignment counts.

Can I export the drill? Yes — license_drill_by_license.csv and license_drill_by_profile.csv are written next to the JSON. Both are headed CSVs ready for spreadsheets.

Published with Nuclino