Every list in tw.local is serialised into the instance's execution context (a BLOB per instance / task) and, for coaches, sent to the browser with the page. Thousands of rows mean megabytes per task and slow coaches. The practical limits: execution contexts above a few MB slow every step (and can hit the database's BLOB / transaction limits); coach payloads above ~1 MB are felt by users. The pattern:
- Keep only keys and the current page in the process - the process holds the query criteria and the selected ids; the data lives in the system of record.
- Page on the server - a service flow takes (criteria, offset, pageSize, sort) and returns one page plus the total; SQL with OFFSET … FETCH FIRST n ROWS ONLY (Db2 / Oracle 12c+), LIMIT / OFFSET (PostgreSQL), or the REST API's paging.
- Page in the coach - the UI Toolkit table shows a page; a Service Call fetches the next page on the table's paging event; sorting and filtering also go to the server when the set is large.
// service flow "Search orders page" - inputs criteria (OrderCriteria), offset (Integer), size (Integer); outputs rows (list of OrderRow), total (Integer)
tw.local.sql = "select order_no as \"number\", customer as \"customer\", total as \"total\" from orders where status = ? order by created desc offset ? rows fetch first ? rows only";
// SQL Execute Statement with parameters status / offset / size, returnType OrderRow; second statement: select count(*) ... -> total
// coach: Table "Orders" (page size 25, "server-side paging" style) - On page changed (pageIndex):
${SearchPage}.execute({ criteria: ${Criteria}.getData(), offset: pageIndex * 25, size: 25 });
// SearchPage > On result: ${Orders}.setData(result.rows); ${Pager}.setText("Page " + (pageIndex+1) + " of " + Math.ceil(result.total / 25));Also: shared business objects reduce copying between steps but not the browser payload; Output Text instead of input controls halves the rendering cost of read-only tables; never map a big list into a BPD variable "for later" - re-query when needed; and clean instance data at the end of the process (set the list to empty in the last step) so that the execution context of finished instances stays small until the housekeeping deletes them.
References