I still remember when our field technicians were forced to revert to paper notes because their app couldn’t retrieve critical equipment details in a remote area. That day underscored a simple truth: offline functionality isn’t a luxury—it’s a necessity. From that moment, I was determined to ensure our Power Apps could stand on their own, even when the internet couldn’t.

In many real-world scenarios, reliable connectivity can’t be taken for granted. Whether you’re working deep in the backcountry or just dealing with spotty cell coverage, enabling offline capabilities in your Canvas Apps ensures users can continue working seamlessly. This article will show you how to build a Canvas app that keeps going offline, using the Power Apps functions SaveData and LoadData.

Why Offline Capabilities Matter

Offline functionality empowers users to:

  • Keep working uninterrupted when connections drop
  • Pre-load critical reference data before venturing into low-connectivity areas
  • Capture and store data locally to sync later
  • Eliminate the frustration of lost work due to network issues

After rolling out offline support in our inspection app, we saw a 70% reduction in data entry errors, saved technicians nearly an hour daily, and dramatically improved user satisfaction. In short, adding offline support directly impacts productivity and user trust in your app.

SaveData and LoadData: Core Offline Functions

SaveData writes collections to device storage, LoadData retrieves them. The key limitation: 1 MB on web browsers, device storage on mobile. Don’t store sensitive data—it’s not encrypted.

// Save data when online
SaveData(MyCollection, "MyLocalCache")

// Load it back when offline
LoadData(MyCollection, "MyLocalCache", true)  // true suppresses errors on first run

That third parameter prevents errors when no cache exists yet—essential for first-time app launches. Combine these with Connection.Connected to detect network status and switch between online and offline data sources.

Implementation Pattern

Planning Your Offline Strategy

Identify what data your app needs offline:

  • Reference Data: Equipment specs, product catalogs (read-only lookups)
  • User Input Data: Inspection forms, orders (created/updated offline)
  • App State: User preferences, sync timestamps, last screen viewed

Keep the scope lean—better performance and you won’t hit storage limits.

Caching Data at Startup

Cache essential data at app startup using App.OnStart:

// App.OnStart - Load data from appropriate source
If(
    Connection.Connected,
    // Online: get fresh data and cache it
    ClearCollect(EquipmentData, EquipmentDataSource);
    ClearCollect(WorkOrders, Filter(WorkOrdersSource, AssignedTo = User().Email));
    SaveData(EquipmentData, "EquipmentCache");
    SaveData(WorkOrders, "WorkOrderCache"),
    // Offline: load from cache
    LoadData(EquipmentData, "EquipmentCache", true);
    LoadData(WorkOrders, "WorkOrderCache", true)
);
Set(isOfflineMode, !Connection.Connected);

After this runs, EquipmentData and WorkOrders contain data from either the server or cache—your app doesn’t need to care which.

Tracking Offline Changes

Capture offline changes for later sync:

// Save button OnSelect
Collect(OfflineChanges, {
    ID: GUID(),
    EntityType: "Inspection",
    ChangeType: "Update",  // or "Create", "Delete"
    ChangeData: frmInspectionData,
    ChangeTime: Now()
});
SaveData(OfflineChanges, "PendingChanges");

This queues changes with metadata for synchronization when connectivity returns.

Synchronization

Sync button pushes queued changes when online:

// Sync button OnSelect
If(Connection.Connected,
    ForAll(OfflineChanges,
        Switch(ThisRecord.ChangeType,
            "Create", Patch(InspectionsDataSource, Defaults(InspectionsDataSource), ThisRecord.ChangeData),
            "Update", Patch(InspectionsDataSource, LookUp(InspectionsDataSource, ID = ThisRecord.RecordID), ThisRecord.ChangeData),
            "Delete", Remove(InspectionsDataSource, LookUp(InspectionsDataSource, ID = ThisRecord.RecordID))
        )
    );
    Clear(OfflineChanges);
    SaveData(OfflineChanges, "PendingChanges");
    ClearCollect(EquipmentData, EquipmentDataSource);
    ClearCollect(WorkOrders, Filter(WorkOrdersSource, AssignedTo = User().Email));
    SaveData(EquipmentData, "EquipmentCache");
    SaveData(WorkOrders, "WorkOrderCache");
    // Update sync status and timestamp
    Set(lastSyncTime, Now());
    Set(syncSuccessful, true);
    SaveData(Table({ lastSyncTime: lastSyncTime }), "SyncInfo");
    ,
    // **Offline**: if sync attempted without connection
    Set(syncSuccessful, false)
);

This code:

  1. Processes each offline change based on its type (create, update, or delete)
  2. Clears the offline changes once processed
  3. Refreshes the local caches with the latest server data
  4. Updates the last sync timestamp
  5. Sets a status flag to indicate sync success or failure

This synchronization ensures that once a connection is restored, all offline changes are applied to the backend and local caches are refreshed.

User Experience Best Practices

To create a seamless offline experience, implement these UI elements:

  1. Connection Status Indicator: Show users when they’re working offline with a subtle banner or icon
  2. Last Sync Information: Display when data was last synchronized (e.g., “Last synced: 3/6/2025 10:45 AM”)
  3. Sync Button: Give users a way to manually trigger synchronization when they’re back online
  4. Sync Status Notification: After sync, show a brief confirmation like “All changes synced!” or “Sync failed: You’re offline”

These visual cues build user confidence by making the app’s state transparent. Users need to know if they’re working with the latest data or need to sync changes.

Key Considerations

As you implement offline capabilities, keep these points in mind:

Storage Limits

  • Web Player: Limited to 1 MB for SaveData
  • Mobile Apps: Limited by device storage, but keep it reasonable for performance

Data Prioritization

  • Cache only what users truly need offline
  • For large datasets, implement filtering to cache only relevant subsets

Conflict Handling

In multi-user systems, you may need a strategy for handling conflicts when the same record is modified by different users while offline. Options include:

  • Last writer wins (simplest approach)
  • Timestamp comparison to determine precedence
  • Conflict flagging for manual resolution

Testing

Thoroughly test your offline implementation by:

  • Enabling airplane mode to simulate complete connection loss
  • Testing with slow or intermittent connections
  • Verifying behavior when transitioning between online and offline
  • Confirming changes sync properly when reconnected

Conclusion

Offline capabilities are a game-changer for mobile Canvas Apps. By leveraging SaveData and LoadData to cache data and building a sync mechanism for when connectivity returns, you can create robust, offline-ready solutions that keep users productive no matter where they are.

The journey to offline-capable apps might seem complex at first, but the workflow is straightforward once you understand the pattern:

  1. Cache data when online using SaveData
  2. Load from cache when offline using LoadData
  3. Track changes made while offline
  4. Sync those changes when a connection is restored

Now your field technicians, like ours, can continue their digital workflow even in remote areas. The results? Happier users, fewer headaches, and no more returning to paper forms when connectivity fails.

Remember these key takeaways:

  • Plan what data is truly needed offline
  • Cache on launch when connectivity is available
  • Use local collections for offline changes
  • Provide clear visual indicators of online/offline status
  • Test thoroughly in various connectivity scenarios

What offline scenarios do you need to support in your Power Apps? With SaveData and LoadData, you have the tools to ensure your apps work flawlessly, online or off.