Live training: next batches coming soon. Join the waitlist:Waitlists open:Developer Training →Developer →Copilot Studio Training →Copilot Studio →

Power Apps OnStart vs OnVisible: Which One Runs When (Tested)

Think about how often the logic has to run. Something the whole app needs once, like an app name or a theme color, belongs to the app. Something a screen needs fresh every time a user lands on it, like a count of new requests, belongs to that screen.

So here’s my rule: use OnStart for one-time, app-wide setup, and use OnVisible for anything that must refresh each time a screen opens. In 2026 I’d also reach for StartScreen to pick the first screen and named formulas for values that never change.

In this tutorial, we’ll compare powerapps onstart vs onvisible on one real app. You’ll see a counter prove how often each one runs, why UpdateContext only works in OnVisible, how to rerun OnStart in Studio, and what replaced Navigate in OnStart.

OnStart vs OnVisible at a Glance

Here’s the short version from my tests in the Service Desk Demo app. OnStart is a property of the App object; OnVisible is a property of every screen. If you’re unsure which variable type to set in each, my guide on global vs context variables in Power Apps covers that side.

FeatureApp.OnStartScreen.OnVisible
Belongs toThe App object (top of Tree view)Each screen
When it runsOnce, when the app startsEvery time a user navigates to the screen
In my testgblStartRuns stayed 1gblVisibleRuns went 1 -> 2 after leaving and coming back
Set (global variables)YesYes
UpdateContext (context variables)No, no screen is loaded yetYes
Rerun in StudioApp … > Run OnStartSelect the screen, or navigate to it in Preview
Navigate to the first screenRetired; use App.StartScreenWorks (it’s a behavior property)
TimingNon-blocking by default, may finish lateCan run in parallel with OnStart
Best forApp-wide setup that runs onceScreen data that must be fresh

Build the Demo App Step by Step

Every test below runs on the same app and the same list: Service Requests on my SPGuides site. It has 623 items (620 sample requests plus 3 test rows) with the columns Title, Status, Priority, Requester and DueDate. Status is a choice column with New, In Progress and Closed.

SharePoint Service Requests list with Title Status and Priority columns used for the OnStart vs OnVisible test

To build the same app, sign in to make.powerapps.com and select Start with design on the Home page.

Power Apps maker portal Home page with the Start with design option highlighted

Choose Create from blank to start an empty canvas app.

Create from blank option for a new Power Apps canvas app

Name the app and pick the Tablet format, then select Create.

Start with a blank canvas dialog with the Tablet layout selected in Power Apps

In Studio, select Add data, type SharePoint in the search box and pick the SharePoint connector.

Add data pane in Power Apps Studio searching for the SharePoint connector

Paste your site URL (mine is /sites/SPGuides) and select Connect.

Connect to a SharePoint site dialog with the SPGuides site URL entered

Check Service Requests and select Connect again. The list now shows up in the Data pane.

Choose a list dialog with the Service Requests SharePoint list selected

Now add the test screen. Select New screen > Blank, then select the screen, select the pencil next to its name in the Properties pane and rename it scrOnVisible. Add a second blank screen named scrParam for the round trip.

On scrOnVisible, insert four labels and set each one’s Text property to one of these names, so the screen shows the live values:

gblStartRuns
gblVisibleRuns
locNewCount
gblAppName

Add a button with the text “Go to scrParam” and this OnSelect. My post on navigating between screens in Power Apps explains Navigate in more detail:

Navigate(scrParam)

On scrParam, add a “Back” button with this OnSelect, so you can return to the screen you came from:

Back()

Three Studio moves you’ll repeat: select a control, pick the property in the dropdown to the left of the fx formula bar, then type the formula. Select Play (top right) or press F5 to preview, and press Ctrl+S to save. More beginner guides live in the Power Apps tutorials hub.

How Often Does OnStart Run Compared to OnVisible?

This is the difference that matters most, so I made each property count its own runs. In Tree view, I selected App, picked OnStart in the property dropdown and entered this formula:

Set(gblStartRuns, gblStartRuns + 1);
Set(gblAppName, "Service Desk Demo")
App object selected in Power Apps Studio with the OnStart formula that counts runs in gblStartRuns

Then, on the same app, I selected scrOnVisible, picked OnVisible and entered the screen’s formula. It adds 1 to its own counter and counts the New requests into a context variable:

Set(gblVisibleRuns, gblVisibleRuns + 1);
UpdateContext({locNewCount: CountIf('Service Requests', Status.Value = "New")})
scrOnVisible screen OnVisible formula in Power Apps Studio with gblVisibleRuns and a CountIf delegation warning

Selecting the screen in Studio ran OnVisible once, so gblVisibleRuns showed 1. Next I opened Preview, clicked Go to scrParam, and clicked Back. The result: gblStartRuns stayed at 1, gblVisibleRuns rose to 2, and locNewCount showed 167.

Power Apps Preview after Back showing gblStartRuns 1 gblVisibleRuns 2 and locNewCount 167

Why the gap? OnStart belongs to the app’s launch, and moving between screens isn’t a launch. OnVisible fires on every arrival, so anything you put there reruns, including the SharePoint call. Keep it light on screens users visit often.

Important: the 167 isn’t the full count. CountIf isn’t delegable to SharePoint, so Studio shows a yellow warning and the count covers only the first 500 rows. My guide on fixing Power Apps delegation warnings shows how to get an exact total.

Can You Use UpdateContext in OnStart?

No. When OnStart runs, no screen has loaded yet, and a context variable always belongs to a screen. Microsoft Learn states it plainly: you can’t set context variables with UpdateContext in OnStart.

On the same scrOnVisible screen, OnVisible has no such limit. That’s why my locNewCount lives there: UpdateContext created it when the screen opened, and only that screen can read it.

