Qlik Community

Qlik Design Blog

All about product and Qlik solutions: scripting, data modeling, visual design, extensions, best practices, etc.

Coming your way, the Qlik Data Revolution Virtual Summit. October 27-29. REGISTER


Every time you click, the Qlik engine recalculates everything.




A new selection implies a new situation: Other field values than before are possible; other summations need to be made; the charts and the KPIs get other values than before. The state vectors and the objects are invalidated. Everything needs to be recalculated since this is what the user demands.


Well, there is of course a cache also – so that the Qlik engine doesn’t have to recalculate something which has been calculated before. So it isn’t quite true that everything is recalculated: If a calculation has been made before, the result is simply fetched from the cache. But it is true that nothing is pre-calculated. There is no need for that. Everything can be done in real-time.


The Qlik engine is an on-demand calculation engine.


From a principal point, there are two steps in the recalculation of data: The logical inference in the data model, and the calculations of all objects, including sheet labels and alerts.


The logical inference is done first. The goal is to figure out which field values in the symbol tables are possible and which records in the data tables are possible, given the new selection. There is no number crunching involved - it is a purely logical process. The result is stored in the state vectors.


Think of it as if the selection propagates from one table in the data model to all other tables. Table after table is evaluated and the Qlik engine figures out which values and records are possible, and which are excluded.




When the logical inference is done, the Qlik engine starts to evaluate all exposed objects. List boxes and dimensions in charts must be populated and sorted. All expressions – in charts, in text boxes, in labels, in alerts – must be calculated. Objects that are on other sheets, minimized or hidden, are however not calculated.


The calculations are always aggregations based on the data records that have been marked as possible by the logical inference engine. I.e., the objects do not persist any data on their own.


The calculation phase is usually the phase that takes time – often over 90% of the response time is due to calculations. The calculations are asynchronous and multi-threaded on several levels: First of all, every object is calculated in its own thread. Secondly, in the 64-bit version, many aggregations e.g. Sum() are calculated using several threads, so that a sum in one single object can be calculated quickly using several CPUs.


Finally, when an object has been calculated, it is rendered. Since the calculation is asynchronous and multi-threaded, some objects are rendered long before other objects are ready.


And when an object has been rendered, you can click again. And everything is repeated.




PS. All of the above is of course true for both QlikView and Qlik Sense. Both use the same engine.


If you want to read more about the Qlik engine internals, see

Symbol Tables and Bit-Stuffed Pointers

Colors, States and State vectors

The Calculation Engine


Very clever people making all this happen.

Are variables evaluated before visible sheet objects - as one group?

Is QlikView smart enough to only evaluate variables involved in the visible sheet and object set?

The engine that hands out the multi-threading: is it smart enough to know that SUM(Amount) and sum(Amount) are the same?

All the best, Adam


Q1: Variables are considered part of the data, so, yes, they are evaluated before the sheet objects.

Q2: Variable dependencies is an interesting topic... Basically, since you can use $-expansions that have different values depending on selection - and nested such - to fetch a variable, it is virtually impossible to figure out where a specific variable is used. So, I believe the answer to Q2 is no. But I need to check with some of our developers to be completely sure.

Q3: I believe it is. I know it is smart enough to recognize both that it is the same aggregation and that the scope of the aggregation is the same, when it looks in the cache. So left to check, is only that no other threads have have started to calculate the same aggregation, but not yet entered the result in the cache.



Hi Henric and Adam,

Mike Steedle actually found that equivalent expressions written slightly differently will not be recognized by QV as being the same.

Near the bottom of this post about performance with column references, Mike mentions:

Note the other possible danger of using explicit expression formulas in the final column: writing an explicit formula slightly differently, like changing the case of a function or inserting spaces before or after parentheses, makes performance even worse (about 3x worse, in this example). QlikView doesn’t detect that sum(Sales) and Sum(Sales) mean the same thing within a chart, even though they have the same result.


I would be very surprised if what you claim is correct.

First of all, the CalcTimes as reported in the document properties, sheet properties and memory statistics are not reliable. The code was written before the latest incarnation of the caching was implemented, and also before much of the multi-tasking was implemented, so I wouldn't trust them to be accurate. To make a proper test, you would have to measure the calculation time some other way.

With the current implementation, the response times should not differ between full expressions, label references and column references. But, there may of course be bugs... Soif you have an example where you think that the response times differ, then please send it to me.



Thanks for the information Henric. I will leave commenting on the nature of the tests to Mike.

Can you define current implementation? Do you mean QlikView 11, or a specific version of QlikView 11, like QV11.2SR2?

One thing I have noticed with column references in QV11SR2 and below is that when I use a function like rand() in an expression, then the result appears to cache after a recalculation. So if I create an expression with rand() and then reference that column multiple times using label or column references, the referenced columns will be equal but will not equal the first column:


Also, how would you define unreliable for the CalcTimes? Do you mean just in terms of absolute value? From experience, it would appear at the very least that you can use them to examine relative changes in performance for a single object across different configurations. In this scenario, the fact that it doesn't take into account the multi-tasking capabilities shouldn't matter. If I understand the example we are discussing now, the multi-threaded calculations shouldn't even come into play because you have stated the software should check whether equivalent expressions are being calculated, thus preventing the same expression from being calculated multiple times.

If this CalcTime cannot be relied on, what would you suggest as an alternative?

Thanks for the feedback


EDIT: typos

Creator III
Creator III

CalcTimes as reported in the document properties, sheet properties and memory statistics are not reliable.

How the Data Island will work? Data island is the single threaded process or Multi threaded process?

It would be very helpful for the performance optimization if we are able to track the expression exuection is single threaded or multithreaded