As the Analytics monitor is a component integrated into your application, it is only natural for conscious software developers to be concerned about the overhead of this integration:
Q: What is the overhead of adding Analytics to my application?
A: It depends - but generally it's very low. The monitor is optimized to impose very little overhead in all respects, on all platforms.
This article will describe the overhead in detail. It will delve into these aspects:
- Runtime Processing: processing time spent by the monitor
- Runtime Memory: amount of memory claimed by the monitor
- File Storage: disk space claimed by the monitor
- Network Traffic: communication with the Analytics servers
O/S Resources: operating system resources claimed by the running monitor
- Code size: size of the monitor-component added to your application
- Risks: valuation of the risk and side-effects of adding the monitor
Here is a top-level overview of the moving parts of the monitor, which will be referenced in the upcoming sections:
On all platforms the monitor's API is non-blocking, with the exception of
Every API call only does very simple parameter-checking and places incoming data on shared in-memory structures for a background thread from the threadpool to pickup and handle asynchronously at regular intervals, as illustrated in the overview above.
Adding data to the in-memory data-structures is really quick. This means that you do not have to worry about the monitor's API methods blocking the caller and it is e.g. perfectly fine to call the monitor API directly from a UI handler. There is therefore no need to delegate calls to the monitor API to a background thread yourself - the monitor already does that for you.
The monitor's background thread handles the registered statistics. New data is serialized and saved to disk every minute and submitted to the server when either of
Stop is called or every 24 hours, and this is the only additional monitor processing overhead. Typically this contributes very little to the CPU-consumption of any application.
Also related to API overhead is the fact that all API calls (except
SetInstallationInfo) do nothing if
Start has not been called yet; they simply return immediately. If you wish to disable Analytics it will suffice to simply not call
Start - there is no need to set and use a flag to avoid invoking API methods in your entire application.
The only blocking method is
Stop. The reason being that it is prudent to give the monitor a chance to deliver the session's data to the Analytics servers before shutting down the monitor. The default timeout for
Stop is 2 seconds. If you need a different timeout then use
The monitor API is non-blocking, presents a low processing overhead, and is usually ready to be used as-is.
Statistics data is stored in-memory before being saved and submitted to the Analytics servers. There is no upper limit on the memory needed by the monitor for storing this, but the monitors have been designed to work even on the tiniest of platforms, including the .NET Compact Framework and on mobile apps, and the data structures and data processing approaches are therefore fundamentally designed to be very memory-efficient.
For instance, storing
TrackFeature information only takes up a single hashtable-entry consisting of the tracked feature's name and the total count.
The most memory-intensive data structures are feature timing, feature value, and exceptions.
- Feature timing and feature value needs to store all the reported 32-bit values and the data will therefore take up entries * 4 bytes.
- Exception data can be large due to the reported error message and stack trace. The stack trace is truncated to a maximum of default 1000 characters. However, when an exception is registered the monitor will attempt to save and deliver that information immediately so exception data does not pile up in-memory.
Memory usage should usually be no concern. However, massive feature timing and feature value tracking can take up much memory. Exceptions can consume significant amounts of memory as well, but are dispatched to the server immediately.
The monitor stores statistics data in the local filesystem while attempting to deliver it to the Analytics servers. Statistics data for a session is typically in the order of 1-5KB, but can be more if feature timing/value or exceptions are being reported.
If the monitor is online then only 1 statistics file will be stored and it will be removed upon successfull delivery.
If the monitor is offline and cannot deliver statistics data to the Analytics servers then the corresponding statistics-files are kept. At startup, re-submission of these old sessions are attempted again (max 5 at each startup) and they are deleted upon successfull delivery. Ultimately, in the unlikely event that the monitor never is online, they will be stored forever.
By default there is no limit to the disk space used by the monitor. The developer can impose a restriction by adjusting the
MaxStorageSizeInKB setting when creating the monitor. When that limit is reached, no further data will be stored (but delivery to the Analytics servers will still be attempted).
// C# for .NET, WinRT, Silverlight etc IAnalyticsMonitorSettings settings = AnalyticsMonitorFactory.CreateSettings("key"); settings.MaxStorageSizeInKB = 10000; IAnalyticsMonitor monitor = AnalyticsMonitorFactory.CreateMonitor(settings);
' VB.NET Dim settings As IAnalyticsMonitorSettings = AnalyticsMonitorFactory.CreateSettings("key") settings.MaxStorageSizeInKB = 10000 Dim monitor As IAnalyticsMonitor = AnalyticsMonitorFactory.CreateMonitor(settings)
// C++ for Windows IAnalyticsMonitorSettings *settings = AnalyticsMonitorFactory::CreateSettings("key", "1.0"); settings->MaxStorageSizeInKB = 10000; IAnalyticsMonitor *monitor = AnalyticsMonitorFactory::CreateMonitorWithSettings(settings);
// C for Windows Eqatec_IAnalyticsMonitorSettings *settings = Eqatec_AnalyticsMonitorFactory_CreateSettings("key", "1.0"); Eqatec_AnalyticsMonitorSettings_SetMaxStorageSizeInKB(settings, 10000); Eqatec_IAnalyticsMonitor *monitor = Eqatec_AnalyticsMonitorFactory_CreateMonitorWithSettings(settings);
// Objective-C for iOS and MacOSX EQATECAnalyticsMonitorSettings *settings = [EQATECAnalyticsMonitorSettings settingsWithProductId:@"key" version:@"1.0"]; [settings maxStorageSizeInKB:10000]; EQATECAnalyticsMonitor *monitor = [EQATECAnalyticsMonitor monitorWithSettings:settings];
// Java for Android and Java IAnalyticsMonitorSettings settings = AnalyticsMonitorFactory.createSettings("key", new Version("1.0")); settings.maxStorageSizeInKB = 10000; IAnalyticsMonitor monitor = AnalyticsMonitorFactory.createMonitor(settings);
File storage is typically 1-5KB per session. For online applications only temporary storage of that order is needed. The developer can limit disk usage via the
Statistics data is delivered to the Analytics server when either
Stop is called, or every 24 hours. Each session data content is typically 1-5KB big. It is submitted using HTTP so there is the additional overhead of the HTTP protocol (or HTTPS, if so selected).
For an application that does not report exceptions, this means that there will typically only be two network transmissions: one when the monitor is started and one when it is stopped.
By default there is no limit to the network traffic used by the monitor. The developer can impose a restriction by adjusting the
MaxBandwidthUsagePerDayInKB setting when creating the monitor. When that limit is reached no further data will be transmitted that day. Data will still be collected and saved to file, though.
// C# for .NET, WinRT, Silverlight etc IAnalyticsMonitorSettings settings = AnalyticsMonitorFactory.CreateSettings("key"); settings.MaxBandwidthUsagePerDayInKB = 100; IAnalyticsMonitor monitor = AnalyticsMonitorFactory.CreateMonitor(settings);
// VB.NET for .NET, WinRT, Silverlight etc IAnalyticsMonitorSettings settings = AnalyticsMonitorFactory.CreateSettings("key"); settings.MaxBandwidthUsagePerDayInKB = 100; IAnalyticsMonitor monitor = AnalyticsMonitorFactory.CreateMonitor(settings);
// C++ for Windows IAnalyticsMonitorSettings *settings = AnalyticsMonitorFactory::CreateMonitorSettings("key", "1.0"); settings->MaxBandwidthUsagePerDayInKB = 100; IAnalyticsMonitor *monitor = AnalyticsMonitorFactory::CreateMonitorFromSettings(settings);
// C for Windows Eqatec_IAnalyticsMonitorSettings *settings = Eqatec_AnalyticsMonitorFactory_CreateMonitorSettings("key", "1.0"); Eqatec_AnalyticsMonitorSettings_SetMaxBandwidthUsagePerDayInKB(settings, 100); Eqatec_IAnalyticsMonitor *monitor = Eqatec_AnalyticsMonitorFactory_CreateMonitorFromSettings(settings);
// Objective-C for iOS and MacOSX EQATECAnalyticsMonitorSettings *settings = [EQATECAnalyticsMonitorSettings settingsWithProductId:@"key" version:@"1.0"]; [settings maxBandwidthUsagePerDayInKB:100]; EQATECAnalyticsMonitor *monitor = [EQATECAnalyticsMonitor monitorWithSettings:settings];
// Java for Android and Java IAnalyticsMonitorSettings settings = AnalyticsMonitorFactory.createSettings("key", new Version("1.0")); settings.maxBandwidthUsagePerDayInKB = 100; IAnalyticsMonitor monitor = AnalyticsMonitorFactory.createMonitor(settings);
Network usage averages at about 10KB per session. The developer can limit the network usage via the
A running monitor typically consumes few O/S resources: one thread, a few timers, a network connection, some locks and events and files in the local file system.
However, each monitor-instance is completely self-contained so multiple monitor instances do not share or pool their resources. Since the claimed resources are specific for each monitor-instance, creating and starting e.g. 10,000 monitor instances in your application will require 10,000 threads. This is typically a bad idea.
The monitor does not use any other resources than those mentioned. It does not write to the system event log, claim GUI object handles, bring up popup-alerts, read the GPS-coordinates, or anything like that.
A single monitor instance uses negligible operating system resources. However, it is not well-suited to be used in designs involving virtually unlimited instances.
The monitor's approximate contribution to your application total size is listed below, for each platform.
(As of monitor version 3.2.x, Jan 2014)
|Platform||Code size (approximate)|
|Icenium||(same as iOS and Android, respectively)|
|Android, Java||analyticsmonitor.jar: 140KB|
|Full .NET||EQATEC.Analytics.Monitor.dll: 65KB|
|.NET CF||EQATEC.Analytics.MonitorCF.dll: 60KB|
|Windows Phone||EQATEC.Analytics.MonitorWP.dll: 60KB|
|Windows C, C++||EQATEC.Analytics.Monitor.Win32_vc100.dll+lib: 3MB
|Windows COM||EQATEC.Analytics.MonitorCOM+Facade.dll: 70KB|
Introducing a third-party component into your application may also result in added risks. Here is a non-exhaustive assessment of risks:
- Monitor errors: The monitor has been designed to never produce any errors or throw unexpected exceptions, whether due to the environment (e.g. low-memory conditions) or to programming errors. All errors, internal or caused by invalid user input to the API, are reported via the observable LoggingInterface.
- API robustness: The monitor has been designed to cope with any kind of malformed user-input, on all platforms. No matter what the input is it should never cause an error or throw an exception. Developers do not need to wrap calls to the API inside try-catch blocks.
- Increased code size: Adding the monitor will make your application bigger. We have worked hard to make the monitor as compact as possible, but it does perform quite a number of tasks and is therefore non-trivial in size. It is possible that the added code in the monitor could push your application over some platform-specific limit which would make it behave differently. For instance, on iOS there is a 100 MB limit for over-the-air downloads from App Store and adding the monitor could possibly push your app over that limit.
Software-wise, integrating the Analytics monitor into an application is a low risk.
This article should enable you to assert the implications of integrating the Analytics monitor into your application.