Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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
contentsvalue, 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
chocolateused 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
Loadingfirst, 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.