So in OnStart, use Set for global variables and Collect or ClearCollect for collections, which I cover in my Power Apps collection guide. If one screen needs several values at once, a single UpdateContext record sets them all, as in setting multiple variables at once.

Note: Status choices in my list are New, In Progress and Closed. My first try counted “Open” and got 0 with no error, because no request has that status. Check the exact choice text when you use the Power Apps CountIf function.

How to Rerun OnStart Without Reloading the App

OnVisible is easy to retest: go to another screen and come back. OnStart doesn’t rerun on navigation, so Studio gives you a menu item for it.

  1. In Tree view, hover over App and select the ellipsis (…).
  2. Select Run OnStart.
  3. Check your labels: on my screen, gblStartRuns showed 1 and gblAppName showed Service Desk Demo.
App ellipsis menu in Power Apps Tree view with the Run OnStart option

The same menu has Navigate to StartScreen, which tests the StartScreen formula covered below.

One catch from Microsoft Learn: when you rerun OnStart this way, variables and collections that already exist keep their values. Collect would add the rows a second time, so use ClearCollect in OnStart if you want a clean collection on every run.

Does OnVisible Wait for OnStart to Finish?

Not anymore. Non-blocking OnStart is the default, so OnStart runs at the same time as other app formulas, and the first screen’s OnVisible can run in parallel with it. A screen can even become interactive before OnStart finishes.

In my small app this never showed, because two Set calls finish almost instantly. A slow OnStart that loads a large list is a different story: a gallery or label on the first screen can read a variable before it’s set and show blank.

Microsoft’s advice is not to rely on OnStart variables inside OnVisible. If the first screen needs the data, load it in that screen’s OnVisible, or use a named formula, which has no timing gap at all.

Navigate in OnStart Is Retired: Use StartScreen Instead

Older apps often ended OnStart with Navigate to choose the first screen. That’s retired: existing apps still work, and a Retired setting brings it back for a limited time, but it slows loading because the app has to finish OnStart before showing anything.

The replacement is the App object’s StartScreen property. This is the one in the same Service Desk Demo app; it opens a screen based on a URL parameter:

If(
    Param("screen") = "param", scrParam,
    Param("screen") = "combo", scrComboDefault,
    Param("screen") = "launch", scrLaunch
)

With no parameter, the If returns blank and the app opens on the first screen in Tree view, scrDelegation. With &screen=param in the app’s URL, it opens scrParam.

Heads up: StartScreen can’t read global variables or collections from OnStart. Use Param, User, LookUp, or a named formula there instead.

Named Formulas: The Third Option Most Apps Need

Microsoft now suggests moving cached values and global setup out of OnStart into the App object’s Formulas property. A named formula is written as name = expression, and you use the name anywhere in the app.

For the same demo app, my gblAppName and the New-request count could become these two lines in App.Formulas:

AppTitle = "Service Desk Demo";
NewRequestCount = CountIf('Service Requests', Status.Value = "New");

Learn lists four advantages: the value is always available (no wait for OnStart), always up to date when the list changes, can’t be changed elsewhere in the app, and is only calculated when a screen uses it. The trade-off is that named formulas can’t use behavior functions like Set, Collect or Navigate.

When to Use OnVisible Instead of OnStart

Here’s how I decide on a new app in 2026:

  • A value that never changes (app name, colors, the current user): a named formula. Use OnStart only if you need Set.
  • Data that must be fresh each time a screen opens: that screen’s OnVisible.
  • A context variable for one screen: OnVisible, because UpdateContext doesn’t work in OnStart.
  • Picking the first screen: App.StartScreen, never Navigate in OnStart.
  • Something triggered by a click: neither one; put it in the button OnSelect property.

And don’t set the same variable in both places. With OnStart and OnVisible running in parallel, whichever finishes last wins, which makes bugs hard to reproduce.

How to Switch Logic from OnStart to OnVisible

If an old app has a long OnStart, I move it in small pieces rather than all at once:

  1. Save the app (Ctrl+S) so you can restore the old version.
  2. Find formulas in OnStart that only one screen uses, and cut them into that screen’s OnVisible.
  3. Change Set to UpdateContext where only that screen reads the variable.
  4. Move constant values into App.Formulas as named formulas.
  5. Replace any Navigate at the end of OnStart with an App.StartScreen formula.
  6. Run OnStart, then preview each screen and check the values.

So the deciding difference is frequency: OnStart ran once in my test while OnVisible ran on every visit. Add the UpdateContext rule and the retired Navigate, and most logic ends up in OnVisible, StartScreen or named formulas.

If you’re tidying up variables and data loading in your app next, these guides pick up from here:

Frequently Asked Questions

Does OnStart run again when I navigate back to the first screen?

No. OnStart runs when the app starts. In my test, gblStartRuns stayed at 1 after leaving the screen and coming back, while the screen’s OnVisible counter went from 1 to 2.

Why don’t I see the OnStart property on the App object?

Microsoft notes that OnStart might be disabled by default in some contexts, with a switch in the app’s Advanced settings to turn it on. The App object reference on Microsoft Learn lists the alternatives it recommends first.

Why is my variable blank on the first screen when OnStart sets it?

Non-blocking OnStart is the default, so the first screen can render before OnStart finishes. Load the data in that screen’s OnVisible, or use a named formula, which has no timing dependency.

Does OnVisible run when I preview a screen in Studio?

Yes. Selecting a screen in Studio ran its OnVisible once in my test, and every navigation to it in Preview ran it again. Use Run OnStart from the App menu to retest OnStart.

What is OnHidden in Power Apps?

OnHidden is the screen property that runs when the user navigates away from the screen. The Screen control reference documents it next to OnVisible.