Large Lists And Performance

Some screens in your application feel instant. Others take a long time to appear, and a few fail outright with an error message. This chapter explains, in plain terms, what makes a list expensive, which of those costs you control, and a practical order in which to attack them when a screen becomes unusable.

Nothing here requires you to change how your application is configured. Every step of the playbook but the last is something you can do yourself, from the screen you are already looking at; the last one is a request to hand to your administrator.

What This Is

A list screen does not merely "show you records". Every time it loads, it goes and fetches a batch of records from storage, works out what each one should look like, and builds the page. That work is real, it takes time, and there is a limit to how much of it can happen before the application gives up.

The important consequence is that a screen is not fast or slow in itself. It is fast or slow for the amount of work you asked it to do. The same screen that appears instantly at 20 rows per page can fail completely at 500 — with no change to the configuration, no change to your permissions, and no warning in between.

Why It Matters

Most "the system is slow" reports turn out to be one of a small number of self-inflicted settings that the person reporting the problem chose themselves, usually for a good reason at the time:

  • they raised the rows per page to see more at once,
  • they added a running total that recalculates over the whole data set,
  • they grouped a large result so they could compare categories,
  • or they did all three on a record type that carries a lot of linked information.

Each of those is a legitimate thing to want. But each has a cost, the costs stack, and the application does not tell you in advance which combination is going to be too much. Knowing the shape of the cost lets you get the answer you need without waiting five minutes for it — or without failing to get it at all.

How The Work Adds Up

The Two Numbers That Matter

The cost of loading a list is roughly:

how many records you asked for at once × how much each record has to carry

Both halves are important, and people usually only think about the first one.

How many records you asked for is your rows-per-page setting. This is the lever with the most immediate effect, because it is a straight multiplier. Going from 20 rows to 500 rows asks the application to do twenty-five times as much per-record work in a single request.

How much each record has to carry is a property of the record type, not of the screen. A "Country" record carries almost nothing. A "Purchase order" record that is linked to a supplier, a warehouse, a buyer, a project, a cost center, an approval, and a list of order lines carries a great deal. Loading one hundred of the second kind is a completely different task from loading one hundred of the first, even though both screens look like a table with rows in it.

Example Your colleague in the Countries administration screen sets the page size to 500 and it loads in under a second. You do the same on the Purchase orders screen and it never finishes. Neither of you did anything wrong — you asked for the same number of rows, but not the same amount of work.

Why Hiding Columns Does Not Make A Screen Light

This is the single most surprising thing about list performance, and it is worth understanding properly because it saves a lot of wasted effort.

When a list loads a page of records, it prepares each record's linked information — the related records it points at, the counts it displays, the connected items — for every field on the record that you are allowed to see, not only for the columns currently shown on screen.

So removing columns from the view makes the table narrower, easier to read, and quicker to render in your browser. It does not meaningfully reduce the work done to fetch the page.

Example A Projects screen has 40 available columns. You open the column picker and cut it down to five: project name, client, status, owner, deadline. The table is far more readable. It is not noticeably faster to load, because the client, owner and every other linked field were prepared regardless.

The practical takeaway: if a screen is slow, reducing the page size will help; reducing the columns will not. Trim columns for readability, not for speed.

There is one exception worth knowing: exports are limited to the columns you have on screen, so the column set genuinely does control the size and cost of an export file. That is covered under Action Buttons And Exporting.

Calculations Over All Matching Records

This is the biggest cost that is entirely under your control, and the one most likely to turn a working screen into a failing one.

When you add a calculation — a sum, an average, a count — the strip above the list shows, on a table or cards layout, two figures for it, side by side:

Word on the chipWhat it counts
DisplayedOnly the records on the page you are currently looking at
AllEvery record that matches your current filters, across all pages

The "All" figure is what makes it expensive. To produce it, the application makes a complete pass over the entire filtered result set — not the page, the whole thing. And it does that pass again, from scratch, every single time anything on the screen changes: every filter you add or remove, every column you sort by, every page you turn to, every press of the refresh button.

You cannot ask for only the "Displayed" figure on a normal table. Both numbers are produced together. The lever you have is simpler: remove the calculation while you are working, and add it back when you actually need the total.

