SAP Knowledge Base Article - Public

3071139 - SuccessFactors Story Reports: Memory Limits and Design Guidelines

Symptom

Users may experience the following issues when working with complex Story reports:

  • Lag or slowness in the Story Designer interface

  • Delays when adding widgets or pages

  • Exporting reports takes longer than 3 minutes

  • Charts and tables render slowly

  • Filters cause unresponsiveness or freezing

  • Browser crashes with “Aw Snap” error in Chrome due to Out of Memory (OOM)

 

Image/data in this KBA is from SAP internal systems, sample data, or demo systems. Any resemblance to real data is purely coincidental.

Environment

  • SAP SuccessFactors HCM Suite
    • Analytics & Reporting (Ad Hoc, YouCalc, ORD)
      • Story Reports

Reproducing the Issue

  1. Open or edit the affected Report Story

  2. Attempt to run or export the report

  3. Observe slow performance or browser crash

  4. Alternatively, navigate to Report Center and run/export the Story

  5. Notice delays or memory-related errors during execution

Cause

Performance degradation, Out of Memory (OOM) and browser crashes stem from:

  • Excessive/improper usage of joins and autojoins in query design

  • Large datasets in tables or charts (e.g., data extraction use cases, designing 'List' reports with Global data)

  • Nested calculated columns and linked dimensions

  • Overuse of widgets, especially data-heavy ones like tree maps or large tables

  • Filters applied inefficiently or with too many members

  • In rare scenarios, Browser memory limit breach (~4 GB) due to the memory consumed while rendering the data in Story

Resolution

Refer the Implementation Design Principles to start your journey with Story reports.
  

Design Considerations

1. Cartesian Join

Description

ExamplesHow to analyze?Recommendation

Incorrectly choosing the combination of objects can result in Cartesian joins, leading to an explosion of records being fetched for a single user. This creates numerous combinations of data that must be held in memory, causing OOM exceptions.

  • Choosing a Driving object which has multiple records for each user
    • Employee Timesheet
    • Compensation Information 
  • Using Driving object with Time filter 'Show All'
  • Change Reporting
    • Fetching all data from both the original and duplicated object to perform change reporting for an older date range 
  • Identify the number of records fetched for a single user by filtering on a single user at driving object level.
  • Verify if the Driving object is a good choice
    • Any object that would fetch single record for User
    • Time filter is set to 'Current Date' 
  • Look for joins, such as User data to Timesheet or All Templates (PM/GM) and so on, which could fetch 10s of records for each user.
  • Verify if Inner Join works
  • See if offline scheduling works
  • Driving object to fetch a single record of User 
  • Time filter to be set as a specific date, and avoid 'Show All', especially for Driving object.

2. Multiple Alias

Description

ExamplesHow to analyze?Recommendation

Using the same object multiple times by duplicating it is a common scenario, to transpose data. This can lead to excessive memory consumption as multiple instances of the same object occupy the memory.

  • This is commonly seen in reports where conversion of multiple rows to a single row is required
  • Mostly used for fetching 
    • All Pay components in a single row
    • All Dependents in a single row 
  • Verify the query design to see if any object is duplicated multiple times. 
    • If duplicated only once, it could be used for 'Change Reporting'.
    • Any duplication, greater than one, would be for Transpose.

3. Nested/Complex Calculated Columns

Description

ExamplesHow to analyze?Recommendation

Using calculated columns within other calculated columns and employing multiple If-Else blocks in a single calculated column can increase the complexity and memory usage. Each layer of calculation consumes additional memory, exacerbating the OOM issue.

Example:

If (PayComp = '123', A, 
    If (PayComp = '234', B,
        If (PayComp = '345', C,
            If (PayComp = '456', D,
                If (PayComp = '567', E,
                    If (PayComp = '678', F, X))))))

  • Calculated column A which has 5 IF() conditions. Now we create another calculated column B which has 10 IF(A) conditions using the calculated column A. When the final query is generated, it will have 50 IF() conditions (A x B) and hence become performance heavy.
  • Check for calculated column complexity
  • Look for depth of IF-ELSE conditions
  • Identify the calculated columns, that are used within other calculated columns 
  • See if offline scheduling works
  • Simplify the conditions used in the Calculated columns. Using functions rather
  • Avoid nested calculated calculations as much as possible. 

4. Filters at Story Level Rather than Query Level

Description

ExamplesHow to analyze?Recommendation

Adding too many filters at the Story level means retrieving and rendering a vast amount of data before applying the filters. This approach requires the entire dataset to be held in memory, resulting in potential OOM exceptions.

  • Fetching Global data of large organizations, without selectively restricting, based on country/business unit/location, at query level
  • Fetching data without Time filters and applying date range at Story level
  • Verify if there is risk of Parallel execution
  • See if the filters used at Story level can be moved to Query level
  • Ensure that all the reports have 'Apply Selection for Filters' setting ON for all Reports. 
  • Move filters to Query level
  • Divide the Report into multiple copies, based on Location, Business Unit etc

