Tutorials/Power Apps/Mastering Patch in Power Apps: Create, Update, and Upsert Records
Power Appsintermediate

Mastering Patch in Power Apps: Create, Update, and Upsert Records

Learn how to use the Patch function for single and batch operations, with a real-world project tasks example.

NA
Narmer Abader
@narmer · Published June 3, 2026

Power Apps can read and write data through a few functions: Patch is the most flexible — and the most misunderstood. The same function handles creating, updating, merging, and even changing in‑memory variables, which is why newcomers find it confusing.

Rather than memorising seven separate syntaxes, think of Patch as a single pattern: you provide a data source, one or more records, and then a set of changes to apply. The exact shape of those arguments determines whether you are creating, updating, or doing both at the same time.

In this article you'll build a practical example using a SharePoint list called ProjectTasks. Every snippet is production‑ready, and I've added performance notes where delegation matters.

Scenario: ProjectTasks list

Our list tracks tasks with these columns:

Internal NameType
TaskIDNumber (auto‑increment)
TaskNameText
OwnerPerson or Group
StatusChoice (Not Started, In Progress, Completed)
DueDateDate only
PriorityChoice (Low, Medium, High)

All examples assume the app has a data source named ProjectTasks connected to this SharePoint list.

1. Create a single task

The simplest Patch call creates a new record. Use Defaults(<data source>) as the base record, then supply a record of column values to set.

Patch(
    ProjectTasks,
    Defaults(ProjectTasks),
    {
        TaskName: "Design landing page",
        Owner: {Claims: "i:0#.f|membership|emily@contoso.com", DisplayName: "Emily Tran"},
        Status: "Not Started",
        DueDate: Date(2026, 6, 30),
        Priority: "High"
    }
)

This returns the newly created record, including system fields like TaskID and Created. You can capture it if you need the ID later.

2. Update an existing record

To change one or more fields, pass the existing record (obtained with LookUp or First) as the second argument and the changes as the third argument. Only the columns you include are updated; everything else stays the same.

Patch(
    ProjectTasks,
    LookUp(ProjectTasks, TaskID = 4),
    {
        Status: "Completed",
        Priority: "Medium"
    }
)

Delegation note: LookUp is delegable when the predicate is a simple equality on the primary key. If you cannot guarantee delegation, use Filter with a top‑n limit or consider a gallery selection to obtain the record.

3. Capture the result in a variable

Patch returns the modified record, which is especially useful for getting the new ID or the full record after creation.

Set(
    varCurrentTask,
    Patch(
        ProjectTasks,
        Defaults(ProjectTasks),
        {
            TaskName: "Fix login bug",
            Owner: {Claims: "i:0#.f|membership|jay@contoso.com", DisplayName: "Jay R. "},
            Status: "In Progress",
            DueDate: Date(2026, 7, 5),
            Priority: "High"
        }
    )
)

After this runs, varCurrentTask contains the entire record – including the TaskID assigned by SharePoint. You can use it immediately in a notification or navigate to a detail screen.

4. Create multiple records in one call

Batch creation reduces network round‑trips. Build a table of new records, then use ForAll to generate a matching number of Defaults records.

ClearCollect(
    colNewTasks,
    Table(
        {TaskName: "Write tests", Owner: ..., Status: "Not Started", DueDate: Date(2026,7,1), Priority: "Medium"},
        {TaskName: "Review PR #42", Owner: ..., Status: "Not Started", DueDate: Date(2026,7,2), Priority: "Low"},
        {TaskName: "Update docs", Owner: ..., Status: "Not Started", DueDate: Date(2026,7,3), Priority: "High"}
    )
);
Patch(
    ProjectTasks,
    ForAll(Sequence(CountRows(colNewTasks)), Defaults(ProjectTasks)),
    colNewTasks
)

Performance note: When Patch receives table arguments, SharePoint and SQL Server support sending multiple changes in fewer network requests. For Dataverse, each row is a separate Web API call regardless of the table-form syntax, so consider using a Power Automate flow with bulk operations for very large sets.

5. Edit multiple existing records

To update several records at once, pass a table of records that includes the primary key (TaskID) and only the columns to change. The trick is to supply a base‑record table that contains just the IDs.

ClearCollect(
    colUpdates,
    Table(
        {TaskID: 2, Status: "Completed"},
        {TaskID: 5, Priority: "High"},
        {TaskID: 9, DueDate: Date(2026, 7, 15)}
    )
);
Patch(
    ProjectTasks,
    ShowColumns(colUpdates, "TaskID"),
    colUpdates
)

Each record in the third table is matched to the corresponding base record by position, not by ID value. This is the fastest way to apply different changes to different rows in one call.

6. Upsert: create or update by ID

Upsert is a single call that creates records where the ID is blank and updates records where the ID matches an existing row. The second argument becomes the combined table, and the third argument is omitted.

ClearCollect(
    colUpsert,
    Table(
        {TaskID: 3, Status: "In Progress", Owner: ...},   // updates task 3
        {TaskID: Blank(), TaskName: "New task", Owner: ..., Status: "Not Started", DueDate: Date(2026,8,1), Priority: "Low"} // creates new
    )
);
Patch(
    ProjectTasks,
    colUpsert
)

The first record contains a non‑blank TaskID, so it updates. The second has Blank() for TaskID, so a new record is created. This pattern is ideal for synchronising data from an external source.

7. Update an in‑memory variable without touching the data source

Patch is not limited to data sources. When you pass two records of the same type, it merges the second into the first and returns a new copy. The original variable is not mutated – you must assign the result.

// Assume varTask is a record variable
Set(
    varTask,
    Patch(
        varTask,
        {Priority: "High", Status: "In Progress"}
    )
)

This is a clean way to modify a record variable without writing back to the data source. Useful for staging changes before a user confirms.

Variable scope

Remember: Patch with two records returns a new record; it does not alter the original variable. Always capture the result with Set or a context variable update.

Common mistakes and how to avoid them

  • Forgetting to capture the result – If you need updated fields or the new ID, always assign the return value to a variable.
  • Mixing Person column formats – The Owner column requires a special structure. Use {Claims: "i:0#.f|membership|alias@domain.com", DisplayName: "Name"}.
  • Passing a table where a record is expected – The third argument of Patch is a record, not a table. For multiple changes, use the batch pattern shown above.
  • Over‑fetching in LookUp – When updating a single record, prefer LookUp over Filter because it returns one record and is often delegable.

Delegation and performance

  • Patch operations are not delegated to the data source in the traditional sense; the entire operation happens in the server but is limited by the data source's API.
  • For batch operations, SharePoint and SQL Server support sending multiple changes in a single request. Dataverse treats each row as a separate web API call, so batch create/update may not be faster than a loop.
  • Always filter the base table as much as possible before calling Patch to minimise the data sent over the network.

Final recommendation

Start with the single‑record create and update patterns – they cover 80 % of real‑world forms. Once you’re comfortable, explore batch operations to handle scenarios like importing spreadsheets or bulk status changes. The upsert pattern is a powerful tool for integrations, and the two‑record variable form can simplify complex screen logic.

Nothing beats experimenting in a small test app. Create a SharePoint list with a few rows and try each of the snippets above – you’ll quickly build an intuition for when Patch is the right tool.

References