Example You are reconciling 6,000 invoices. You add "Sum: Amount" so you can see the total value. From that moment on, every filter change, every sort and every page turn quietly re-totals all 6,000 invoices before the screen can redraw. Twenty clicks of exploration means twenty full passes.

The efficient way round: do your filtering and sorting first, with no calculation active. When you have narrowed the list to what you actually care about, add the sum, read the "All" figure, and remove it again with the ✕ on its chip.

Grouping multiplies this further. When grouping is active, the per-group figures shown in each group heading are worked out separately, group by group. Twenty groups with two calculations is a different order of work from two calculations on a flat list.

Adding, removing and reading calculations is covered fully in Columns, Grouping, Merging And Calculations.

Grouping And Merging

Grouping (keeping every record but sorting them under collapsible headings) and merging (collapsing records into one row per distinct value) are both extra work laid on top of the fetch. On a small result set neither is noticeable. On a large one, combined with calculations, they are.

Two practical notes:

  • Grouping applies to the records on the current page, so people often raise the page size to "see the whole grouping" — which stacks the two most expensive settings at once.
  • Group headings are always expanded when the screen redraws. Collapsing them helps you read; it does not reduce the work already done, and the collapse is forgotten on the next refresh.

If you are not actively using them, take the grouping and merging chips off while you browse.

Boards And Calendars

The board layout is a special case worth knowing about. Instead of one page of rows it loads a batch of cards for every column at once, and it works out the record count shown on each column separately. That is what can make a board feel heavy on a record type where a table of the same data feels fine. A board normally carries no rows-per-page control either, so the usual first lever is not available there — filtering is.

Calendars fetch whatever falls inside the visible date range, so a month view over a busy calendar is a bigger request than a day view.

On both of these layouts a calculation shows only the "All" figure — the expensive one — so the advice to take calculations off while you work applies with extra force there.

Layout specifics are covered in Boards and Calendars.

Why The Screen Looks Like It Arrived Before The Data Does

A list screen paints in two stages. First the page frame appears with a pulsing gray placeholder where the table will be. Then a second request goes off to fetch the actual rows, and the real table replaces the placeholder when it comes back.

This is why a heavy screen "looks loaded" but sits there shimmering. The page did arrive — it is the data request that is still running. If a screen contains several lists (a dashboard, or a record detail with related lists), each fires its own request, so they fill in at different times and a single slow one can hold up your sense that the page is finished.

What Failure Looks Like

There is no graceful degradation. A list request either completes or it does not.

When it does not — because it took too long or asked for too much — this is what you see:

  1. The pulsing placeholder never turns into a table.
  2. The application's general error dialog appears on top of the page. Among other things it suggests that the request may have timed out and that selecting fewer data items at once might help.
  3. Behind the dialog there is no partial list. You do not get "the first 100 rows we managed" — you get nothing.

That suggestion is not a generic apology. For this particular failure it is correct advice and is worth acting on: ask for less.

The same dialog appears for every kind of failed request, so seeing it does not by itself prove you hit a size limit. If the screen was small and simple, the cause is probably something else. The dialog itself, and the other reasons it turns up, are covered in When Something Goes Wrong.

Canceling A Request You Regret

If you realize mid-wait that you have asked for far too much, pressing Esc cancels the request in flight rather than waiting for it to fail on its own.

Be aware that canceling produces the same error dialog — the application does not distinguish between a request that failed and one you stopped yourself. Dismiss it, then lower the page size before trying again.

The Playbook

Work through these in order. The earlier steps are cheaper and more likely to be the actual problem.

1. Lower The Rows Per Page

On most screens the page-size control sits in the footer of the list, on the left, next to the pagination. It is the button showing two numbers — the current page size and the total number of records matching your filters — such as 20 / 4312. Click it and a list of sizes opens upward.

The available sizes are fixed across the whole platform and cannot be changed:

10, 20, 30, 50, 75, 100, 250, 500

Two things to know about that list:

  • An "All" entry appears only on smaller lists. When the total number of matching records is below 500, the menu offers an extra entry at the bottom reading "All" followed by the total, which sets the page size to exactly that number. Above 500 matching records that entry is not there at all, and 500 is the largest page you can request. There is no way to display more than 500 records on one page.
  • The starting size is set for your application (commonly 20), and a saved view can carry its own size. So different screens may open at different page sizes for reasons that have nothing to do with you.

