Calculating billing
Overview
This topic explains how LaunchDarkly calculates billing for your account.
LaunchDarkly calculates your billing based on different aspects of your system usage. Depending on your billing model, you may be billed for more than one of the account usage metrics displayed on the Usage page.
For example, Foundation, Enterprise, and Guardian plans can include monthly entitlements for client-side MAU, service connections, and Experimentation keys.
LaunchDarkly will bill you at the beginning of each month for any usage in excess of these entitlements from the prior month. Throughout each month, LaunchDarkly sends an email notification to your account owner and your account’s billing contact when your overage balance exceeds various dollar amounts.
Client-side monthly active users (MAU)
MAU was previously called "primary contexts"
Previously, we used “primary contexts” to determine costs and billing. As of December 19, 2024 we have updated the name of this billing metric to “MAU.” Your usage charts on the Usage page have been updated to reflect this name change, but there was no change to your billing or pricing.
MAU is the number of unique monthly active users who encounter LaunchDarkly client-side SDKs. For most customers, we use client-side monthly active users (MAU) to help determine your bill every month.
Your usage is based on the total number of unique client-side MAU across your entire account. Uniqueness is defined by unique context key
s. If you change an existing context’s key, LaunchDarkly considers the new context unique and counts it as an additional MAU. Custom attributes do not affect uniqueness.
If you subscribe to a LaunchDarkly plan, you commit to a certain number of unique MAU each month.
Client-side MAU for context kinds other than user
For most LaunchDarkly customers, MAU is the number of client-side monthly active user
s.
The majority of LaunchDarkly customers use the user
context kind the most. However, if your greatest-used context kind is something other than user
, then your MAU is calculated based on that kind. For example:
- If you use 2,000,000
users
and 500,000devices
, your MAU will be 2,000,000, based onuser
. - If you use 2,000,000
users
and 4,000,000devices
, your MAU will be 4,000,000, based ondevice
.
Client-side MAU limits
The LaunchDarkly plan you subscribe to may include a client-side MAU limit. We understand that a company’s customer base can grow unexpectedly over time. We never stop or throttle service if you exceed your client-side MAU limit. All contexts will continue to receive feature flags correctly, regardless of the amount of your client-side MAU.
Context instances live on the Contexts list for 30 days from their last evaluation, or until the environment reaches 3,000,000 context instances. To learn more, read Context storage.
If you have configured LaunchDarkly to use anonymous contexts, that can impact your client-side MAU as well. To learn more, read Manage anonymous contexts.
To learn more about your client-side usage billing model, contact your LaunchDarkly representative.
Service connections
Some customers are billed by service connections. A service connection is one instance of one server-side SDK connected to one LaunchDarkly environment for a time period measured in minutes. To learn more, read Service connections.
If you subscribe to a LaunchDarkly plan, you commit to a certain number of service connections each month. LaunchDarkly will also bill you at the beginning of each month for any usage in excess of these prepaid entitlements from the prior month. You can change your monthly entitlements from the Billing page. To learn more, read The Billing page.
Experimentation keys
Some customers are billed by Experimentation keys.
Experimentation keys include the total number of unique context keys, from server-side, client-side, AI, and edge SDKs, included in each experiment:
- if the same context key is in one experiment multiple times, LaunchDarkly counts it as one Experimentation key
- if the same context key is in two different experiments, LaunchDarkly counts it as two Experimentation keys
Your total usage of Experimentation keys measures how many contexts you are targeting in your experiments.
If you subscribe to a LaunchDarkly plan, you commit to a certain number of Experimentation keys each month. LaunchDarkly will also bill you at the beginning of each month for any usage in excess of these prepaid entitlements from the prior month. You can change your monthly entitlements from the Billing page. To learn more, read The Billing page.
For some annual billing plans, you commit to a certain number of Experimentation keys each month. If you consistently go over your plan limits, averaged over a quarter, we will “true forward” your contract based on your actual average use. To learn more about your Experimentation billing plan, contact your LaunchDarkly representative.
Identifying causes of unexpected high bills
Billing issues can be complex and unique to your account. As a best practice, we recommend taking questions about your LaunchDarkly bill to your LaunchDarkly representative.
However, customers on Foundation plans or who otherwise do not have access to a LaunchDarkly representative may find it helpful to understand how to investigate unexpected high bills. A common cause of unexpected high bills is incorrectly implemented SDKs. In almost all cases, we recommend that you implement SDKs in a singleton pattern.
Symptoms of not following the singleton pattern
An incorrectly implemented SDK can result in a number of different symptoms. Common symptoms include:
- Large number of service connections
- Increased CPU or memory usage
- Frequent connectivity errors, such as connection timeouts or dropped connections
- Experiments missing events
- Flags reflecting default or stale values because they are unable to connect to LaunchDarkly
Correctly implementing the singleton pattern
Here are some best practices for correctly implementing the singleton pattern:
- Create a singleton for the SDK and make sure it’s reused throughout your application.
- Inject the singleton into dependent classes, or pass it explicitly, rather than instantiating it directly.
- Centralize SDK initialization so you initialize one time, during application setup, and reuse the SDK client through the lifecycle.
- Lazy load safely. In some SDKs, the initialization method returns a promise. Make sure to either set your
client
variable to the actual initialized SDK client, or wait for the promise to resolve.
Identifying incorrect SDK implementations
There are two common coding patterns that result in the unintentional creation of multiple SDK instances. These patterns are:
- Over-instantiation: In this situation, you unintentionally create multiple instances. This can lead to inflated service connection costs and may contribute to performance issues as you scale.
- Runaway instantiation: In this situation, you unintentionally create new instances throughout the lifespan of your application. This can lead to explosive service connection costs and nearly always cause performance issues, regardless of scale.
Examples of over-instantiation include:
- Instantiating in multiple classes. In this case, each service creates its own SDK instance, which results in multiple unnecessary connections.
- Improperly implemented lazy loading. In some SDKs, the
initLDClient
function returns a promise. If you use a helper method to setldClient
to that promise rather than to the actual initialized SDK client, then you can end up with multiple SDK instances by making multiple calls to your helper method before the firstinitLDClient
call resolves. This can lead to unexpected behavior or resource overuse. This asynchronous gap can also cause problems in applications where proper initialization and single-instance management of the SDK are critical. The SDK is designed to be initialized once per application instance, so it is important to ensure proper lazy loading without redundant initializations.
Examples of runaway instantiation include:
- Instantiating inside a loop or recurring function. In this case, each iteration of the loop or function creates a new SDK instance, which results in a large number of unnecessary connections.
- Instantiating in a request handler or other short-lived context. In this case, a new SDK instance is created for each request, which results in a large number of unnecessary connections.