DEV Community

Daniel Jonathan
Daniel Jonathan

Posted on

Inside Logic Apps Standard: Understanding Compute Units (CU) for Storage Scaling

Introduction

When your Logic App Standard workflows grow in volume and complexity, Azure provides a powerful horizontal scaling mechanism through Compute Units (CU). This post explains how CU architecture enables Logic Apps to distribute storage load across multiple storage accounts while maintaining data consistency and routing integrity.


Why Storage Scaling Matters

A single Azure Storage account has inherent limits:

  • ~2,000 requests per partition
  • ~20,000 requests per second at account level

Beyond these thresholds, request throttling occurs. For high-volume Logic Apps processing thousands of runs with dozens of actions each, a single storage account quickly becomes a bottleneck.

Microsoft's guidance suggests approximately 100K action executions per minute per storage account as a threshold for considering additional storage. Compute-heavy workflow actions may lower this threshold significantly.


What Are Compute Units?

Compute Units (also called Scale Units) are Azure Logic Apps' approach to horizontal storage scaling. Rather than overloading a single storage account with all workflow execution data, Logic Apps can distribute the load across up to 32 storage accounts (CU00 through CU31).

You configure this via host.json using the Runtime.ScaleUnitsCount parameter.


Single Storage Architecture

In the simplest deployment, all workflows use a single storage account:


Logic App → CU00 (Master) → Single Storage Account
Enter fullscreen mode Exit fullscreen mode

With single storage:

  • All workflow definitions, runs, and actions live in one storage account
  • The storage account uses the CU00 suffix
  • This works well for low-to-moderate workloads

Scale-Out Storage Architecture

When a Logic App needs to handle high-volume workflows, it can scale out to multiple storage accounts:

Multi-Storage Architecture

Logic App → CU00 (Master)  → Storage Account 1
         → CU01            → Storage Account 2
         → CU02            → Storage Account 3
         → ...             → ...
         → CU31            → Storage Account 32
Enter fullscreen mode Exit fullscreen mode

Each Compute Unit maps to its own dedicated storage account, allowing parallel writes and reads across multiple storage endpoints.


How CU Routing Works

The key to this architecture is the Run ID. Every workflow run includes a CU suffix that identifies which storage account contains its action data:

08584345852018133305811297792-CU00
08584345852018133305811297793-CU01
08584345852018133305711297794-CU02
Enter fullscreen mode Exit fullscreen mode

CU Routing Storage Architecture

Routing Steps

  1. Extract CU suffix from the RunId (e.g., -CU01)
  2. Lookup storage account mapping for the Logic App + CU combination
  3. Query the correct storage account for action data

This ensures that when you request run details, the system knows exactly which storage account to query.


Table Distribution Across CUs

Not all tables are distributed the same way. Here's the key distinction:

Table Type Location Determined By
Base Tables (flows, jobdefinitions, etc.) Always CU00 (Master)
Workflow flows, runs, histories ScaleUnit field in base flows metadata table
Date-stamped actions tables RunId-CUXX suffix (per-run routing)

Two Different Assignment Mechanisms

1. Workflow Tables (ScaleUnit field)

When you deploy a new workflow, Logic Apps assigns it to a CU. This assignment is:

  • Non-deterministic from developer perspective - you can't specify "put this workflow on CU02"
  • Decided at deployment time - when a new workflow is added, Logic Apps picks a CU
  • Stored in the workflow's metadata - the ScaleUnit field in the flows table records the assignment

The workflow's flows, runs, and histories tables live in this assigned CU storage account.

2. Action Tables (RunId-CUXX suffix)

Here's the critical difference: action tables are distributed per-run, not per-workflow.

Each run execution gets assigned to a CU, indicated by the suffix in the RunId:

08584345852018133305811297792CU01
08584345852115148130432249577CU00
Enter fullscreen mode Exit fullscreen mode

This means:

  • A single workflow's actions can be spread across multiple CU storage accounts
  • On any given date, you might have action tables for the same workflow in CU00, CU01, CU02, etc.
  • Each storage account has its own date-stamped action table: {WFIdentifier}20250114T000000Zactions

Example: Distributed Actions

For a workflow with ScaleUnit = CU00, runs might execute across different CUs:

Workflow metadata (flows, runs, histories) → CU00 storage

Run 1: 08584345852018133305811297792-CU00 → actions in CU00 storage
Run 2: 08584345852018133305811297793-CU01 → actions in CU01 storage
Run 3: 08584345852018133305811297794-CU00 → actions in CU00 storage
Run 4: 08584345852018133305811297795-CU02 → actions in CU02 storage
Enter fullscreen mode Exit fullscreen mode

On January 14, 2025, this workflow could have action tables in three different storage accounts:

  • CU00: flow{LAIdentifier}{WFIdentifier}20250114T000000Zactions
  • CU01: flow{LAIdentifier}{WFIdentifier}20250114T000000Zactions
  • CU02: flow{LAIdentifier}{WFIdentifier}20250114T000000Zactions

What This Means

  • App-level metadata stays centralized: Base tables remain in CU00 (Master)
  • Workflow metadata has a home: flows, runs, histories live in the workflow's assigned CU
  • Actions are truly distributed: Action data spreads across CUs based on run execution
  • Query complexity increases: To get all actions for a date range, you may need to query multiple storage accounts

Why This Matters

For High-Volume Workflows

If your Logic App processes thousands of runs daily, each run might execute dozens of actions. Without CU distribution:

  • A single storage account becomes a bottleneck
  • Table partition limits could throttle performance
  • Query latency increases as tables grow

With CU distribution:

  • Write operations spread across multiple endpoints
  • Each storage account handles a fraction of the load
  • Queries route directly to the relevant storage

For Run History Queries

When building tooling that queries run history (like export utilities or monitoring dashboards), you must account for CU routing:

  1. Parse the Run ID to extract the CU suffix
  2. Resolve the correct storage account for that CU
  3. Query the CU-specific storage for action data

Ignoring CU routing means you'll miss action data entirely.


Configuring Scale Units

To enable multiple storage accounts, configure host.json:

{
  "extensions": {
    "workflow": {
      "settings": {
        "Runtime.ScaleUnitsCount": 4
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This tells Logic Apps to use 4 storage accounts (CU00-CU03). You'll need to provision the additional storage accounts and configure their connection strings or managed identity access.

Authentication options:

  • Connection strings in app settings
  • Managed identity (recommended for production)

Summary

Compute Units enable Logic Apps Standard to scale storage horizontally:

  • CU00 is the master, holding app-level base tables
  • Workflow tables (flows, runs, histories) live in the CU specified by the ScaleUnit field
  • Action tables are distributed per-run based on the RunId-CUXX suffix
  • Same workflow, multiple CUs: A workflow's actions can span multiple storage accounts
  • Configure via Runtime.ScaleUnitsCount in host.json (max 32)
  • Threshold guidance: ~100K action executions per minute per storage account

Understanding this architecture is essential when building tooling around Logic Apps, querying run histories programmatically, or troubleshooting high-volume workflow performance.


References


This is part of the "Inside Logic Apps Standard" series, exploring the internals of Azure Logic Apps Standard architecture.

Top comments (0)