FileMaker performanceunstored calculationsFileMaker calculation fieldsdatabase indexingFileMaker optimizationrelational database design
Why unstored calculations can slow FileMaker down

Why unstored calculations can slow FileMaker down

Jeroen·

Learn why unstored calculations quietly slow FileMaker down, how to spot them, and when to fix, index, or replace them with a script or API call.

Your FileMaker layout used to feel instant. Now a list view that shows 2,000 records takes several seconds to load, a find that used to be immediate now makes users wait, and nobody on the team can point to a single change that caused it. Nine times out of ten, when we get called in to diagnose a case like this, part of the answer is sitting quietly in the relationship graph or the field definitions: an unstored calculation.

This article explains exactly what an unstored calculation is, why it silently taxes performance as your database grows, and how to find and fix the ones that are actually hurting you — without turning every calculation field into a maintenance headache.

What does "unstored" actually mean in FileMaker?

Every calculation field in FileMaker is either stored or unstored, whether or not you consciously chose that.

  • A stored calculation is computed once, when the record is created or edited, and the result is saved to disk like a normal field. Reading it later is just a lookup — fast, indexable, sortable.
  • An unstored calculation is not saved anywhere. FileMaker recalculates its value on the fly, every single time it needs to display it, sort by it, search it, or use it in another calculation.

FileMaker automatically marks a calculation as unstored when it references anything that isn't guaranteed to be fixed for that record, such as:

  • A field in a related table (through any relationship)
  • Global fields or global variables
  • Functions like Get(CurrentTime), Get(CurrentUser), or Status(CurrentDate)
  • Summary fields
  • Certain uses of ExecuteSQL and other context-dependent functions

This is a deliberate design choice, not a bug: FileMaker can't safely cache a value that depends on data living somewhere else, because that related data can change without touching the current record at all.

Why does this actually slow things down?

Here's the concrete version of the problem, not the abstract one.

Imagine an Invoices layout with a calculation field TotalPaid that sums related Payments records. It's unstored, because it depends on a related table. On a single invoice detail view, that's invisible — FileMaker computes it in a blink.

Now put that same field on a list view of 3,000 invoices, or use it as a sort key, or put it in a find request. FileMaker now has to walk the Payments table and recompute the sum for every single one of those 3,000 invoices, every time the list is drawn, sorted, or searched — not once, but on every refresh, every scroll, every re-sort. That's the moment a report that used to feel instant becomes a 10-second spinner, and it's usually the moment someone calls it "FileMaker being slow" when the real cause is a design decision made two years earlier.

The same pattern shows up in:

  • Portals that show an unstored calculation in every row — each row triggers its own recalculation
  • Conditional formatting based on an unstored field, recalculated on every screen redraw
  • Scripts that loop through found sets and touch an unstored field on each record
  • Sub-summary reports grouped or sorted by an unstored calculation

[[IMAGE:left|invoice list with a slow spinning gear icon over a sum column]]

Can you always just make it stored instead?

No — and this is the trade-off that trips people up. FileMaker won't let you store a calculation that references related fields, globals, or context-dependent functions, because it genuinely can't guarantee the cached value stays correct. If it let you force it, you'd get invoices showing a TotalPaid that's silently wrong after someone edits a payment in another window.

So the real question is never "stored or unstored" in isolation — it's "do I actually need this calculated live, or can I compute it once and keep it in sync deliberately?"

How do you find the unstored calculations that are actually a problem?

Not every unstored calculation is a problem. A field used only on a single detail-view layout, viewed one record at a time, rarely matters. The ones worth fixing are the ones used in list views, portals, sorts, finds, or loops over large found sets.

