OpenBao limits and maximums
OpenBao imposes fixed upper limits on the size of certain fields and objects, and configurable limits on others. OpenBao also has upper bounds that are a consequence of its underlying storage. This page attempts to collect these limits, to assist in planning OpenBao deployments.
In some cases, the system will show performance problems in advance of the absolute limits being reached.
Storage-Related limits
Storage entry size
The maximum size of an object written to a storage backend is determined by that backend.
For the integrated storage backend, the default limit is 1 MiB. This may be
configured via max_entry_size
in the storage
stanza.
Many of the other limits within OpenBao derive from the maximum size of a storage entry, as described in the next sections. It is possible to recover from an error where a storage entry has reached its maximum size by reconfiguring OpenBao to a larger maximum storage entry. However, using large storage entries also negatively affects performance, as even a small change may become a large read-modify-write cycle on the entire entry. Larger writes may also delay Raft heartbeats, leading to leadership instability.
Mount point limits
All secret engine mount points, and all auth mount points, must each fit within a single storage entry. Each JSON object describing a mount takes about 500 bytes, but is stored in compressed form at a typical cost of about 75 bytes. Each of (1) auth mounts, (2) secret engine mount points, (3) local-only auth methods, and (4) local-only secret engine mounts are stored separately, so the limit applies to each independently.
Integrated storage default (1 MiB) | |
---|---|
Maximum number of secret engine mount points | ~14000 |
Maximum number of enabled auth methods | ~14000 |
Maximum mount point length | no enforced limit |
Specifying distinct per-mount options, or using long mount point paths, can increase the space required per mount.
The number of mount points can be monitored by reading the
sys/auth
and
sys/mounts
endpoints from the root namespace and
similar sub-paths for namespaces respectively, like: namespace1/sys/auth
,
namespace1/sys/mounts
, etc.
Alternatively, use the
vault.core.mount_table.num_entries
and
vault.core.mount_table.size
telemetry metrics to monitor the number of mount points and size of each mount table.
Namespace limits
The entire list of namespaces must fit in a single storage
entry. However, the effective limit is generally much smaller because each
namespace must have at least two secret engine mounts (for sys
and identity
),
one local secret engine (cubbyhole
) and one auth engine mount (token
).
Integrated storage default (1 MiB) | |
---|---|
Maximum number of namespaces | ~7000 |
Maximum number of namespaces with one additional secret engine per namespace | ~4600 |
Maximum nesting depth for namespaces | ~220 |
The maximum nesting depth calculation assumes a cost of 40 bytes per namespace path element. 160 nested paths = 160 namespaces ranging from 40 bytes to 6400 bytes.
The number of namespaces can be monitored by querying
sys/namespaces
.
To estimate the number of namespaces that can be created, divide the mount
point limit by the larger of the number of auth mounts per namespace
(including ns_token
) and the number of secret mounts per namespace
(including identity
and sys
.)
Entity and group limits
The metadata that may be attached to an identity entity or an entity group has the following constraints:
Limit | |
---|---|
Number of key-value pairs in metadata | 64 |
Metadata key size | 128 bytes |
Metadata value size | 512 bytes |
OpenBao shards the entities across 256 storage entries. This creates a hard limit of 256MiB on integrated storage with its default settings. Entity aliases are stored inline in the Entity objects and so consume the same pool of storage. Entity definitions are compressed within each storage entry, and the pre-compression size varies with the number of entity aliases and the amount of metadata. Minimally-populated entities about 200 bytes after compression.
Group definitions are stored separately, in their own pool of 256 storage entries. The size of each group object depends on the number of members and the amount of metadata. Group aliases and group membership information is stored inline in each Group object. A group with no metadata, holding 10 entities, will use about 500 bytes per group. A group holding 100 entities would instead consume about 4,000 bytes.
The following table shows a best-case estimate and a more conservative estimate for entities and groups. The number is slightly less than the amount that fits in one shard, to reflect the fact that the first shard to fill up will start inducing failures. This maximum will decrease if each entity has a large amount of metadata, or if each group has a large number of members.
Integrated storage default (1 MiB) | |
---|---|
Maximum number of identity entities (best case, 200 bytes per entity) | ~1,250,000 |
Maximum number of identity entities (conservative case, 500 bytes per entity) | ~480,000 |
Maximum number of identity entities (maximum permitted metadata, 41160 bytes per entity) | 2,400 |
Maximum number of groups (10 entities per group) | ~480,000 |
Maximum number of groups (100 entities per group) | ~50,000 |
Maximum number of members in a group | ~23,000 |
The number of entities can be monitored using OpenBao's telemetry; see vault.identity.num_entities
(total) or vault.identity.entities.count
(by namespace).
The cost of entity and group updates grows as the number of objects in
each shard increases. This cost can be monitored via the
vault.identity.upsert_entity_txn
and
the vault.identity.upsert_group_txn
metrics.
Very large internal groups should be avoided (more than 1000 members), because the membership list in a group must reside in a single storage entry. Instead, consider using external groups or split the group up into multiple sub-groups.
Token limits
One storage entry is used per token; there is thus no upper bound on the number of active tokens. There are no restrictions on the token metadata field, other than the entire token must fit into one storage entry:
Limit | |
---|---|
Number of key-value pairs in metadata | no limit |
Metadata key size | no limit |
Metadata value size | no limit |
Total size of token metadata | 512 KiB |
Policy limits
The maximum size of a policy is limited by the storage entry size. Policy lists that appear in tokens or entities must fit within a single storage entry.
Integrated storage default (1 MiB) | |
---|---|
Maximum policy size | 1 MiB |
Maximum number of policies per namespace | no limit |
Maximum number of policies per token | ~28,000 |
Maximum number of policies per entity or group | ~28,000 |
Each time a token is used, OpenBao must assemble the collection of
policies attached to that token, to the entity, to any groups that the
entity belongs to, and recursively to any groups that contain those groups.
Very large numbers of policies are possible, but can cause OpenBao’s
response time to increase. You can monitor the
vault.core.fetch_acl_and_token
metric to determine if the time required to assemble an access control list
is becoming excessive.
Versioned key-value store (kv-v2 secret engine)
Limit | |
---|---|
Number of secrets | no limit, up to available storage capacity |
Maximum size of one version of a secret | slightly less than one storage entry (512 KiB or 1024 KiB) |
Number of versions of a secret | default 10; configurable per-secret or per-mount |
Maximum number of versions (not checked when configured) | at least 24,000 |
Each version of a secret must fit in a single storage entry; the key-value pairs are converted to JSON before storage.
Version metadata consumes 21 bytes per version and must fit in a single storage entry, separate from the stored data.
Each secret also has version-agnostic metadata. This data can contain a custom_metadata
field of
user-provided key-value pairs. OpenBao imposes the following custom metadata limits:
Limit | |
---|---|
Number of custom metadata key-value pairs | 64 |
Custom metadata key size | 128 bytes |
Custom metadata value size | 512 bytes |
Transit secret engine
The maximum size of a Transit ciphertext or plaintext is limited by OpenBao's maximum request size, as described below.
All archived versions of a single key must fit in a single storage entry. This limit depends on the key size.
Key length | Integrated storage default (1 MiB) |
---|---|
aes128-gcm96 keys | 4017 |
aes256-gcm96 keys | 3731 |
chacha-poly1305 keys | 3731 |
ed25519 keys | 2841 |
ecdsa-p256 keys | 1635 |
ecdsa-p384 keys | 1318 |
ecdsa-p523 keys | 1078 |
1024-bit RSA keys | 333 |
2048-bit RSA keys | 233 |
4096-bit RSA kyes | 178 |
Other limits
Request size
The maximum size of an HTTP request sent to OpenBao is limited by
the max_request_size
option in the listener stanza. It defaults to 32 MiB. This value, minus the overhead of
the HTTP request itself, places an upper bound on any Transit operation,
and on the maximum size of any key-value secrets.
Request duration
The maximum duration of an OpenBao operation is
max_request_duration
, which defaults to
90 seconds. If a particular secret engine takes longer than this to perform an
operation on a remote service, the OpenBao client will see a failure.
The environment variable VAULT_CLIENT_TIMEOUT
sets a client-side maximum duration as well,
which is 60 seconds by default.
Lease limits
A systemwide maximum TTL, and a maximum TTL per mount point can be configured.
Although no technical maximum exists, high lease counts can cause degradation in system performance. We recommend short default time-to-live values on tokens and leases to avoid a large backlog of unexpired leases, or a large number of simultaneous expirations.
Limit | |
---|---|
Maximum number of leases | advisory limit at 256,000 |
Maximum duration of lease or token | 768 hours by default |
The current number of unexpired leases can be monitored via the
vault.expire.num_leases
metric.
External plugin limits
The plugin system launches a separate process initiated by OpenBao that communicates over RPC. For each secret engine and auth method that's enabled as an external plugin, OpenBao will spawn a process on the host system. For the Database Secrets Engines, external database plugins will spawn a process for every configured connection.
Regardless of plugin type, each of these processes will incur resource overhead on the system, including but not limited to resources such as CPU, memory, networking, and file descriptors. There's no specific limit on the number secrets engines, auth methods, or database configured connections that can be enabled. This ultimately depends on the particular plugin resource utilization, the extent to which that plugin is being called, and the available resources on the system. For plugins of the same type, each additional process will incur a roughly linear increase in resource utilization. This assumes the usage of each plugin of the same type is similar.