If a screen fails, halve the page size and try again. If 500 fails, try 100. If 100 fails, try 30. The point at which it starts working tells you a lot about how heavy that record type is, and it is a useful number to pass on to your administrator.

Pagination and page sizes in general are covered in List Screens.

2. Narrow With Filters Before Widening The Page

Filters reduce the number of matching records, which reduces every cost on the page at once — the fetch, the calculations, the grouping and the export. They are strictly better than paging through a large result.

The instinct to "show everything so I can find it" is the wrong way round. Filter first to the set you care about, and only then raise the page size if you still need to.

Example Rather than setting 500 rows per page on 4,000 open tickets and scrolling, filter to Assigned to = me and Status = In progress. Forty rows come back, the page is instant, and the answer is easier to read.

Note that the "Find on page..." box in the filters strip is not a filter in this sense. It hides rows that are already loaded in your browser; it does not reduce what the server fetched, so it never makes a screen faster. Real filters are covered in Filtering Your Data.

3. Turn Off All-Matching Calculations While You Work

Remove the calculation chips with their ✕ while you are exploring, filtering and sorting. Add them back once the result set is the one you want.

If you have several ad-hoc calculations, groupings and merges layered on and want a clean slate, the quickest reset is to switch to another saved view and back — switching views discards ad-hoc arrangements. See Saved Views And Queries.

4. Hide Grouping And Merging When You Do Not Need Them

Same principle, same control: the chips in the active row of the filters strip each have a ✕. Grouping and merging are display conveniences; they are not free, and their cost rises sharply in combination with calculations and a large page size.

5. Use Export Instead Of A Giant Page

If what you actually want is "all of it", a spreadsheet is the right tool and the screen is the wrong one. Exports are built to survive large volumes in a way that screens are not — see Exports Behave Better Than Screens below.

Trying to render 4,000 rows in the browser so you can read them is both slower and less useful than exporting 4,000 rows and opening them in a spreadsheet.

6. Ask For The Screen To Be Split

If a screen is genuinely unusable at any page size, the problem is not your settings — the screen is being asked to serve too many purposes at once. That is fixable, but only by whoever configured it.

See What To Ask Your Administrator For for how these requests work generally, and the section below for how to phrase this particular one.

Exports Behave Better Than Screens

Exporting the whole result set — the "Export all to XLSX" entry in the menu at the bottom right of the list — is not the same mechanism as drawing a page, and it has different limits. (The companion entry that exports only the current page is a plain, immediate download of what you can already see, so it carries none of the advantages below.)

  • It runs in the background. "Export all" hands the work off and returns immediately with a message telling you the file will download when it is ready and asking you to keep the tab open. You can keep working while it builds. The screen you were on is not blocked.
  • It works through the records a batch at a time and releases each batch as it goes, instead of holding the whole result at once. That is part of why an export can handle a volume that would fail as a page.
  • It stops early on purpose rather than failing. If a very large export approaches its time or memory ceiling, it deliberately stops adding rows, finishes writing the file properly, and hands you a usable spreadsheet containing everything it managed to collect.

Exports, the Jobs tray they arrive in, and what the file contains are covered in Action Buttons And Exporting.

What A Truncated Export Looks Like, And What To Do

When an export was cut short, the finished job tells you so with a message strip in the corner of the screen. It says that the export was stopped early — to avoid exhausting memory, or to avoid exceeding the time limit — states how many rows the file actually contains, and advises you to narrow the view's filter to export the rest.

Two things make this message miss its mark, so be deliberate about it:

  • The message is a temporary strip. It fades after a few seconds and there is no history of it. If you were looking away when the export finished, you will never see it. The finished job stays in the Jobs tray, but the tray shows only that the file is ready — not that it was cut short.
  • The file itself looks completely normal. There is no warning row inside the spreadsheet, no gap, no marker. It ends where the export stopped. A truncated export of 12,400 rows is indistinguishable from a complete export of 12,400 rows if you only look at the file.

The reliable check is to compare counts. Before you export, note the total shown on the page-size button at the bottom of the list — the second number, for example 20 / 46312. After the export downloads, check how many data rows the spreadsheet contains. If they do not match, your export is partial.

