Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Hi everyone,
I’m currently working on extracting app metadata using the Qlik Repository API, specifically this endpoint:
/api/v1/apps/{appId}/data/metadata
My goal is to retrieve reload performance metrics such as:
cpu_time_spent_ms
peak_memory_bytes
fullReloadPeakMemoryBytes
for exemple on around 600 apps (latest reload only).
I’m looping over all app IDs and calling the API via the REST connector.
Here is the script I’m using:
SUB app_metadata
For Each vAppGUID in FieldValueList('AppLoopID')
LET vGetAppMetadataUrl = 'https://$(vs_host_and_virtual_proxy_prefix)/api/v1/apps/$(vAppGUID)/data/metadata';
LIB CONNECT TO 'monitor_apps_REST_app';
[TempAppMetadata]:
SQL SELECT
"static_byte_size",
"__KEY_root",
(SELECT
"cpu_time_spent_ms",
"peak_memory_bytes",
"fullReloadPeakMemoryBytes",
"__FK_reload_meta",
"__KEY_reload_meta"
FROM "reload_meta" PK "__KEY_reload_meta" FK "__FK_reload_meta")
FROM JSON (wrap on) "root" PK "__KEY_root"
WITH CONNECTION (
Url "$(vGetAppMetadataUrl)"
);
[AppReloadMetadata]:
LOAD
'$(vAppGUID)' AS [AppID],
[cpu_time_spent_ms],
[peak_memory_bytes],
[fullReloadPeakMemoryBytes]
RESIDENT [TempAppMetadata]
WHERE NOT IsNull([__FK_reload_meta]);
DROP TABLE [TempAppMetadata];
Next vAppGUID
ENDSUB
I frequently get the following error:
HTTP protocol error 504 (Gateway Timeout)
/api/v1/apps/{appId}/data/metadata
Processing ~600 apps takes around 20 minutes
Some calls timeout (504), likely because the endpoint is slow
Is /data/metadata the right endpoint for retrieving reload performance metrics?
Is there a more efficient API endpoint to get:
cpu_time_spent_ms
peak_memory_bytes
fullReloadPeakMemoryBytes
(ideally only for the latest reload)
Are there best practices to avoid 504 errors when looping over many apps?
Has anyone faced similar performance issues with this endpoint?
Looping sequentially over apps
Even though I get the 504 error, the script still manages to retrieve the data.
Any advice or feedback would be greatly appreciated
Thanks!
Great post, and a very well-structured question!
On question 1: Is /data/metadata the right endpoint?
Yes, /api/v1/apps/{appId}/data/metadata does return reload performance metrics including cpu_time_spent_ms, peak_memory_bytes, and fullReloadPeakMemoryBytes. However, it was not designed for bulk iteration. The endpoint opens the app engine session internally to collect the metadata, which is expensive server-side and explains why it is slow and prone to timeouts at scale.
On question 2: Is there a better endpoint?
For reload performance metrics specifically, consider using the reload tasks API combined with the audit/reload logs approach. A more efficient alternative for bulk retrieval is:
GET /api/v1/reloads?appId={appId}&limit=1This endpoint returns reload history including duration and status without opening an engine session. However, it does not expose peak_memory_bytes or fullReloadPeakMemoryBytes directly. Unfortunately, those specific memory metrics are only available via /data/metadata today, so there is no complete alternative for those fields.
On question 3: Best practices to avoid 504 errors
A few approaches that help significantly:
Add a SLEEP between iterations to reduce server pressure:
CALL app_metadata;
CALL Sleep(500);
Batch your app IDs into smaller groups and reload in multiple passes rather than all 600 in one run.
Implement retry logic: since you mentioned the script still retrieves data even after a 504, wrapping the call in an error handler with a retry attempt can make the loop more resilient:
FOR vRetry = 1 TO 3
// your SQL SELECT here
IF ScriptError = 0 THEN
EXIT FOR
END IF
CALL Sleep(2000)
NEXT vRetry
Also, reconnecting inside the loop (LIB CONNECT TO) on every iteration adds overhead. Move the connection outside the loop if the REST connector supports reuse in your environment.
On question 4: Has anyone faced this?
This is a known pain point when using /data/metadata at scale. The endpoint was primarily designed for single-app inspection, not bulk extraction. The 20-minute runtime for 600 apps (roughly 2 seconds per app) is actually close to the expected behavior given how the endpoint works internally.
Suggested architecture for your use case
Instead of calling the API live on every reload, consider building an incremental approach: store the metadata results in a QVD after each successful call, and on the next reload only fetch apps that have reloaded since the last extraction. This way you are never processing all 600 apps in a single run.
Hope this helps!
Thanks a lot for your detailed answer, it really helped clarify how /data/metadata works and why it doesn’t scale well for bulk usage.
So this endpoint relies on the Engine to open the app and compute metadata, which explains both the latency and the timeout issues when iterating over a large number of apps. This also makes sense regarding the lack of a true alternative for metrics like cpu_time_spent_ms.
Taking a step back, this actually raises broader questions on how to approach performance monitoring in Qlik at scale.
I am currently building a monitoring app (thanks to logs, qvd that stored data, lib connect) that is refreshed regularly (focused on recent activity during the day), in order to:
In this context, the challenge is not only about accessing the data, but also about doing it efficiently, without putting too much pressure on the Engine.
So I’d like to ask a few targeted questions:
Thanks again for your insights!
These are excellent questions, and they directly address how Qlik exposes performance data at scale.
Q1: Do Qlik logs expose reliable CPU or resource usage metrics per app or task?
A1: Yes, but through a specific logging mechanism that needs to be explicitly enabled. Since the February 2018 release of Qlik Sense, it is possible to capture granular usage metrics from the QIX in-memory engine based on configurable thresholds, including CPU and RAM utilization of individual chart objects and reload tasks.
This is done via QIX Performance Logging (also called Telemetry Logging). Telemetry data is logged to C:\ProgramData\Qlik\Sense\Log\Engine\Trace\<hostname>_QixPerformance_Engine.txt and includes fields such as DocId (the app ID), PeakRAM, NetRAM, and ProcessTime (the end-to-end clock time for a request).
The key fields for your use case are:
One important caveat: having Warning level QIX Performance logging enabled produced a small increase in response times of around 1.4% over having logging disabled, while Info level produced a 7.0% increase. For production monitoring, the recommended setting is Warning or Error, not Info, to keep the overhead low.
Q2: What data sources do the Operations Monitor and Reload Monitor use?
A2: The Operations Monitor loads service logs to populate charts covering performance history of hardware utilization, active users, app sessions, results of reload tasks, and errors and warnings. Qlik-poc It reads directly from the log files on disk, not from the Engine API, which is precisely why it scales well and does not put pressure on the engine at all.
The App Metadata Analyzer provides a holistic view of all Qlik Sense apps, including granular detail of an app's data model and its resource utilization. Qlik Help This one does call the Engine, but it does so in a controlled, scheduled way rather than on demand for every app simultaneously.
The key architectural insight here is that the native monitoring apps are all log-based and batch-oriented, not live API calls. That is how they handle hundreds of apps without engine pressure.
Q3: Recommended approach for performance monitoring at scale
A3: Based on what the native monitoring stack does, the recommended pattern for your use case is:
Log-based collection over API polling. Enable QIX Performance Logging at Warning level in the QMC (Engines → [engine] → Logging → QIX Performance log level), then load those log files into your monitoring app via a scheduled reload. This gives you per-app, per-operation metrics without any Engine API calls at runtime.
Incremental QVD layer. Since you are already building a monitoring app with QVDs, structure it so each reload only picks up new log entries since the last run, not the full history. This keeps reload time short even as the log volume grows.
Avoid polling /data/metadata for monitoring. As we established earlier, that endpoint opens an engine session per app and does not scale. For the metrics you described, identifying resource-intensive apps and detecting spikes, the QIX Performance logs give you equivalent or better data without the engine overhead.
For a ready-made reference implementation, the Telemetry Dashboard (available at github.com/eapowertools/qs-telemetry-dashboard) follows exactly this pattern and can serve as a starting point or benchmark for your own monitoring app.
Hope this helps move the architecture forward!
Sources:
https://github.com/eapowertools-archive/qs-telemetry-dashboard/wiki/Logging-Performance
https://adminplaybook.qlik-poc.com/docs/tooling/operations_monitor.html