Performance and Scalability Tuning
Push work to the database
Retrieve only what is needed: constrain with XPath, sort inside the retrieve so the database orders rows, and use range for pagination. XPath contains(), not equal and functions applied to attributes prevent index use. Retrieve by association translates into a join and is usually faster than the equivalent XPath over an association. Calculated attributes cannot appear in XPath at all.
Batches and commits
Commits are expensive: commit once per list rather than per iteration, use commit without events where handlers are unnecessary, and process large volumes in scheduled events with a limited batch so the runtime is not blocked. A retrieve inside a loop is the classic N+1 problem - retrieve the full set first or use one constrained query.
Schema and runtime
Index every attribute used in filters, sorts and unique constraints. Wide reference sets and deep inheritance add joins, so measure before abstracting. For scale, tune Java heap and run multiple runtime instances where the platform supports it; keep no state in the runtime that assumes a single instance.
Worked example
An overview loads 5,000 orders and filters them in a microflow loop. Fix: move the filter into the page data source XPath, sort in the retrieve, paginate at 20 rows and index Order/Status. Reasoning: the database returns 20 rows instead of 5,000 over the network and no per-page microflow loop runs.
Traps
Sorting with a List operation after retrieving everything; measuring only on a small development dataset; storing large content as string attributes; using exceptions for ordinary flow control.