bitwarden/server
Application cache
Active contributors: platform team.
Purpose
IApplicationCacheService is an in-process cache of frequently-read, slowly-changing data — most notably organization abilities and provider abilities. It is held per-pod (so a single in-process dictionary can answer the question "is this org enabled / has it got SSO / is it in trial / does it accept Secrets Manager?") and invalidated cluster-wide via a Service Bus topic when an update happens elsewhere.
Directory layout
src/Core/Services/
├── IApplicationCacheService.cs # interface
└── Implementations/
├── InMemoryApplicationCacheService.cs # default
└── InMemoryServiceBusApplicationCacheService.cs # cloud / cluster-aware
src/Core/HostedServices/
└── ApplicationCacheHostedService.cs # Service Bus subscriber that invalidates the cacheKey abstractions
| Type | Description |
|---|---|
IApplicationCacheService |
GetOrganizationAbilitiesAsync(), GetProviderAbilitiesAsync(), UpsertOrganizationAbilityAsync(...), DeleteOrganizationAbilityAsync(...). |
InMemoryApplicationCacheService |
Self-host default. Reads abilities from the DB on first use; updates are mutated locally. |
InMemoryServiceBusApplicationCacheService |
Cloud default. Same as above but every mutation also publishes to a Service Bus topic so other pods refresh. |
ApplicationCacheHostedService |
Subscribes to the Service Bus topic and applies received messages locally. |
OrganizationAbility (src/Core/Services/Implementations/OrganizationAbility.cs) |
The cached struct: ID, plan type, seat usage, enabled flags, business info — derived from the Organization row. |
How it works
sequenceDiagram
participant Api as Api / other host (write)
participant Cache as Local IApplicationCacheService
participant Bus as Service Bus topic
participant Other as Other host instances
Api->>Cache: UpsertOrganizationAbilityAsync(orgId)
Cache->>Cache: Update local dict
Cache->>Bus: publish "OrgUpdated"
Bus->>Other: deliver
Other->>Other: ApplicationCacheHostedService appliesApplicationCacheHostedService is registered in Api.Startup, Identity.Startup, and the other long-running hosts when globalSettings.ServiceBus.ConnectionString is configured.
Why this matters
Reading the Organization row on every request would generate enormous load on the database — every cipher endpoint must check seat limits, plan features, and policy flags. Holding the abilities in-memory makes those checks essentially free. The Service Bus topic ensures that a plan change in one pod is visible to every other pod within seconds.
Entry points for modification
- Add a new field to abilities → extend
OrganizationAbility(and the equivalent provider class), updateInMemoryApplicationCacheServiceto hydrate it from the DB, update the Service Bus message contract. - Move a new entity into the cache → introduce a new ability type and an additional
Get/Upsertmethod onIApplicationCacheService. - Skip the Service Bus dependency for a self-host scenario → the
InMemoryApplicationCacheServiceis already used when the bus is not configured.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.