5. Filters on Query Level rather than Table Level

Description

ExamplesHow to analyze?Recommendation

Adding filter on the table rather than the query (especially for driving table) can reduce the SQL statement sent to the server, preventing OOM. This is due to the table filters being considered first, only after query filters are applied.

  • Fetching Global data of large organizations, with filters based on country/business unit/location, at query level
  • Check if there are too many filters at Query level
  •  Look for filtering options on Driving objects
  • For filters at Query level, identify the ones which can be moved to Object level. 
    • Country/Location type of fields will reduce the amount of data fetched from DB, when filtered at Object level

6. Time trend Analysis (usage of extensive Date Range)

Description

ExamplesHow to analyze?Recommendation

Having a large date range applied on table/s can cause large amount of data being sent to the server.

  • Using Time Filter 'Show All' on most of the objects used in the Query
  • Change Reporting
    • Fetching all data from both the original and duplicated object to perform change reporting for an older date range 
  • Fetch the data for Current Date and see if the report works
    • If it does, extend the time frame to an year and see if it works
  • See if offline scheduling works
  • Fetching yearly data can be tested and reports be divided based on years
  • Using Charts rather than List widgets might work for Time Trend Analysis

7. Hierarchy Reports 

Description

ExamplesHow to analyze?Recommendation

Avoid trying to create hierarchies in Story Reports. Doing so may cause issues not only for the given report, but also if other reports are run in parallel may run into errors. 

  • There is a Standard template, designed to show how simple supervisor reports can be created. Customers increase the levels in it.
  • Reduce the levels and see if the report works
  • Try offline schedule export
  • Try not go past 5 levels for large organizations
  • Make sure to use Time Filter to a specific date (Show All will certainly fail)

8. Story level calculations

Description

ExamplesHow to analyze?Recommendation

Limit the use of calculations at the Story widget level.

Below examples intends to aggregation of specific pay component.

  • Users are creating multiple calculated columns at the widget level to aggregate the results, instead of creating using a calculation at the query level. 
  • Historically, changing this design of the query can reduce the memory consumption significantly (when there is large amount of data).
Create a calculated column, of the similar design, and use it in the widget.
Verify if the report works fine. 
Provide similar suggestion to move all Story calculations, possible to be moved, to Query level.

Additional design considerations:

Look for these aspects to understand the heaviness of the Story:

  • Too many pages
  • Too many fields in a data source (i.e.in particular fields which are not used in the story)
  • Too many data sources, used in a single Story page
  • Usage of multiple data sources and linking via Link Dimensions to bypass 120 column limits
  • Split query into multiple data sources and apply each to separate page 
  • Split report into multiple parts by applying a filter on the driving table (per region?)  

Data Considerations

Identifying the amount of data

Understanding the number of Records fetched for a single User, at query level

  • At Query level, add an object level filter on a single User 
  • Delete all Query level filters (let the object level filters remain as-is)
  • Preview the Query
    • This would provide the information on number of records being fetched for a single user

Similar testing can be performed at Position, Department etc., level based on the query design

Understanding the number of records, using a Numeric Point widget

  • Add a Numeric Point Widget on a Page
  • Fetch 'Count' of the data source
  • This will return the number of records which will be fetched

Finding the Join which is leading to high number of records being fetched

  • From R to L, remove each object and Preview Query
  • This will provide the information on number of records being fetched in each iteration
    • The object, which when removed will reduce the number of records vastly is the one causing cartesian joins
Provide Best Practices with Customer

  • Look for design changes by adding restrictive filters (Any query fetching over 1M cells of data is non-performant)
    • Such as Country, Location, Business Unit etc.
  • Try to visualize the date, using various chart types, rather than using 'List Widgets' 
  • Watch out for in-app warning messages that display the amount of records being fetched (for object where one to many relation is defined)
  •  Refer the Performance Analysis report in the Story designer page
  • Query Limits: 1 million cells/120 columns/30 tables/30 joins (including auto-joins)
  • Prevent users from running massive reports at the same time
  • If report cannot be run by any user, you can provide "Unconditional access" permission to admins. This will skip RBP complexity and most likely make the report usable. However consider that all data will be visible in the report. KBA: 3453290

By addressing these design patterns and optimizing both the design and data handling processes, you can significantly reduce the occurrence of OOM exceptions and improve the performance of your SuccessFactors Story Reports.

See Also

Implementation Design Principles 

Keywords

story, slowness, slow, performance, successfactors, report, center, out of memory, oom, aw snap, guidelines , KBA , LOD-SF-ANA-SAC , Stories in People Analytics , LOD-SF-ANA-SAC-QDS , Query Designer - Filter, Calculated Column, Params , LOD-SF-ANA-SAC-SDS , Story Designer - Story & Formatting , Problem

Product

SAP SuccessFactors HCM Suite 2511 ; SAP SuccessFactors Platform 2511

Attachments

Pasted image.png
Pasted image.png
Multiple Alias.png