Azure confidential ledger limits

Azure confidential ledger limits the number of ledgers in a subscription and the data and code that a ledger stores, to keep the performance and availability of every ledger predictable. This article describes these limits, how the ledger responds when a request exceeds them, and what performance to expect from a ledger.

Note

The limits in this article are defaults. In certain cases, an individual ledger can have different limits, for example, a ledger created before a limit was introduced. To request higher limits or discuss limitations, contact Azure support.

Subscription limits

The following limit applies to each Azure subscription.

Limit Value
Ledgers per subscription 2

Ledger data limits

The following limits apply to every ledger by default.

Limit Default value Error code
Collections per ledger 5,000 CollectionCapacityExceeded
Collection ID length 256 bytes CollectionIdTooLong
Size of the contents of a ledger entry 8 KiB (8,192 bytes) EntrySizeCapacityExceeded
Tags per ledger (public ledgers only) 10,000 TagCapacityExceeded
  • Collections per ledger: The default collection isn't counted. When a ledger reaches the limit, writes that would create a new collection are rejected. Writes to existing collections still succeed.
  • Collection ID length: The length is measured in bytes of the UTF-8 encoded ID, after URL decoding. The limit applies only when a write creates a new collection, so you can keep writing to and reading from collections created before this limit was introduced.
  • Size of the contents of a ledger entry: The size is measured in bytes of the UTF-8 encoded contents value, after JSON decoding. Contents of exactly 8,192 bytes are accepted. The limit applies to writes to both new and existing collections. The collection ID, tags, and other fields of the request don't count toward this limit. The whole request is also subject to the ledger's maximum request body size.
  • Tags per ledger: A tag counts once for each collection that uses it. For example, the tag chocolate used in two collections counts as two tags. When a ledger reaches the limit, writes that would add a new tag to a collection are rejected. Writes without tags, or with tags that the collection already uses, still succeed.

A write that exceeds a limit is rejected with HTTP status code 400 (Bad Request), and nothing in the request is written to the ledger. The response contains the error code and a message that includes the limit that applies to the ledger. For example:

{
  "error": {
    "code": "EntrySizeCapacityExceeded",
    "message": "Entry contents of 9000 bytes exceed the limit of 8192 bytes."
  }
}

Tag limits per write

Tags are supported only on public ledgers. The following limits apply to every public ledger.

Limit Value
Tags per write 5
Tag length 63 characters

Tags can't be empty and can contain only the characters A–Z, a–z, 0–9, -, _, ., and ~. A write that exceeds these limits or contains an invalid tag is rejected with HTTP status code 400 and the NotAllowed error code.

User defined function limits

The following limits apply to user defined functions (UDFs) in every ledger. Requests that exceed them are rejected with HTTP status code 400.

Limit Value Error code
UDFs per ledger 100 UserDefinedFunctionCapacityExceeded
UDF ID length 256 bytes InvalidFunctionId
UDF code size 64 KiB (65,536 bytes) InvalidInput
Pre-hooks per write 5 InvalidInput
Post-hooks per write 5 InvalidInput

The UDF count and ID length limits apply only when you create a UDF. You can still update an existing UDF if its code fits within 64 KiB.

For the runtime options that apply when a UDF runs, see Running UDFs. For more information about pre-hooks and post-hooks, see Transaction hooks.

User defined endpoint runtime options

Values set with PATCH /app/userDefinedEndpoints/runtimeOptions must be within the following ranges. Otherwise, the request is rejected with HTTP status code 400 and the InvalidInput error code. Only the options whose value the request changes are checked.

Runtime option Allowed values
max_heap_bytes Up to 209,715,200 (200 MiB)
max_stack_bytes 1 to 10,485,760 (10 MiB)
max_execution_time_ms Up to 10,000 (10 seconds)
max_cached_interpreters 1 to 20

Performance

A ledger's performance depends on your workload, such as the size of your entries, how many requests you send concurrently, and the mix of reads and writes. The following guidance gives a general idea of what to expect. It isn't a guarantee.

Throughput

  • A ledger can sustain hundreds of writes per second. Smaller entries and more concurrent requests increase the rate. Writes that run user defined functions take longer, depending on the functions' code.
  • Reading the latest entry of a collection uses fewer resources than a write, so a ledger can usually serve more of these requests. Getting an entry by transaction ID, getting a receipt, and range queries use more resources than reading the latest entry, because the ledger first loads the data from storage. A high rate of these requests reduces the throughput left for writes.
  • A client that waits for each response before it sends the next request is limited by its round-trip time to the ledger. To get the most out of a ledger, send requests concurrently and reuse connections.

If your workload needs sustained high throughput, test it on a ledger before you go to production. If you need more throughput, contact Azure support.

Latency

  • By default, a write request returns as soon as the ledger accepts the write, and the ledger commits the write shortly after. Before you rely on a write, for example to get its receipt, check that its status is Committed. The client libraries can wait for the commit for you.
  • Getting an entry by transaction ID, getting a receipt, and range queries can return Loading first, while the ledger loads the data. Repeat the request within one minute until it returns the result.
  • Latency also depends on distance and load. Each new connection needs a TLS handshake with the ledger, so reuse connections and run your clients close to the ledger's region. Expect latency to increase as the load on a ledger approaches what it can sustain.