Step-by-step audit:

  1. Open Manage Database > Fields and look at the storage options for each calculation field (the storage icon or the "Storage Options" dialog tells you if it's unstored).
  2. Cross-reference which of those fields appear on list-view layouts, in portals, in sort scripts, or in find requests.
  3. Check whether any are used inside other calculations — an unstored field referenced by a second calculation makes that one unstored too, even if it looks self-contained.
  4. Time a real-world action (opening the list, sorting the report) before and after temporarily removing the field from the layout, to confirm it's actually the bottleneck and not something else like an unindexed find or a slow network share.
  5. Prioritize fixing the fields used most often, by the most users, on the most frequently opened layouts — not every unstored field in the file.

What are the practical fixes?

1. Replace it with a stored value updated by a script. Instead of a live TotalPaid calculation, store TotalPaid as a plain number field, and update it with an auto-enter script trigger or a scheduled script whenever a related Payment record is created, edited, or deleted. You lose the guarantee of "always perfectly live," but you gain speed, and in most business workflows a value that's correct "as of the last payment change" is exactly what's needed.

2. Use a trigger-based summary instead of a live relationship. For running totals, counts, or rollups, a script triggered OnRecordCommit on the related table that pushes the new total back to the parent record is usually far cheaper than an unstored sum recalculated on every list refresh.

3. Move the calculation out of the list view. If a value is only needed when a user opens a specific record, don't calculate it on the list layout at all — calculate it only on the detail layout, where it's touched once instead of once per visible row.

4. Avoid unstored calculations in sort and find criteria. Sorting or finding on an unstored field forces FileMaker to compute it for the entire found set before it can even begin sorting or filtering. Where possible, sort and find on a stored field that's kept in sync instead.

5. Reconsider global fields and functions like Get(CurrentUser) inside heavily used calculations. These are convenient but automatically make a calculation unstored. If a value only needs to reflect "who created this record," capture it once with an auto-enter calculation at record creation instead of recalculating it live forever.

Is this only a FileMaker-specific quirk, or does it matter in every database?

It's specific in mechanism but universal in principle. Every serious database — SQL Server, Postgres, even a well-built API layer — faces the same trade-off between computing a value on demand (accurate, but expensive at scale) and caching it (fast, but requiring deliberate invalidation). FileMaker just makes the trade-off visible and explicit through the stored/unstored setting, which is actually a gift: it forces you to think about it early, rather than discovering it as a mystery slowdown in production three years later.

This is also why unstored calculations rarely show up alone — they're usually one symptom in a system whose structure grew organically over years without anyone revisiting the original data model. If you're seeing this kind of slowdown, it's worth reading our broader guide on how to improve the performance and structure of a FileMaker solution, which covers the other common culprits alongside this one.

[[IMAGE:right|before and after diagram, live calculation replaced by stored cached value]]

A quick checklist before you touch anything

  • List every calculation field currently marked unstored
  • Flag which ones appear on list views, portals, sorts, or finds
  • Confirm the slowdown by testing with and without the field, not by assumption
  • Decide, per field, whether "live and occasionally slower" or "cached and refreshed by script" fits the business need
  • Build the script trigger or auto-enter logic to keep the stored replacement in sync
  • Re-test the same layout, sort, or find after the change
  • Document why each field was changed, so a future developer doesn't "fix" it back

FAQ

Does making a field stored always make it faster? Usually, yes for reading — but writing gets slightly more expensive, since FileMaker now has to update the stored value whenever a dependency changes. For fields read far more often than they're written (true of almost every rollup or total), this trade is almost always worth it.

Can I index an unstored calculation? No. FileMaker cannot build an index on a field it can't cache, which is exactly why finds and sorts on unstored fields are slow — every find has to compute the value for every record instead of consulting an index.

Will this problem get worse as our database grows? Yes, and that's the trap — an unstored calculation feels fine with 200 records and painfully slow with 50,000, so it's easy to build it in early and only discover the cost once the business has scaled.

Is this something we can fix ourselves, or does it need a developer? Small fixes (spotting an obvious unstored field on a busy list view) are approachable for an in-house developer. Systemic cases — where dozens of calculations, layouts, and scripts all interact — usually benefit from an experienced FileMaker developer doing a structural review, since removing the wrong dependency can quietly break another report.

If your FileMaker solution has grown from a handful of tables into a system with dozens of relationships, calculations, and years of accumulated "quick fixes," it's often worth having someone map where the real performance bottlenecks are before making changes. Loggix regularly does exactly this kind of structural review — sometimes leading to a targeted rebuild of specific modules, sometimes to connecting the system to other tools via API integrations, and sometimes simply to a short consultancy session that gives your team a clear, prioritized list of what to fix first.