All notable changes to the LaunchDarkly Erlang/Elixir SDK will be documented in this file. This project adheres to Semantic Versioning.
3.9.0 (2026-02-09)
- Fix an issue where <<kind>> would be included in the list of context kinds when kind was binary. (#168) (8cdee5c)
3.8.1 (2025-11-12)
- Handle connection errors during read operations. (#163) (5838c2b)
- Handle redis errors during mutations. (#165) (9dbe853)
- Prevent uninitialized SDK warning in daemon mode. (#162) (0961922)
- Redact SDK in gen_server descriptions and network errors. (#166) (3a4e005)
3.8.0 (2025-08-08)
- Update minimum OTP version to 24. (82f0e77)
- Fix issue where sometimes a dropped stream would not reconnect. (82f0e77)
3.7.2 (2025-06-25)
3.7.1 (2025-06-03)
3.7.0 (2025-05-08)
3.6.0 (2025-03-17)
- Add support for setting the redis username when using redis persistence. (#142) (c37fefd)
- Update certifi to 2.14.0 (#144) (69771cf)
3.5.0 (2024-11-07)
3.4.0 (2024-10-24)
- Add support for client-side prerequisite events. (167308a)
- Add support for client-side visibility for all_flags_state. (167308a)
- Use ets for last-known server-time. (#136) (568ac51)
3.3.1 (2024-09-23)
3.3.0 (2024-05-20)
3.2.0 (2024-03-14)
- Always inline contexts for feature events (#119) (e5c6cc4)
- Redact anonymous attributes within feature events (#120) (d334861)
3.1.0 (2024-01-04)
3.0.4 (2023-12-04)
3.0.3 (2023-11-17)
3.0.2 (2023-11-16)
- Update certifi dependency to 2.12.0 (b0c5e56)
3.0.1 (2023-09-26)
3.0.0 (2023-09-14)
Version 3.0 requires Gun 2.x. There are no changes to the Erlang SDK API or functionality. However, version 3.0 now requires Gun 2.x.
If your application depends directly on Gun, or if you have other dependencies that use Gun, then you must ensure that they work with Gun 2.x.
- Upgrade to support Gun 2.x (#99)
2.1.2 (2023-08-24)
- Update to
eredisversion1.7.1.
- Fixed
ldclient_instance:options()to include newredis_tlsoption. Only specs affected.
- A new configuration option,
redis_tls, for configuring TLS settings for redis. When this option is omitted Redis will not use TLS. When specified it should contain a list ofssl:tls_option(). These options will be forwarded toeredis.
- Upgraded
yamerlto version0.10.0.
- Remove error log message associated with debugging redis initialization state.
- Add missing
boolean()type to theldclient_context:attribute_value()definition.
- Fixed an issue that would prevent using values from redis for
variationorall_flags_statecalls before client initialization was complete. After this change if the erlang SDK is using an initialized redis prefix, then it will be able to evaluate against that store before initialization is complete. Note that the SDK did not previously store the$initedkey used when detecting that a store is initialized, so the store will need updated by this SDK version (or newer) at least once before it would be considered initialized.
- Fixed an issue where invalid contexts would generate events resulting in a crash in the event server.
The latest version of this SDK supports LaunchDarkly's new custom contexts feature. Contexts are an evolution of a previously-existing concept, "users." Contexts let you create targeting rules for feature flags based on a variety of different information, including attributes pertaining to users, organizations, devices, and more. You can even combine contexts to create "multi-contexts."
For detailed information about this version, please refer to the list below. For information on how to upgrade from the previous version, please read the migration guide.
- Added a new module,
ldclient_context, which defines the new "context" model. - All SDK methods that took an
ldclient_user:user()now accept anldclient_context:context()as well. - Added
ldclient_flagbuilder:if_match/4,ldclient_flagbuilder:if_not_match/4,ldclient_flagbuilder:and_match/4, andldclient_flagbuilder:and_not_match/4which allow creating rules targeting specific context kinds usingldclient_testdata.
- The secondary meta-attribute, which previously affected percentage rollouts, no longer exists. If you set an attribute with that name in
ldclient_context:context(), it will simply be a custom attribute like any other. - Evaluations now treat the anonymous attribute as a simple boolean, with no distinction between a false state and an undefined state.
- The
binary()values inprivate_attributesin the configuration map now represent attribute references. If an attribute name had started with a/, then that will need to be escaped. For instance/myAttributewould now reference an attribute namedmyAttributenot an attribute named/myAttribute. The attribute reference would need to be updated to the escaped form/~1myAttribute. ldclient_flagbuilder:variation_for_all_usershas been replaced withldclient_flagbuilder:variation_for_alland now applies to contexts.ldclient_flagbuilder:variation_for_userhas been replaced withldclient_flagbuilder:variation_for_contextand requires a context kind to be provided.user_keys_capacityhas been replaced withcontext_keys_capacityin the option configuration map.
- The SDK can now evaluate segments that have rules referencing other segments.
- Analytics event data now uses a new JSON schema due to differences between the context model and the old user model.
- Removed the
secondarymeta-attribute inldclient_user:user(). - The
ldclient:aliasmethod no longer exists because alias events are not needed in the new context model. - The
inline_users_in_eventsoption no longer exists because it is not relevant in the new context model.
applicationoption, for configuration of application metadata that may be used in LaunchDarkly analytics or other product features. This does not affect feature flag evaluations.
ldclient:start_instance("sdk-key", #{
application => #{
id => <<"my-app-id">>,
version => <<"my-app-version">>
}
})
- Added support for using server time, from response headers, when determining if debug events should be sent.
- Updated jitter/backoff implementation to be consistent with other SDK implementations.
- Upgraded
lruto version2.4.0. - Upgrade
certifito version2.10.0. - Removed dependency on
backoff.
- Fixed an issue where the SDK did not handle deleted flags/segments correctly in combination with evaluation of all flags.
- Allow for track data to be
null.
- Updated
certifito 2.9.0. - Updated
shotgunto 0.5.3. This should obviate the need to overrideshotguninmix.exsfor Elixir projects.
- Updated URI parsing to work with OTP 25. Removing the usage of
http_uri:parseand replacing it withuri_string:parse.
ldclient:all_flags_state/3to be used instead ofldclient:all_flags_state/1 or /2if you are passing flag data to the front end for use with the JavaScript SDK. It preserves some flag metadata that the front end requires in order to send analytics events correctly. It does NOT yet support selecting client-side-enabled flags.ldclient_testdatais a new way to inject feature flag data programmatically into the SDK for testing—either with fixed values for each flag, or with targets and/or rules that can return different values for different users. Unlike the file data source, this mechanism does not use any external resources, only the data that your test code has provided.- Support for the SDK test harness.
- An issue with handling
firstNameandlastNamein rules. The SDK usesfirst_nameandlast_nameatoms for these fields and there was an issue with when the attribute names were converted. Now name conversion for attributes are done after evaluation and processing of private attributes. ldclient:trackandldclient:tack_metricwill not allow for types other thanmap()to be used fordata.- The SDK was sending identify events for users with an empty key when it should not.
- The SDK would send duplicate events for a user which had been identified and then was noticed by a feature evaluation. Now the event will be de-duplicated correctly within the LRU cache timeout.
- Rule matches against dates in the user object, which could not be parsed, would cause evaluation to fail and return the default value. Now they will correctly result in the rule not matching instead.
- The configuration was not trimming trailing
/from URLs.
- Event fields which contained false or null will not generally be omitted from events for compactness.
- Clarifications to documentation.
- The file
file_auto_updatefeature was not working correctly. If the flag files did not contain any changes between polling intervals, then the file system watcher would crash. (Thanks, matt-glover!)
- Updated the
options()typings forldclient_instance:startto include missing configuration options. These included redis configuration, ld relay configuration, cache ttl, file data source configuration, and the http options. This is not a functionality change, but will correct issues reported by the dialyzer.
-
Support for configuring HTTP options. Including:
- The ability to specify custom headers.
ldclient_config:parse_options("sdk-key", #{ http_options => #{ custom_headers => [ {"Basic-String-Header", "String"}, {"Binary-String-Header", "Binary"} ]} }),- The ability to specify a custom connect timeout.
ldclient_config:parse_options("sdk-key", #{ http_options => #{ connect_timeout => 2000 } }),- The ability to specify a custom TLS configuration.
The default behavior for OTP is to use
verify_nonefor TLS verification. If no configuration is specified, then the SDK will inherit this behavior.
ldclient_config:parse_options("sdk-key", #{ http_options => #{ %% This is a list of tls_client_options() %% https://www.erlang.org/doc/man/ssl.html#type-tls_client_option tls_options => ldclient_config:tls_basic_options() } }),- A number of TLS configuration helpers. A full TLS configuration can be specified, but these methods provide a number of basic configurations.
ldclient_config:tls_basic_options() -> [ssl:tls_client_option()]
Create a basic TLS configuration which will try to use a default location for certificate authority store. If that store is not present, then instead the configuration will use a certifi store which is a Rebar3 dependency.ldclient_config:tls_basic_linux_options() -> [ssl:tls_client_option()]Create a basic TLS configuration which will use a default location for a certificate store. If the store is not present, then it will produce an error.ldclient_config:tls_ca_certfile_options(CaStorePath :: string()) -> [ssl:tls_client_option()]Create a basic TLS configuration with the specified certificate store. If the store is not present, then it will produce an error.ldclient_config:with_tls_revocation(Options :: [ssl:tls_client_option()]) -> [ssl:tls_client_option()]Decorate a configuration with revocation checks. Currently revocation checks are not cached in OTP, so this will result in additional requests for each HTTP request.ldclient_config:tls_basic_certifi_options() -> [ssl:tls_client_option()]Create a basic TLS configuration which will use the certifi store specified in the Rebar3 dependencies.
- The SDK now supports the ability to control the proportion of traffic allocation to an experiment. This works in conjunction with a new platform feature now available to early access customers.
- The SDK now supports the ability to read flags from a file.
- When a rule was missing both the rollout and the variation, and that rule was matched, then variation 0 would be returned instead of the default value.
- When a fall-through was missing both a rollout and a variation, then null would be returned instead of the default value.
- The SDK now forces connections to use HTTP/1.1 instead of the newer HTTP/2 protocol as an underlying dependency does not yet support HTTP/2. This change does not impact current behavior as LaunchDarkly’s servers do not yet accept requests with HTTP/2; however, this SDK change ensures operational continuity when LaunchDarkly’s services enable HTTP/2 compatibility.
- The SDK is more resilient when opening an SSE connection, processing events from the stream, and evaluating feature flags.
- Updated the
eredisdependency to version1.4.0. (Thanks, jeffgrunewald!) - Updated the
jsxdependency to version3.1.0. (Thanks, bitwalker!) - Updated the
uuiddependency to version2.0.2. (Thanks, jeffgrunewald!) - Expanded test coverage to include OTP 24.
ldclient:alias/2andldclient:alias/3functions. These can be used to associate two user objects for analytics purposes with an alias event.
- Removed internal storage files from generated documentation.
Initial supported release of the SDK.
- Added Redis feature store.
- Added LDD mode.
- Reload in-memory flag data when storage server fails.
- Parse flags and segments before in-memory storage.
- Updated the default base URL to
sdk.launchdarkly.com. - Events URL path from
api/events/bulkto/bulk. - Renamed
ldclient_settingstoldclient_config. - Renamed
ldclient:track_with_metrictoldclient:track_metric. - Improved generated documentation.
- Ignore path in streaming put events.
- Removed
ldclient_settings. - Removed
ldclient:track_with_metric.
- Updaters now initialize asynchronously.
- Updated
shotgunfrom 0.4.0 to 0.5.0.
- Fixed
GenServercrash on socket close inhandle_castinldclient_event_dispatch_httpc.erl. - Fixed network timeout on initial connection.
- Fixed restarting updates after a crash.
- Fixed updater initialization state bugs.
- Added Erlang/OTP 23 image to CircleCI tests
- Fixed a bug preventing user first name and last name attibutes from properly being set
- Fixed dates in tests to be RFC3339 compliant
- Fixed dialyzer warning when application was started with
offlineoption - Fixed SSE parsing bug in shotgun library with a workaround
- Renamed
eldtoldclientto better adhere to LaunchDarkly SDK naming conventions. - Changed the
pkg_nametolaunchdarkly_server_sdk
-
Added offline mode which stops the SDK making remote calls to LaunchDarkly and variation calls will then fall back to default values for your feature flags. You can do this by setting offline mode in the config map with the
offlinekey. -
Added ETag polling cache for If-None-Match on update requests.
-
The SDK now specifies a uniquely identifiable request header when sending events to LaunchDarkly to ensure that events are only processed once, even if the SDK sends them two times due to a failed initial attempt.
-
Added an initialized function which indicates whether the SDK is in offline mode or if the update processor has been initialized.
-
Return last variation when user bucket exceeds variation weight sum.
-
Client now checks initialization status when evaluating a variation or all flags.
- Support for experimentation features. See
eld:track_with_metric/4-5.
- Custom URI configuration is now consistent with other SDKs
- Bucketing logic for custom non-string attributes is brought in line with the other SDKs
- Dependencies specify tagged versions and use hex (thank you @hez)
eld:all_flags_state/2now uses correct non-default instance (thank you @hez)- Streaming connection will now retry after initial request timeout
eld:evaluate/3-4which were deprecated in the previous versionerlang.mk,Makefilenow usesrebar3
- Support for all server side LaunchDarkly events
eld:variation/3-4andeld:variation_detail/3-4functions to replaceeld:evaluate/3-4to reflect the naming convention- Feature to inline users inside events
- Feature to define global private user attributes, including making all user attributes private
- Events POST URI, it no longer gets HTTP 405 Method Not Allowed error
eld:evaluate/3-4will be removed in a future release
- Polling support
- Known issues for some edge case error conditions, and other minor missing features
- Initial public release
- Support for streaming and evaluations
- Events don't pass integration tests
- Polling support
- Other known issues and minor missing features