Back to Blog

Power Apps Performance Issues - Common Problems and Fixes

April 13, 202611 min readMichael Ridland

Your Power App is slow. Users are complaining. Screens take five seconds to load. Galleries stutter when scrolling. Forms hang when saving. The app that worked perfectly in testing with 50 records is barely functional with 5,000.

We've been called in to fix slow Power Apps more times than we can count. The problems are almost always the same, and most of them are fixable without rebuilding from scratch.

Here are the most common performance issues and how to solve them.

Problem 1 - Delegation Failures

This is the number one performance killer in Power Apps, and the most misunderstood.

What Delegation Is

When you filter or sort data in a Power Apps gallery, the platform tries to push that work to the data source (SharePoint, Dataverse, SQL Server). The data source does the filtering and returns only the matching records. This is delegation - delegating the work to the server.

When Power Apps can't delegate a function to the data source, it pulls the first 500 records (or 2,000 if you've changed the limit) into the app and filters locally. If you have 10,000 records and your filter isn't delegable, you're searching through 500 records and ignoring the other 9,500.

How to Spot It

The yellow triangle warning in Power Apps Studio means "this expression isn't delegable." Don't ignore these warnings. They're not suggestions - they're telling you the app will silently return incomplete results.

Common Non-Delegable Functions

These functions will NOT delegate to SharePoint or many other data sources:

  • Search() - Use Filter() with StartsWith() instead
  • Last(), FirstN(), LastN() when used as filters
  • Len(), Left(), Right(), Mid() - string functions in filter expressions
  • IsBlank() in some data source contexts
  • Or() conditions with mixed delegable and non-delegable parts
  • Nested Filter() in certain combinations

The Fixes

Fix 1 - Use delegable alternatives:

Instead of:

// Non-delegable - searches all text columns
Search(Customers, SearchBox.Text, "Name", "Email", "Phone")

Use:

// Delegable - filters with StartsWith on specific column
Filter(Customers, StartsWith(Name, SearchBox.Text))

StartsWith delegates to most data sources. Search does not.

Fix 2 - Increase the delegation limit:

Go to Settings > General > Data row limit for non-delegable queries. Increase from 500 to 2,000. This isn't a real fix - it just delays the problem - but it helps for datasets under 2,000 records.

Fix 3 - Use Dataverse instead of SharePoint:

Dataverse supports more delegable functions than SharePoint. If your data is growing beyond a few thousand records and you need complex filtering, moving to Dataverse is often the right answer.

Fix 4 - Create views or indexed columns:

In SharePoint, create indexed columns on fields you filter by. In Dataverse, create views that pre-filter data. In SQL Server, add indexes on commonly queried columns.

Fix 5 - Pre-filter with Power Automate:

For complex queries that can't be delegated, use a Power Automate flow that runs the query server-side and returns results to the app. More work to set up but solves the delegation problem completely.

Problem 2 - Too Many Data Calls

Every time a screen loads, Power Apps makes network calls to your data sources. Too many calls means slow screens.

How to Spot It

Use the built-in Monitor tool (Settings > Upcoming features > Experimental > Enable Monitor). This shows every network call, its duration, and the data returned. If you see 20+ calls when a screen loads, you have a problem.

Common Causes

Formulas in control properties that reference data sources directly:

// Every text label with this formula makes a separate data call
Text = LookUp(Customers, ID = Gallery1.Selected.CustomerID).Name

If you have 10 labels each doing a LookUp, that's 10 separate network calls.

Galleries loading nested galleries:

A gallery that displays records, where each item contains another gallery or multiple LookUps, creates N+1 query problems. For a gallery showing 50 items with 3 LookUps each, that's 150+ data calls.

OnVisible loading data from multiple sources:

// Three separate data calls on screen load
OnVisible =
    ClearCollect(colCustomers, Customers);
    ClearCollect(colJobs, Jobs);
    ClearCollect(colParts, Parts)

The Fixes

Fix 1 - Use collections (ClearCollect) for reference data:

Load data that doesn't change often into local collections when the app starts, not when each screen loads.

