6. Configuration and Build Size Impact
Anjay Lite is highly configurable at build time. By enabling or disabling specific compile-time flags, you can reduce the footprint for constrained environments or enable advanced features such as FOTA or Composite operations.
This document summarizes the most important configuration options, grouped by category. Use it as a practical guide for setting up your client.
Note
The main way to configure Anjay Lite is by providing your own
anj/anj_config.h
file with the desired set of flags.
When using CMake, this header can also be generated automatically during the
build.
6.1. Configuration
6.1.1. Minimal configuration
These enabler flags are enough to create a basic LwM2M client that connects to a server and supports standard operations on the Data Model, including the Client Registration Interface and the Device Management and Service Enablement Interface (without composite operations).
ANJ_WITH_DEFAULT_SECURITY_OBJ
- enables the built-in Security Object (/0)ANJ_WITH_DEFAULT_SERVER_OBJ
- enables the built-in Server Object (/1)ANJ_WITH_DEFAULT_DEVICE_OBJ
- enables the built-in Device Object (/3)ANJ_WITH_DISCOVER
- enables support for the Discover operationANJ_COAP_WITH_UDP
- enables CoAP over UDPANJ_WITH_SENML_CBOR
- enables SenML CBOR as a payload format
SenML CBOR is the most complete content format, supporting composite operations, timestamps in Send messages and notifications. It can replace any other format.
Note
In addition to these feature flags, you also need to configure the compatibility layers. For example, if you want to run a minimal client on a POSIX system, define:
#define ANJ_WITH_TIME_POSIX_COMPAT
#define ANJ_WITH_RNG_POSIX_COMPAT
#define ANJ_WITH_SOCKET_POSIX_COMPAT
#define ANJ_NET_WITH_IPV4
#define ANJ_NET_WITH_UDP
Also note that all numeric configuration options (such as buffer sizes, and limits for objects, observations, or attributes) directly affect RAM usage. Memory footprint considerations are covered later in this document.
6.1.2. Commonly used
Most production deployments require additional features beyond the minimal configuration. These options significantly improve interoperability with real-world LwM2M servers, enable more robust operation, and cover scenarios that almost every deployment requires in practice.
Security
ANJ_WITH_SECURITY
- enables support for secure connectionsANJ_NET_WITH_DTLS
- enables DTLS transportANJ_WITH_MBEDTLS
- enables built-in MbedTLS integration (you can provide a custom TLS backend if needed)
Bootstrap support
ANJ_WITH_BOOTSTRAP
- enables the Bootstrap InterfaceANJ_WITH_BOOTSTRAP_DISCOVER
- enables Bootstrap Discover operation, not all servers require it
Caching
ANJ_WITH_CACHE
- enables response caching to prevent processing retransmitted UDP messages multiple times.
Warning
Caching is essential for reliable operation over UDP. Without it, retransmitted messages may be processed multiple times, leading to duplicate operations and inconsistent state.
Content formats and CBOR extensions
You can often configure or enforce the preferred formats on the server side. If you are not certain how your server encodes messages, it is generally safer to enable the additional CBOR decoder extensions so that the client can handle a wider range of payloads.
ANJ_WITH_PLAINTEXT
- allows plaintext encoding for single resources.ANJ_WITH_OPAQUE
- used in FOTA Push modeANJ_WITH_CBOR_DECODE_DECIMAL_FRACTIONS
ANJ_WITH_CBOR_DECODE_HALF_FLOAT
ANJ_WITH_CBOR_DECODE_INDEFINITE_BYTES
ANJ_WITH_CBOR_DECODE_STRING_TIME
Firmware Update (FOTA)
ANJ_WITH_DEFAULT_FOTA_OBJ
- enables the built-in Firmware Update Object (/5)ANJ_FOTA_WITH_PUSH_METHOD
- enables firmware delivery via PUSH (Write operation)ANJ_FOTA_WITH_PULL_METHOD
- enables firmware delivery via PULL (download)
6.1.3. Additional features
Beyond the minimal and recommended configurations, Anjay Lite provides a number of additional features that can be enabled depending on the needs of your application.
CoAP Downloader
ANJ_WITH_COAP_DOWNLOADER
- generic CoAP/CoAPS downloader used by FOTA PullANJ_FOTA_WITH_COAPS
/ANJ_FOTA_WITH_COAP
- transport options for firmware downloads
Persistence
ANJ_WITH_PERSISTENCE
- allows storing Security and Server object state to a non-volatile storage. See tutorial for details.
Information Reporting Interface
ANJ_WITH_LWM2M_SEND
- enables the LwM2M Send operationANJ_WITH_OBSERVE
- enables Observation support
Logging
Anjay Lite has flexible logging options. Check out the article for details. The most relevant flags are:
ANJ_LOG_FULL
- full log mode with file and line numbersANJ_LOG_LEVEL_DEFAULT
- sets the default log level (can be overridden per-module)
6.1.4. Optional / advanced
Some options are rarely needed but can be enabled for specific scenarios:
ANJ_WITH_COMPOSITE_OPERATIONS
- enables Composite Read and Composite Write operationsANJ_WITH_OBSERVE_COMPOSITE
- enables Observe-Composite and Cancel-Composite operationsANJ_WITH_DISCOVER_ATTR
- reports attributes in Discover responses In practice this is rarely needed, because Discover is usually performed right after Register, which in turn forces the server to reapply attributes using Write-Attributes.ANJ_WITH_EXTERNAL_CRYPTO_STORAGE
- integration with external secure key storage (e.g., HSM)ANJ_WITH_EXTERNAL_DATA
- use external data sources (see tutorial for details)ANJ_WITH_LWM2M12
enables selected features from the LwM2M 1.2 specification It adds support for new attributes (edge, con, hqmax), extends the Server Object with a default notification mode resource, and allows passing attributes directly in Observe requests instead of separate Write-Attributes. Although LwM2M CBOR is formally defined in 1.2, Anjay Lite makes it available regardless of the negotiated version.ANJ_WITH_TLV
- legacy TLV decoderANJ_WITH_CBOR
- CBOR encoder/decoder (content-format 60) - rarely usedANJ_WITH_LWM2M_CBOR
- LwM2M CBOR encoder/decoder (content-format 11544) - SenML CBOR is generally preferredANJ_WITH_CUSTOM_CONVERSION_FUNCTIONS
- replacessprintf
/sscanf
with minimal converters This can be useful in very resource-constrained environments, since linking the standardstdio
conversion functions may add more than 20 kB of extra code size overhead.
6.2. Library size impact
To better understand how each module affects the final footprint, we measured binary sizes when building the Anjay Lite Bare-Metal Client with various configurations. Size analysis was performed with puncover.
Note that puncover does not include data from the .rodata section (i.e., const variables), so these values were manually extracted and added to the overall result to provide a complete representation of the final memory footprint.
The build environment was:
Compiler:
arm-none-eabi-gcc-14.2.1
Anjay Lite version:
1.0.0
Build type:
RelWithDebInfo
(-DCMAKE_BUILD_TYPE=RelWithDebInfo
)
Note
The sizes include Anjay Lite core and built-in modules
without external integration layers.
An exception is the default MbedTLS DTLS integration layer
(anj_mbedtls_dtls_socket.c
), which is included in the measurements,
but the full MbedTLS library itself is not.
For details about its size and configuration, refer to the
MbedTLS repository.
Actual numbers depend on compiler version, optimization flags and enabled modules. These measurements should be treated as a guideline only.
Important
Building with the MinSizeRel
configuration typically reduces the final
binary size by around 5% compared to RelWithDebInfo
.
However, we do not use this configuration for size breakdowns in this
document, because it prevents accurate estimation of the size of individual components.
6.2.1. Overall size depending on enabled modules
Approximate binary sizes (in kilobytes) with logs disabled:
Configuration |
Size [kB] |
---|---|
Minimal build (must-have only) |
33.2 |
Security (PSK) - MbedTLS not included |
+ 1.7 |
Bootstrap support |
+ 4.4 |
Caching mechanism |
+ 1.2 |
FOTA |
+ 1.3 |
Additional recommended content-formats (Plaintext + Opaque + CBOR extensions) |
+ 5.8 (2.8 + 0.6 + 2.4) |
Minimal build + all commonly used options |
47.6 |
LwM2M Send |
+ 0.9 |
Observations |
+ 5.4 |
Persistence |
+ 0.8 |
CoAP Downloader |
+ 1.7 |
Minimal build + all commonly used options + all additional options (excluding logs) |
56.4 |
All of the above + LwM2M 1.2 + TLV + LwM2M CBOR + CBOR + composite operations + discover attr. |
65.5 |
6.2.2. Impact of logging
Logging has a measurable impact on final binary size. The table below shows how much the size increases when enabling logs at different levels.
Note
The absolute size increase depends on which modules are enabled, since each of them may add its own log messages. For this reason, the percentage growth is often a better metric to consider when evaluating the impact of logging on your build.
Build variant |
Error logs only [kB] |
Error, warning and info logs [kB] |
Full logs [kB] |
---|---|---|---|
Minimal build |
+ 7.3 (~22%) |
+ 9.7 (~29%) |
+ 12.1 (~36%) |
Minimal build + all commonly used options + all additional options |
+ 13.2 (~23%) |
+ 15.2 (~27%) |
+ 19.1 (~34%) |
6.2.3. Static RAM usage
In addition to flash size, Anjay Lite also consumes a certain amount of static RAM.
Unlike many libraries, Anjay Lite does not use dynamic memory allocation - no heap is required.
All larger buffers and data structures are allocated within the main context anj_t
or within object instances.
If these objects are declared as static, they do not increase stack usage.
The table below shows approximate static RAM allocations for the core context and built-in objects for a minimal configuration with security, caching and observations enabled.
Component |
RAM usage [B] |
Flags affecting size |
---|---|---|
anj_t core context |
7816 |
— |
-> Incoming messages buffer |
1200 |
ANJ_IN_MSG_BUFFER_SIZE |
-> Outgoing messages buffer |
1200 |
ANJ_OUT_MSG_BUFFER_SIZE |
-> Outgoing payload buffer |
1024 |
ANJ_OUT_PAYLOAD_BUFFER_SIZE |
-> Caching payload buffer |
1024 |
ANJ_OUT_PAYLOAD_BUFFER_SIZE |
-> Observations array |
10*120 |
ANJ_OBSERVE_MAX_OBSERVATIONS_NUMBER |
-> Attributes array |
10*64 |
ANJ_OBSERVE_MAX_WRITE_ATTRIBUTES_NUMBER |
Security Object (/0) instance |
1040 |
— |
-> Public key buffer |
2*64 |
ANJ_SEC_OBJ_MAX_PUBLIC_KEY_OR_IDENTITY_SIZE |
-> Server public key buffer |
2*64 |
ANJ_SEC_OBJ_MAX_SERVER_PUBLIC_KEY_SIZE |
-> Secret key buffer |
2*64 |
ANJ_SEC_OBJ_MAX_SECRET_KEY_SIZE |
Server Object (/1) instance |
152 |
— |
Device Object (/3) instance |
60 |
— |
To reduce memory footprint, you should primarily focus on adjusting:
buffer sizes (
ANJ_IN_MSG_BUFFER_SIZE
,ANJ_OUT_MSG_BUFFER_SIZE
, etc.),maximum record counts (
ANJ_OBSERVE_MAX_OBSERVATIONS_NUMBER
for observations number, etc.).
6.3. Summary
Anjay Lite’s configuration system is highly modular, allowing you to tailor the client to very constrained environments or full-featured production use cases. Start with a minimal setup, add features as required by your deployment, and balance functionality against memory and binary size constraints. Careful selection of enabled modules ensures both efficiency and long-term maintainability of your solution.