What are the guidelines on storing embedded page (or page list) data in case vs. storing this data as separate instances and using auto-populate?
Some of the main considerations here are as follows:
Is the "related data" of interest outside of the context of the case*?
Are the "related data" types themselves complex types (composed of many other classes of data)?
Are the volumes of the "related data" for a single instance of the case* "high"?
Consider externalizing the embedded data into distinct concrete instances when any of these are true, and even more so when multiple or all are true.
"High volume" is of course subjective, is dependent on many factors, and is informed by your client's Non-Functional Requirements. Where a higher volume of embedded data starts having a noticeable impacting the time taken to open or save the case*, consider reverting to this approach.
Unit Test Cases - built in PegaUnit - can include a "Response Time" assertion on a Data Page that uses the Lookup Data Source to open your case*. Create Unit Test Cases like this - at the start of your project - with a volume of "related data" that is realistic and representative of Production. If these PegaUnit tests start failing because the response time exceeds the required threshold, you have crossed the line and should transition to managing the related data as distinct concrete instances.
That you can anticipate part of your case* data model that may be susceptible to this issue may, in itself, be a good enough reason to take this approach from the start.
* Whilst the above examples refer to a "case" as a typical scenario for this; this approach is equally applicable to Data instances that have embedded data that meets some/all of the criteria listed above.