What to do with a truncated export: do not re-run the same export hoping for a better result — it will stop at roughly the same place. Split it instead, using a filter that cleanly divides the data with no overlap and no gap, and export each slice.

Example An export of 46,000 delivery records comes back with 12,400 rows and the stopped-early message. Rather than retrying, you filter by delivery month and export each month separately: twelve files of roughly 4,000 rows each, all complete. Any filter that partitions the data works — a status, a region, a first letter of the name — as long as the slices do not overlap and together cover everything.

Trimming the column set before exporting also helps, because exports only contain the columns currently displayed. Fewer columns means smaller rows and more of them fit inside the ceiling.

Bulk Actions On Very Many Records

Running an action over a selection of records is subject to the same arithmetic as loading a page, with one extra wrinkle: the records are processed one after another inside a single request. There is no progress bar counting through them and no summary at the end — just the thin progress indicator at the top of the window, and then whatever messages the action produces.

So a selection that is too large fails the same way a page that is too large fails: the request times out and you get the same error dialog. Its advice to select fewer items at once is aimed squarely at this case.

Do bulk work in batches. Select a screenful, run the action, let it finish, then move on. If you are not sure what size is safe, start with 20–30 and increase only if that is comfortable.

A few behaviors that matter when you are batching:

  • Your selection only ever covers the rows currently on screen. There is no "select all matching records" anywhere. Anything that re-renders the list — changing page, sorting, filtering, or the refresh that follows an action — clears the selection silently.
  • A bulk delete is all-or-nothing. If one record in the batch cannot be deleted, none of them are, and you get a single message. Smaller batches make it much easier to find out which record was the problem.
  • Bulk quick-edits are not all-or-nothing. Some records can succeed while others fail, and the only evidence is the stack of messages in the corner — which fades. With a large batch you can easily miss a failure. Another reason to keep batches small enough to check.
  • Running an action with nothing selected applies it to everything matching your filters, not to nothing. Confirm your filters before using an action from the menu at the bottom of the list.

Selection mechanics, which layouts support checkboxes, and what feedback you get are covered in Selecting Records And Bulk Actions.

Worked Example: Making A 40-Column, 4,000-Row Screen Usable

The Purchase orders screen at a distribution company. Forty available columns. Around 4,000 orders in the system. Each order is linked to a supplier, a warehouse, a buyer, a project and a cost center, and shows a count of its order lines. Someone has saved a shared view with the page size set to 250 and three running totals: total value, average value, and a count of distinct suppliers.

The symptom. Opening the screen shows the pulsing placeholder for a long time. Sometimes it resolves after a minute; more often the error dialog appears and there is no list at all. Adding a filter — the obvious thing to try — makes it worse, because it triggers another full load and another full recalculation before anything can be shown.

What is actually happening. Four costs are stacked:

  1. 250 rows per page of a record type that carries five linked records each.
  2. Three calculations, each producing an "All" figure over the whole 4,000-record set.
  3. Every one of those recalculates from scratch on every interaction, including the filter you were trying to apply to make things better.
  4. Forty columns — which makes the table hard to read, though it is not the reason it is slow.

The fix, in order.

  1. Drop the page size to 20. The screen now loads, slowly but reliably. This alone is often enough to get from "fails" to "works".
  2. Remove all three calculation chips with their ✕. The screen becomes responsive: filters, sorting and paging now feel normal, because nothing is re-totaling 4,000 records behind each click.
  3. Filter down to the real question. In practice nobody needs all 4,000 orders — they need Status = Awaiting approval and Warehouse = Central, which is 180 records.
  4. Add the calculations back. With 180 matching records the "All" figures come back quickly and are now the totals the person actually wanted, rather than a company-wide number nobody reads.
  5. Trim the columns for readability — eight instead of forty. This does not change the speed, but it makes the screen usable at a glance and, usefully, makes any export from it much smaller.
  6. Save it as your own view so you do not rebuild it every morning. See Saved Views And Queries.
  7. For the monthly reconciliation, where all 4,000 really are needed, do not raise the page size. Clear the filters, keep the trimmed column set, and use "Export all to XLSX" from the menu at the bottom right. Then check that the exported row count matches the total on the page-size button.

