SfSkills Domains Docs GitHub

Home / devops / appexchange-app-analytics

appexchange-app-analytics

Use when an ISV partner needs usage telemetry for an AppExchange managed package — activating AppExchange App Analytics on a 1GP/2GP package, submitting AppAnalyticsQueryRequest records from the License Management Org, and downloading package usage logs, monthly usage summaries, and subscriber snapshots as CSV/Parquet.

Open the skill folder on GitHub


AppExchange App Analytics

This skill activates when an ISV partner wants to know how subscribers actually use their AppExchange managed package — which components get touched, by how many users, in which orgs — and needs to activate AppExchange App Analytics and pull its data. The mechanism is the AppAnalyticsQueryRequest object, created in the License Management Org (LMO) that owns the package; results arrive as downloadable CSV (or Parquet) files.


Before Starting

Gather this context before working on anything in this domain:


Core Concepts

Three data products, three cadences

Data productDataType valueCadenceActivation needed?Retention
Package usage logsPackageUsageLogNightly (~05:00 instance local time, previous day's data, precise event timestamps)Yes45 days
Package usage summariesPackageUsageSummaryMonthly (timestamps normalized to 00:00 UTC on the last day of the month)No — available by default10 years
Subscriber snapshotsSubscriberSnapshotNightly (collected ~01:00, generated ~03:00 instance local time; timestamps normalized to 00:00 UTC)Yes45 days

Usage logs track UI, API-based, Lightning-based, and Apex operations, and log each CRUD operation on packaged components and custom objects. Each log row carries the org context (organization_id, edition, type), a pseudonymized user_id_token (Salesforce can't store an actual user ID for privacy compliance), a log_record_type (e.g. API, ApexExecution, LightningInteraction, LightningPageView, VisualforceRequest), the packaged custom_entity, and an operation_type (INSERT, READ, UPDATE, DELETE, SOQL_QUERY, SOSL_QUERY) with an operation_count.

Activation is per package, one command for 2GP

For a 2GP package, activation is a one-time Salesforce CLI command (keep the CLI current with sf update and sf plugins update):

sf package update --package "Your Package Alias" --enable-app-analytics
# to deactivate:
sf package update --package "Your Package Alias" --no-enable-app-analytics

For a 1GP package, the 1GP guide's activation steps apply — the docs frame it the same way ("Activate AppExchange App Analytics on your first-generation (1GP) managed package") but the mechanics live in the 1GP developer guide, not the CLI reference.

The user pulling data needs Create, Read, Edit, Delete, View All, and Modify All on the AppAnalyticsQueryRequest object, plus Read on Packages and Package Versions.

The AppAnalyticsQueryRequest lifecycle

You create a record describing what you want; the platform processes it asynchronously; you poll and then download:

Prior to Summer '20 the DataType values were CustomObjectUsageLog and CustomObjectUsageSummary; those legacy names work only with API v47.0 and earlier.

Data-lake timing drives when you query

Usage data flows into a Salesforce data lake throughout the day, region by region: EMEA arrives first, then North America, then Asia Pacific. Ordinarily all org data arrives by 23:00 UTC the day after it was recorded (occasional delays happen). Practical consequences:


Common Patterns

Nightly incremental pull with AvailableSince

When to use: an automated pipeline that lands each day's usage logs into a warehouse without gaps or duplicates.

How it works: persist the timestamp of the last successful pull; each night create an AppAnalyticsQueryRequest with DataType = PackageUsageLog and AvailableSince set to that watermark, so you only receive data that arrived in the data lake since then. Poll RequestState, download within the 60-minute URL window, then advance the watermark.

Why not the alternative: re-pulling fixed StartTime/EndTime windows either misses late-arriving regional data or double-counts it, and repeated wide pulls burn the 20 GB/24h budget.

Scoped pulls to stay under the 20 GB cap

When to use: a large install base where an unscoped pull risks the daily download cap or a Failed/oversized request.

How it works: split requests by PackageIds (up to 16 per request) and/or OrganizationIds, request gzip CSV or Parquet, and keep windows to one UTC day. Track DownloadSize per request to project your 24-hour total.

Why not the alternative: one giant uncompressed all-orgs pull can blow the 20 GB/24h limit and leaves no room to retry a failed download that day.

Adoption and churn baseline: summaries + snapshots

When to use: roadmap or renewal conversations — which features are used, which subscribers are going quiet.

How it works: use monthly PackageUsageSummary pulls (no activation required, 10-year retention) as the long-term trend line, and nightly SubscriberSnapshot pulls for point-in-time subscriber activity. Join on the org identifier; falling active-user counts against a stable license count is the attrition signal the feature is designed to surface.


Decision Guidance

SituationRecommended ApproachReason
Need month-over-month adoption trend onlyPackageUsageSummary pullsAvailable by default (no activation) and retained 10 years
Need per-event, per-component detailActivate App Analytics, pull PackageUsageLog nightlyLogs need activation and are only retained 45 days — pull continuously
Need "who is going quiet" churn signalSubscriberSnapshot nightly + summary trendSnapshots are the point-in-time subscriber activity view
Automating a pipelineAvailableSince watermark patternOnly mechanism that tracks data-lake arrival instead of event time
Large install base / big filesScope by PackageIds/OrganizationIds, gzip or ParquetStay under the 20 GB/24h download cap
Subscriber has Government Cloud orgsSet expectations: that data is absentGov Cloud / Gov Cloud Plus usage data isn't available in App Analytics
Need subscriber-org security auditingNot this feature — use Event Monitoring in the subscriber orgApp Analytics is partner-facing package telemetry, pseudonymized by design

  1. Verify eligibility and access — the package passed security review, is registered to an LMA, and you can log in to the owning LMO with CRUD/View All/Modify All on AppAnalyticsQueryRequest plus Read on Packages and Package Versions.
  2. Activate if you need logs or snapshots — for 2GP run sf package update --package "<alias>" --enable-app-analytics (summaries need no activation); for 1GP follow the 1GP guide's activation steps.
  3. Design the pull — pick DataType, scope (PackageIds, OrganizationIds), window (StartTime/EndTime and/or AvailableSince), and format (FileType, FileCompression), respecting UTC day boundaries and the 23:00 UTC arrival guarantee.
  4. Create the request in the LMO — insert the AppAnalyticsQueryRequest record via the SOAP API and record its Id.
  5. Poll and download promptly — poll RequestState until Complete (handle Failed via ErrorMessage, and NoData/Expired explicitly); download from DownloadUrl within 60 minutes of completion.
  6. Operationalize — schedule pulls inside the 45-day retention window for logs/snapshots, track cumulative DownloadSize against the 20 GB/24h cap, and keep pulling at least every 90 days — inactivity for 90 days can cause Salesforce to stop collecting your data (a Partner Community support case is needed to resume).

Review Checklist

Run through these before marking work in this area complete:


Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems (full list in references/gotchas.md):

  1. 90 days of inactivity can silently stop data collection — if you don't view/pull log or snapshot data for 90 days, collection may cease and only a support case via the Salesforce Partner Community resumes it. A "set it up and come back next quarter" plan loses data.
  2. The download URL is a 60-minute window — DownloadExpirationTime is 60 minutes after completion. Poll-then-download must be one automated motion, not a human checking a queue later.
  3. Querying too early looks like missing data — regional data lands EMEA → NA → AP and is only guaranteed complete by 23:00 UTC the next day; an early pull returns a plausible-looking but partial file, or NoData.

Output Artifacts

ArtifactDescription
Activation runbookCLI command + permission checklist to turn on App Analytics for the package
AppAnalyticsQueryRequest request specField-by-field request definition (see templates/appexchange-app-analytics-template.md)
Pull pipeline designWatermark (AvailableSince) schedule with polling, download, and cap tracking
Downloaded datasetsCSV/Parquet usage logs, monthly summaries, subscriber snapshots for analysis

Package files