Business Central performance tuning

Where Business Central performance problems come from, and the AL and configuration patterns that fix them — keys, queries, locking, and async jobs.

Updated 2025-10-24

Business Central is fast out of the box, but custom code, large data volumes, and chatty integrations can all degrade it. The fixes are well-known.

Read the telemetry first. Every tenant emits performance telemetry to a partner-configured Application Insights workspace. Long-running pages, slow API calls, lock timeouts, and inefficient SQL queries are all reported. Diagnose with telemetry before guessing.

SetLoadFields. When you read a record but only need a subset of fields, call SetLoadFields() first. The platform issues a narrower SELECT, dramatically cutting I/O for large tables. The single highest-yield optimisation in many extensions.

Keys and indexes. Tables have keys (the AL term for indexes), and queries are fastest when a key matches the SetRange / SetFilter pattern in code. Custom queries on standard tables often need a custom key declared in a table extension. Watch for MaintainSiftIndex on flow fields — SIFT keys speed up SUMs but slow inserts.

FlowField pitfalls. Pages that display FlowFields recalculate them on every refresh. For high-volume lists, hide or compute on demand rather than on load.

Locking. Posting code locks rows. Long-running custom code that holds locks blocks other users. Patterns: commit between independent units of work; avoid running OnAfterPostXyz subscribers that do slow external calls inside the transaction; move heavy work to job queue entries that run asynchronously.

Job queue. The Job Queue is BC's built-in scheduler. Use it for nightly batch routines, asynchronous integrations, and any code that doesn't need to complete before the user gets a response. Configurable retries, parallelism limits, and isolation.

API performance. API calls obey the same rules as page calls — SetLoadFields, $select query parameter, and $expand instead of N+1 round-trips. Honour the platform's 429 throttling rather than retrying immediately.

Reports. Long reports running interactively block the user. Schedule them via the Job Queue or Report Inbox, where the user gets a notification when the PDF is ready.

Pages. Pages with hundreds of fields, many FactBoxes, or heavy AL OnAfterGetRecord triggers are slow to refresh. Profile with the AL profiler in VS Code.

Database growth. Stale data (orphan attachments, old change-log entries, completed but un-archived job queue entries) inflates storage and slows queries. Schedule cleanup routines.

Test at scale. Performance tests pass against a 1,000-row sandbox and fail against a 1,000,000-row production. Test against representative data volumes before go-live.

Related guides