// In App.OnStart - load once
ClearCollect(colStatuses, StatusList);
ClearCollect(colCategories, CategoryList);
ClearCollect(colTeamMembers, TeamMembers)

Then reference colStatuses instead of the data source throughout the app. One call instead of dozens.

Fix 2 - Reduce gallery page size:

Don't load 100 items into a gallery if users only see 10 at a time. Use the gallery's Items count property or implement lazy loading.

Fix 3 - Consolidate LookUps with AddColumns:

Instead of multiple LookUps in individual controls:

// Add related data to the collection once
ClearCollect(
    colJobsWithCustomer,
    AddColumns(
        Jobs,
        "CustomerName", LookUp(Customers, ID = CustomerID).Name,
        "CustomerPhone", LookUp(Customers, ID = CustomerID).Phone
    )
)

This makes fewer calls than having each label do its own LookUp.

Fix 4 - Use Concurrent() for parallel loading:

// Load data in parallel instead of sequentially
OnVisible = Concurrent(
    ClearCollect(colCustomers, Customers),
    ClearCollect(colJobs, Jobs),
    ClearCollect(colParts, Parts)
)

This doesn't reduce the number of calls, but it reduces the total wait time by running them simultaneously.

Problem 3 - Slow Galleries

Galleries are the most-used control in Power Apps and the most common source of visible slowness.

Symptoms

  • Blank items that pop in as you scroll
  • Stuttering or jerky scrolling
  • Long pause before gallery items appear
  • The app freezing briefly when navigating to a screen with a gallery

The Fixes

Fix 1 - Simplify gallery templates:

Every control in a gallery template is rendered for every visible item. A template with 15 controls displaying 20 items means 300 controls rendered. Reduce the template to essential information only.

Before: Name, email, phone, address, status, category, created date, modified date, assigned to, priority, due date, notes preview, photo thumbnail, action button, status icon.

After: Name, status, due date, action button. Show the rest on a detail screen.

Fix 2 - Avoid complex formulas in gallery items:

// Slow - calculated for every item, every render
Text = If(
    DateDiff(ThisItem.DueDate, Today()) > 0,
    "Overdue by " & DateDiff(ThisItem.DueDate, Today()) & " days",
    If(
        DateDiff(Today(), ThisItem.DueDate) <= 3,
        "Due soon",
        "On track"
    )
)

Better approach: Calculate this once in a collection and display the pre-calculated value.

Fix 3 - Use DelayOutput on search boxes:

// Set DelayOutput to true on the search TextInput
// This waits for the user to stop typing before filtering
// Instead of filtering on every keystroke
DelayOutput = true

Without this, typing "Melbourne" triggers 9 filter operations (M, Me, Mel, Melb, ...). With DelayOutput, it waits until typing stops and triggers once.

Fix 4 - Avoid images in galleries where possible:

Loading images for each gallery item is expensive. If you must show images:

  • Use thumbnails, not full-size images
  • Consider showing images only on the detail screen
  • Use image URLs that point to optimised versions

Problem 4 - Slow App Startup

If the app takes more than a few seconds to load, users will give up.

Common Causes

Too much in App.OnStart: Loading every piece of data when the app opens, regardless of whether the user needs it immediately.

Large resource files: Embedded images, custom fonts, and media files included in the app package.

Complex theming calculations: Dynamic colour schemes and styles that calculate on every launch.

The Fixes

Fix 1 - Move data loading from OnStart to screen OnVisible:

Only load data when the user actually navigates to the screen that needs it. App.OnStart should contain only what's needed for the first screen.

// App.OnStart - minimal
Set(varCurrentUser, User());
Set(varUserRole, LookUp(UserRoles, Email = User().Email).Role)

// Screen-specific data loading in each screen's OnVisible
// HomeScreen.OnVisible
ClearCollect(colMyJobs, Filter(Jobs, AssignedTo = varCurrentUser.Email))

Fix 2 - Use App.StartScreen instead of complex OnStart navigation:

// Instead of navigation logic in OnStart
App.StartScreen = If(
    varUserRole = "Admin", AdminScreen,
    varUserRole = "Manager", ManagerScreen,
    HomeScreen
)

Fix 3 - Reduce app file size:

  • Remove unused screens, controls, and media files
  • Use image URLs instead of embedded images
  • Reference external style values instead of embedding theme resources
  • Use the Solution Checker to identify unused components

Fix 4 - Use loading screens:

If startup genuinely needs time (complex security checks, large reference data loads), show a loading screen with a progress indicator. Users tolerate waits better when they can see something is happening.

Problem 5 - Form Submission Delays

Users click Save and nothing happens for 3-5 seconds. Or worse, they click Save again and create duplicate records.

The Fixes

Fix 1 - Disable the save button after click:

// Save button OnSelect
UpdateContext({locSaving: true});
SubmitForm(Form1);

// Save button DisplayMode
DisplayMode = If(locSaving, DisplayMode.Disabled, DisplayMode.Edit)

// Form OnSuccess
UpdateContext({locSaving: false});
Notify("Saved successfully", NotificationType.Success);
Navigate(ListScreen)

Fix 2 - Reduce the number of fields submitted:

If the form has 30 fields, each field's value needs to be sent to the data source. If only 5 fields changed, use Patch instead of SubmitForm to send only the changed values.

Fix 3 - Handle attachments separately:

Photo uploads and file attachments are slow. Submit the form data first, then upload attachments in the background. Show the user that the record is saved and attachments are uploading.

Fix 4 - Use optimistic UI updates:

Navigate away from the form immediately after submission, updating the local collection optimistically. If the submission fails, revert and notify. This makes the app feel faster even though the network call takes the same time.

Problem 6 - The App Has Outgrown Power Apps

Sometimes the performance problems aren't fixable. The app has outgrown the platform.

Signs You've Hit the Ceiling

  • Data volume: More than 50,000 active records with complex queries
  • User count: 200+ concurrent users causing throttling
  • Calculation complexity: Business logic that takes seconds to evaluate in Power Fx
  • Real-time requirements: Users need to see changes from other users within seconds, not minutes
  • Integration volume: 10+ external system connections with frequent data exchange
  • Screen count: 30+ screens with complex navigation and shared state

What to Do

Option 1 - Optimise ruthlessly: Apply every fix in this article. You might squeeze another 6-12 months from the platform.

Option 2 - Offload processing: Move complex calculations and data processing to Power Automate or Azure Functions. Let Power Apps be the UI layer only.

Option 3 - Hybrid architecture: Keep Power Apps for simple screens and build custom components (PCF controls) for performance-critical parts.

Option 4 - Plan the migration: If the app is business-critical and growing, start planning a custom application. Use the Power Apps version to document requirements - you now know exactly what users need because they've been using it.

We've helped several clients make this transition. The Power Apps version wasn't a failure - it proved the concept, delivered value, and defined requirements for the production system. Our custom development team builds the next generation while the Power Apps version keeps running.

Performance Testing Checklist

Before releasing any Power Apps update, run through this checklist:

  • Monitor tool shows fewer than 10 data calls per screen load
  • No delegation warnings on gallery filter expressions
  • App startup completes in under 3 seconds on target devices
  • Gallery scrolling is smooth with production-volume data
  • Form submission completes in under 2 seconds
  • Offline mode works if required (test in airplane mode)
  • The app works on the slowest device and connection your users have
  • Search returns results in under 1 second
  • No duplicate record creation from double-taps

Getting Help With Performance

If you've tried these fixes and the app is still slow, it's worth getting an expert assessment. Our Power Apps consultants can review your app, identify the specific bottlenecks, and recommend the most effective fixes.

Sometimes it's a quick win - a single non-delegable formula causing all the grief. Sometimes it's architectural - the app needs restructuring to perform well. And sometimes the honest answer is that a different approach will serve you better.

Either way, your users deserve an app that's fast. Slow tools get abandoned, and all the effort you put into building the app goes to waste. Get in touch and we'll help you work out the right path forward.