What to hand to the administrator afterwards. The daily-work version of this screen would be better as a dedicated screen — pre-filtered to awaiting-approval orders for your warehouse, with eight columns and a page size of 20 — leaving the wide 40-column view as a separate screen for the occasional deep dive. That is a request worth making, and one an administrator can usually act on without much work.

Tips And Gotchas

  • The refresh button is not free. The circular-arrows button re-runs the whole query with every current setting, including all calculations. On a heavy screen it costs exactly as much as the original load, and it can fail the same way. It is still the right control to use — lists never update themselves — just do not treat it as a lightweight nudge.
  • A large page is unpleasant even when it works. Column headers do not stay pinned when you scroll, so at 250 or 500 rows you lose track of which column you are reading. Long text values are not truncated in cells either, so a single verbose field can make rows very tall.
  • A very large list at a small page size makes the page-number list unwieldy. The dropdown that lets you jump to a page contains one entry for every page. Fifty thousand records at 10 per page means five thousand entries in that menu, rebuilt on every redraw. Prefer filtering over deep paging.
  • On a narrow window and inside pop-up windows, the numbered page links disappear and only the previous/next arrows remain. You can still jump straight to a page with the page selector next to them, but stepping through a long list in a pop-up is slow going — another reason to filter rather than page.
  • Screens driven by a specially built query behave differently. On these, the page-size control is inert and shows only a count, and the buttons for filters, grouping, merging and calculations are absent entirely. If a screen offers you none of those choices, this is why. What you may get instead is a set of named parameters your administrator built into the screen; beyond those, the only lever left is to ask for the screen itself to be narrowed.
  • Several lists on one page compete with each other. A dashboard or a record detail with many related lists fires one request per list. One heavy list makes the whole page feel unfinished.
  • A screen that was fine last quarter can stop being fine. Nothing was changed — the data grew past the point where your saved page size still works. If a screen you have used for months starts failing, check the total row count on the page-size button before assuming something broke.
  • Your colleague's experience may genuinely differ from yours. Permissions decide which fields are prepared for each record, so the same screen can be measurably heavier for someone who can see more fields than you. See Why Your Screen Differs.

What To Ask Your Administrator For

Two kinds of request are worth making. Both are far easier to act on when you bring numbers.

Report A Screen That Fails

Include all of these, because together they let an administrator reproduce the failure without guessing:

Tell themExample
Which screen, by the name in the navigation"Purchase orders"
Which saved view was selected"All open orders (shared)"
Which filters were active"Status = Awaiting approval, nothing else"
The total row count shown on the page-size button"the button read 250 / 4312"
The page size you had chosen"250"
Which calculations, groupings or merges were active"Sum: Value, Average: Value, grouped by Supplier"
Roughly how long before it failed"about 90 seconds, then the error dialog"
Whether a smaller page size works"20 works, 100 fails about half the time"

That last line is the most valuable one. "It fails at 100 but works at 20" tells an administrator far more than "it is slow".

Ask For The Screen To Be Split

If a screen is unusable at any page size, or if you find yourself applying the same three filters every morning, ask for it to be split into purpose-built screens. A request phrased around what you do, rather than how it should be built, is the one most likely to be granted:

"The Purchase orders screen is too heavy to open. Nearly all of my work is on orders awaiting approval for the Central warehouse — that is about 180 records and eight columns: order number, supplier, value, requested date, buyer, project, status, age. Could we have a separate screen that opens already filtered to that, with just those columns and a small page size? Please keep the current full screen as it is, because I use it once a month for the reconciliation."

Useful things to include in that kind of ask:

  • The filter that defines your daily working set — "only open ones", "only mine", "only this region", "only the last 90 days".
  • The columns you genuinely read, named. Eight named columns is a much more actionable request than "fewer columns".
  • Whether you need totals, and over what. Be aware that a total built into the screen still costs the same to produce on every interaction, and depending on how it is set up you may not be able to take it off. If you only need the number once a day, ask whether it could sit on a dashboard tile instead of on the list.
  • What you still need the wide screen for, so it does not get taken away.
  • Anything you currently export by hand every week, because a recurring export need is often better solved another way entirely.

You cannot change the page-size choices themselves — those are fixed across the platform — but the size a screen opens at, the filters it starts with, the columns it shows and whether it carries calculations are all things an administrator can set for you.