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 operation

  • ANJ_COAP_WITH_UDP - enables CoAP over UDP

  • ANJ_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 connections

  • ANJ_NET_WITH_DTLS - enables DTLS transport

  • ANJ_WITH_MBEDTLS - enables built-in MbedTLS integration (you can provide a custom TLS backend if needed)

Bootstrap support

  • ANJ_WITH_BOOTSTRAP - enables the Bootstrap Interface

  • ANJ_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 mode

  • ANJ_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 Pull

  • ANJ_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 operation

  • ANJ_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 numbers

  • ANJ_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 operations

  • ANJ_WITH_OBSERVE_COMPOSITE - enables Observe-Composite and Cancel-Composite operations

  • ANJ_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 decoder

  • ANJ_WITH_CBOR - CBOR encoder/decoder (content-format 60) - rarely used

  • ANJ_WITH_LWM2M_CBOR - LwM2M CBOR encoder/decoder (content-format 11544) - SenML CBOR is generally preferred

  • ANJ_WITH_CUSTOM_CONVERSION_FUNCTIONS - replaces sprintf/sscanf with minimal converters This can be useful in very resource-constrained environments, since linking the standard stdio 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.