Skip to main content

Full reference

Every table and key Andromeda reads, generated from the descriptor that andromeda configuration describe writes. It is always complete for the release the descriptor came from.

[server]​

The data-plane listener that serves the NGSI-LD API, and its HTTP/3 sibling.
[server]
host = "0.0.0.0"
port = 1056
transport = "plaintext"
# public_url = "https://broker.example.org/"
graceful_drain_timeout = "30s"
announced_close_timeout = "1s"
request_head_timeout = "30s"
idle_timeout = "3m"

server.host​

stringrestart to apply

The address the API listens on. The --host command-line flag overrides it.

Default
"0.0.0.0"
Environment variable
ANDROMEDA__SERVER__HOST

server.port​

positive integerrestart to apply

The TCP port the API listens on. The --port command-line flag overrides it.

Default
1056
Must be
0 < port
Also required
Environment variable
ANDROMEDA__SERVER__PORT

server.transport​

stringrestart to apply

Whether the API listener serves plaintext or terminates TLS with the [tls] certificate. One port speaks one or the other, never both.

Default
"plaintext"
Allowed values
"plaintext"Serves plaintext HTTP/1.1 and HTTP/2, for a deployment behind a reverse proxy or load balancer that terminates TLS. NGSI-LD calls plaintext HTTP not recommended.
"tls"Terminates TLS in the broker with the [tls] certificate and serves HTTP/1.1 and HTTP/2 over it.
Environment variable
ANDROMEDA__SERVER__TRANSPORT

server.public_url​

URLrestart to apply

The address clients and peers reach the API at, path prefix included, such as https://broker.example.org/context-broker. Every absolute URL the broker hands out is built on it, including stored @context URLs, and forwarded subscriptions name it as the endpoint their notifications come back to. Left out, URLs are built on the origin each request reveals, with no prefix, and subscriptions are not forwarded to context sources.

Default
Not set. Example: "https://broker.example.org/"
Environment variable
ANDROMEDA__SERVER__PUBLIC_URL

server.graceful_drain_timeout​

durationrestart to apply

How long open connections get to finish their requests once shutdown begins. Connections still open after it are closed. The whole stop takes at most this plus notifications.evaluation.drain_timeout from the stop signal, 60 seconds by default, however many tenants are loaded: the tenants and the background tasks share what the connections leave, and whatever still runs then is abandoned and logged. Give the broker the two together plus 10 seconds to stop before your orchestrator kills it; Docker and Podman wait only 10 seconds unless told otherwise.

Default
"30s"
Environment variable
ANDROMEDA__SERVER__GRACEFUL_DRAIN_TIMEOUT

server.announced_close_timeout​

non-zero durationrestart to apply

How long an HTTP/1.1 connection stays open, unread, after a response that announced Connection: close, so the client reads the response before the connection goes. Such a response refuses an upload the broker did not read.

Default
"1s"
Must be
0 < announced_close_timeout < server.graceful_drain_timeout
Environment variable
ANDROMEDA__SERVER__ANNOUNCED_CLOSE_TIMEOUT

server.request_head_timeout​

non-zero durationrestart to apply

How long a connection to the API or management listener gets to send a complete request head, counted from when it opens until its first request, and over HTTP/1.1 from the first byte of each later request. When part of an HTTP/1.1 head has arrived, the broker answers 408 Request Timeout before it closes the connection; otherwise it closes the connection without an answer. A new HTTP/2 connection gets the same time to open its first request.

Default
"30s"
Must be
0 < request_head_timeout
Environment variable
ANDROMEDA__SERVER__REQUEST_HEAD_TIMEOUT

server.idle_timeout​

non-zero durationrestart to apply

How long a connection to the API or management listener may stay open with no request in flight before the broker closes it. An HTTP/2 connection is sent a GOAWAY first. Keep it above how long a reverse proxy in front keeps idle upstream connections, commonly 60 to 120 seconds, so the proxy closes an idle connection first and never sends a request on one the broker is closing.

Default
"3m"
Must be
0 < idle_timeout
Environment variable
ANDROMEDA__SERVER__IDLE_TIMEOUT

[server.http3]​

The optional HTTP/3 listener on the same host and port as the API.
[server.http3]
mode = "disabled"
advertisement_lifetime = "1day"

server.http3.mode​

stringrestart to apply

Whether HTTP/3 is served beside the TCP listener. HTTP/3 has no plaintext form, so enabling it needs tls.certificate and tls.private_key whatever server.transport says.

Default
"disabled"
Allowed values
"disabled"Binds no QUIC endpoint and advertises no HTTP/3.
"enabled"Serves HTTP/3 over UDP on the same host and port as the API, with the [tls] certificate, and advertises it in an Alt-Svc header.
Environment variable
ANDROMEDA__SERVER__HTTP3__MODE

server.http3.advertisement_lifetime​

durationrestart to apply

How long a client may remember the Alt-Svc header that announces HTTP/3, sent as its ma parameter.

Default
"1day"
Environment variable
ANDROMEDA__SERVER__HTTP3__ADVERTISEMENT_LIFETIME

[tls]​

The certificate, private key and handshake policy every TLS-terminating listener shares. Read only when some listener terminates TLS.
[tls]
# certificate = "/etc/andromeda/tls/tls.crt"
# private_key = "/etc/andromeda/tls/tls.key"
minimum_protocol_version = "tls1.2"
handshake_timeout = "10s"
reload_settle_after = "2s"

tls.certificate​

pathreloads live

The PEM certificate chain the broker presents, leaf first. Left out, no listener can terminate TLS. The file is reloaded when it changes.

Default
Not set. Example: "/etc/andromeda/tls/tls.crt"
Also required
Environment variable
ANDROMEDA__TLS__CERTIFICATE

tls.private_key​

pathreloads live

The PEM private key of the leaf certificate, as PKCS#8, SEC1 or PKCS#1. Left out, no listener can terminate TLS. The file is reloaded when it changes.

Default
Not set. Example: "/etc/andromeda/tls/tls.key"
Also required
Environment variable
ANDROMEDA__TLS__PRIVATE_KEY

tls.minimum_protocol_version​

stringrestart to apply

The oldest TLS version a TCP connection may negotiate. HTTP/3 always uses TLS 1.3.

Default
"tls1.2"
Allowed values
"tls1.2"Accepts TLS 1.2 and TLS 1.3. NGSI-LD requires TLS 1.2 support.
"tls1.3"Accepts TLS 1.3 only, for a deployment whose clients all speak it.
Environment variable
ANDROMEDA__TLS__MINIMUM_PROTOCOL_VERSION

tls.handshake_timeout​

non-zero durationrestart to apply

How long a TCP client may take to finish its TLS handshake before the connection is dropped.

Default
"10s"
Must be
0 < handshake_timeout
Environment variable
ANDROMEDA__TLS__HANDSHAKE_TIMEOUT

tls.reload_settle_after​

durationrestart to apply

How long the certificate files must stay unchanged after an edit before the broker loads them again, so a certificate and key replaced one after the other load together.

Default
"2s"
Environment variable
ANDROMEDA__TLS__RELOAD_SETTLE_AFTER

[tls.client_authentication]​

Client certificate authentication (mutual TLS).
[tls.client_authentication]
mode = "disabled"
# ca = "/etc/andromeda/tls/clients.pem"

tls.client_authentication.mode​

stringrestart to apply

Whether clients are asked for a certificate, and whether one is required.

Default
"disabled"
Allowed values
"disabled"Asks for no client certificate. Authentication, if any, happens above TLS.
"optional"Verifies a client certificate when the client sends one and still serves a client without. A certificate from an issuer outside tls.client_authentication.ca fails the handshake.
"required"Serves only clients that present a certificate chaining to tls.client_authentication.ca.
Also required
Environment variable
ANDROMEDA__TLS__CLIENT_AUTHENTICATION__MODE

tls.client_authentication.ca​

pathreloads live

The PEM bundle of the CAs client certificates must chain to. Left out, no client certificate can be verified.

Default
Not set. Example: "/etc/andromeda/tls/clients.pem"
Also required
Environment variable
ANDROMEDA__TLS__CLIENT_AUTHENTICATION__CA

[management]​

Where the broker serves its health probes and metrics.
[management]
mode = "separate-port"
host = "0.0.0.0"
port = 1086
transport = "plaintext"

management.mode​

stringrestart to apply

Where the management endpoints are served: on a port of their own, on the API port, or not at all. A port of their own by default, so probes and metrics keep answering while the API is saturated or draining.

Default
"separate-port"
Allowed values
"disabled"Serves no management endpoints. The health paths under /ngsi-ld/v1 on the API port remain.
"shared-port"Serves the management endpoints at the root of the API port, behind the API's full web stack (CORS, CSRF, security headers, body limits, compression).
"separate-port"Serves the management endpoints on a listener of their own, management.host and management.port, on a bare stack, so probes and metrics keep answering while the API is saturated or draining.
Also required
Environment variable
ANDROMEDA__MANAGEMENT__MODE

management.host​

stringrestart to apply

The address the management listener binds. Read only when management.mode is "separate-port".

Default
"0.0.0.0"
Environment variable
ANDROMEDA__MANAGEMENT__HOST

management.port​

positive integerrestart to apply

The TCP port the management listener binds. Read only when management.mode is "separate-port".

Default
1086
Must be
0 < port
Also required
Environment variable
ANDROMEDA__MANAGEMENT__PORT

management.transport​

stringrestart to apply

Whether the management listener serves plaintext or terminates TLS with the [tls] certificate. Read only when management.mode is "separate-port".

Default
"plaintext"
Allowed values
"plaintext"Serves plaintext HTTP/1.1 and HTTP/2, for a deployment behind a reverse proxy or load balancer that terminates TLS. NGSI-LD calls plaintext HTTP not recommended.
"tls"Terminates TLS in the broker with the [tls] certificate and serves HTTP/1.1 and HTTP/2 over it.
Environment variable
ANDROMEDA__MANAGEMENT__TRANSPORT

[request_limits]​

What one request may cost the broker. Every replica of one deployment runs the same values.
[request_limits]
timeout = "30s"
max_body = "64 MiB"
max_header_section = "32 KiB"
max_json_values = 4000000
max_entity_json_values = 1000000
max_geometry_positions = 1000000
max_attribute_nesting = 32
max_q_comparisons = 1000
max_q_nesting = 16
max_page_body = "64 MiB"

request_limits.timeout​

non-zero durationrestart to apply

The longest one request may run. A request whose body is still arriving then is answered 408 RequestTimeout, and any other request still running is answered 500 InternalError.

Default
"30s"
Must be
0 < timeout
Environment variable
ANDROMEDA__REQUEST_LIMITS__TIMEOUT

request_limits.max_body​

non-zero sizerestart to apply

The largest request body the broker accepts, counted after decompression. A larger body is answered 413.

Default
"64 MiB"
Must be
0 < max_body
Also required
  • It must fit the platform's address width.
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_BODY

request_limits.max_header_section​

sizerestart to applysame on all replicas

The largest request header section the broker accepts, on HTTP/1.1, HTTP/2 and HTTP/3 alike. Every field, the method, target and authority included, costs its name, its value and 32 bytes. A request over it is answered a bare 431. The management listener applies the same limit.

Default
"32 KiB"
Must be
8 KiB ≤ max_header_section ≤ 32 KiB
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_HEADER_SECTION

request_limits.max_json_values​

positive integerrestart to applysame on all replicas

The most JSON values one request body may hold, counted before it is parsed. Every object, array, string, number, boolean and null counts once, so the count follows the cost of processing the body rather than its bytes. A body over it is answered 413.

Default
4000000
Must be
0 < max_json_values
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_JSON_VALUES

request_limits.max_entity_json_values​

positive integerrestart to applysame on all replicas

The most JSON values one entity may hold outside its geometries and JSON literals, counted on the expanded document and on the entity a write stores, so several writes cannot grow one entity past it. A write over it is answered 413. After the limit is lowered, an entity already over it can still be shrunk or rewritten at its size, but not grown.

Default
1000000
Must be
0 < max_entity_json_values
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_ENTITY_JSON_VALUES

request_limits.max_geometry_positions​

positive integerrestart to applysame on all replicas

The most positions one geometry may hold, in a written entity and in a query, subscription or registration geometry. A written geometry over it is answered 413, a query's 403 TooComplexQuery.

Default
1000000
Must be
0 < max_geometry_positions
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_GEOMETRY_POSITIONS

request_limits.max_attribute_nesting​

positive integerrestart to applysame on all replicas

The deepest one written attribute may nest: each sub-attribute, each JSON object or list of a value, and each object or array inside a JSON literal is one level. An attribute nesting deeper is answered 400 BadRequestData. It is also the depth a q or orderBy path may walk. It may be raised to the deepest every stored value reads back at.

Default
32
Must be
0 < max_attribute_nesting ≤ 62
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_ATTRIBUTE_NESTING

request_limits.max_q_comparisons​

positive integerrestart to applysame on all replicas

The most comparisons one q filter may make, in an entity or temporal query, a delete by query, or a subscription. Each Query Term is one comparison, and a value list such as a==1,2,3 one per value. A filter over it is answered 403 TooComplexQuery. A stored subscription is not checked again after the limit is lowered.

Default
1000
Must be
0 < max_q_comparisons
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_Q_COMPARISONS

request_limits.max_q_nesting​

positive integerrestart to applysame on all replicas

How deep the ; and | combinations of one q filter may nest, in an entity or temporal query, a delete by query, or a subscription: a;b nests one level, a;(b|c) and a|b;c two, and parentheses around a single Query Term add none. A filter nesting deeper is answered 403 TooComplexQuery. It may be raised to the deepest parentheses are parsed at; parentheses written deeper are refused whatever this holds.

Default
16
Must be
0 < max_q_nesting ≤ 64
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_Q_NESTING

request_limits.max_page_body​

non-zero sizerestart to applysame on all replicas

The largest body one page of a collection may render to, before any compression. A page that renders to more is answered 403 TooManyResults naming the size and the ceiling, and none of it is sent; the client asks for a smaller limit and follows the next page pointer.

Default
"64 MiB"
Must be
0 < max_page_body
Also required
  • It must fit the platform's address width.
Environment variable
ANDROMEDA__REQUEST_LIMITS__MAX_PAGE_BODY

[http]​

The web-facing layers in front of the API: forwarded-field trust, Link layout, body decoding, CORS, compression, Server-Timing, security headers and CSRF.
[http]
link_field = "combined"
stringrestart to apply

How the Link values of a response or an HTTP notification are spread over field lines. All layouts mean the same; pick the one your clients read.

Default
"combined"
Allowed values
"combined"Puts every Link value on one field line, separated by commas, for clients that read only one field line.
"grouped"Gives the @context link, the pagination links and any other values a field line each.
"separate"Gives every Link value its own field line, for clients that never split a line on commas.
Environment variable
ANDROMEDA__HTTP__LINK_FIELD

[http.body_decoding]​

Where request bodies are parsed: on the request's own worker or on a separate thread pool.
[http.body_decoding]
blocking_threshold = "256 KiB"
max_concurrent_blocking = 4

http.body_decoding.blocking_threshold​

sizerestart to apply

The body size from which a body is parsed on a separate thread pool instead of the request's own worker, so a large body does not stall unrelated requests sharing that worker.

Default
"256 KiB"
Also required
  • It must fit the platform's address width.
Environment variable
ANDROMEDA__HTTP__BODY_DECODING__BLOCKING_THRESHOLD

http.body_decoding.max_concurrent_blocking​

positive integerrestart to apply

How many large bodies are parsed on the separate thread pool at once. A parse holds memory in proportion to its body while it runs; a body waiting for its turn holds only its bytes.

Default
4
Must be
0 < max_concurrent_blocking
Environment variable
ANDROMEDA__HTTP__BODY_DECODING__MAX_CONCURRENT_BLOCKING

[http.cors]​

The Cross-Origin Resource Sharing policy browser clients see.
[http.cors]
mode = "permissive"
allow_origins = "any"
allow_methods = "any"
allow_headers = "any"
expose_headers = []
credentials = "refused"
private_network = "refused"
# preflight_lifetime = "10m"

http.cors.mode​

stringrestart to apply

Which CORS policy applies. Only "configured" reads the other keys of this table. "permissive" by default, so a browser-based interface works against the broker from any origin, and since it allows no credentials a page cannot act with a user's cookies; set "configured" to name the origins a deployment serves.

Default
"permissive"
Allowed values
"disabled"Adds no CORS headers.
"permissive"Allows any origin, method and header, without credentials. Every other [http.cors] key is ignored.
"very-permissive"Mirrors the request's origin, method and headers, and allows credentials. Every other [http.cors] key is ignored.
Also required
Environment variable
ANDROMEDA__HTTP__CORS__MODE

http.cors.allow_origins​

string or list of URLrestart to apply

The origins allowed to read the API: "any", or a list such as ["https://dashboard.example.org"]. Read only when http.cors.mode is "configured".

Default
"any"
Allowed values
"any"Accepts requests from any origin.
Also required
Environment variable
ANDROMEDA__HTTP__CORS__ALLOW_ORIGINS

http.cors.allow_methods​

string or list of stringrestart to apply

The methods allowed: "any", "mirror" to allow whatever the preflight asks for, or a list such as ["GET", "POST"]. Read only when http.cors.mode is "configured".

Default
"any"
Allowed values
"any"Allows any method.
"mirror"Allows the method the request asks for.
Also required
Environment variable
ANDROMEDA__HTTP__CORS__ALLOW_METHODS

http.cors.allow_headers​

string or list of stringrestart to apply

The request headers allowed: "any", "mirror" to allow whatever the preflight asks for, or a list of header names. Read only when http.cors.mode is "configured".

Default
"any"
Allowed values
"any"Allows any request header.
"mirror"Allows the headers the request asks for.
Also required
Environment variable
ANDROMEDA__HTTP__CORS__ALLOW_HEADERS

http.cors.expose_headers​

string or list of stringrestart to apply

The response headers a browser script may read: "any", or a list of header names. Read only when http.cors.mode is "configured".

Default
[]
Allowed values
"any"Exposes any response header.
Also required
Environment variable
ANDROMEDA__HTTP__CORS__EXPOSE_HEADERS

http.cors.credentials​

stringrestart to apply

Whether cookies and HTTP authentication may accompany a cross-origin request. Read only when http.cors.mode is "configured".

Default
"refused"
Allowed values
"allowed"Grants it.
"refused"Refuses it.
Also required
Environment variable
ANDROMEDA__HTTP__CORS__CREDENTIALS

http.cors.private_network​

stringrestart to apply

Whether a private-network preflight is answered with Access-Control-Allow-Private-Network. Read only when http.cors.mode is "configured".

Default
"refused"
Allowed values
"allowed"Grants it.
"refused"Refuses it.
Environment variable
ANDROMEDA__HTTP__CORS__PRIVATE_NETWORK

http.cors.preflight_lifetime​

durationrestart to apply

How long a browser may cache a preflight answer, sent as Access-Control-Max-Age. Left out, the broker sends no Access-Control-Max-Age and the browser's own default applies. Read only when http.cors.mode is "configured".

Default
Not set. Example: "10m"
Environment variable
ANDROMEDA__HTTP__CORS__PREFLIGHT_LIFETIME

[http.compression]​

Which codings responses may be compressed with, and how hard.
[http.compression]
mode = "enabled"
algorithms = ["gzip", "brotli", "deflate", "zstd"]
quality = "default"

http.compression.mode​

stringrestart to apply

Whether responses are compressed. Turn it off when a proxy in front compresses them.

Default
"enabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Also required
Environment variable
ANDROMEDA__HTTP__COMPRESSION__MODE

http.compression.algorithms​

list of stringrestart to apply

The codings responses may be compressed with, chosen against the client's Accept-Encoding. Read only when http.compression.mode is "enabled".

Default
["gzip", "brotli", "deflate", "zstd"]
Also required
Environment variable
ANDROMEDA__HTTP__COMPRESSION__ALGORITHMS

http.compression.quality​

stringrestart to apply

How hard the compressor works.

Default
"default"
Allowed values
"fastest"Favours speed over compression ratio.
"best"Favours compression ratio over speed.
"default"Uses each coding's own balance of speed and ratio.
Environment variable
ANDROMEDA__HTTP__COMPRESSION__QUALITY

[http.decompression]​

Which codings a request body may arrive in.
[http.decompression]
mode = "enabled"
algorithms = ["gzip", "brotli", "deflate", "zstd"]
unaccepted_encoding = "refused"

http.decompression.algorithms​

list of stringrestart to apply

The codings a request body may arrive in, decoded before the body is read. Read only when http.decompression.mode is "enabled".

Default
["gzip", "brotli", "deflate", "zstd"]
Also required
Environment variable
ANDROMEDA__HTTP__DECOMPRESSION__ALGORITHMS

http.decompression.unaccepted_encoding​

stringrestart to apply

What happens to a body in a coding that is not listed. Read only when http.decompression.mode is "enabled".

Default
"refused"
Allowed values
"refused"Answers the request 415 Unsupported Media Type.
"allowed"Passes the body on still encoded.
Environment variable
ANDROMEDA__HTTP__DECOMPRESSION__UNACCEPTED_ENCODING

[http.forwarded]​

Whose Forwarded, X-Forwarded-Proto and X-Forwarded-Host fields decide the scheme and host of the URLs the broker builds. Believe them only from a reverse proxy that overwrites them.
[http.forwarded]
trust = "none"
proxies = []

http.forwarded.trust​

stringrestart to apply

Whose forwarded fields the broker believes.

Default
"none"
Allowed values
"none"Ignores the fields. The URLs the broker builds carry the scheme its own listener speaks and the host the request addressed.
"any"Believes the fields from every peer. Set it only when nothing but a reverse proxy that overwrites the fields can reach the broker, or any client chooses the scheme and host of the URLs the broker builds, including the stored URL of an @context it serves to later readers.
"proxies"Believes the fields only from a peer http.forwarded.proxies lists, and ignores them from every other peer. Each listed proxy must overwrite the fields rather than append to them.
Also required
Environment variable
ANDROMEDA__HTTP__FORWARDED__TRUST

http.forwarded.proxies​

list of stringrestart to apply

The IP addresses and subnets ("10.0.0.0/8", "192.0.2.7", "fd00::/8") of the proxies whose forwarded fields are believed, matched against the address a request arrives from. An IPv4 peer reaching a dual-stack listener is matched as its IPv4 address.

Default
[]
Also required
Environment variable
ANDROMEDA__HTTP__FORWARDED__PROXIES

[http.server_timing]​

Whether responses carry a Server-Timing header, and what it reports.
[http.server_timing]
mode = "enabled"
phases = ["total"]

http.server_timing.mode​

stringrestart to apply

Whether responses carry a Server-Timing header.

Default
"enabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__HTTP__SERVER_TIMING__MODE

http.server_timing.phases​

list of stringrestart to apply

Which times the header reports.

Default
["total"]
Environment variable
ANDROMEDA__HTTP__SERVER_TIMING__PHASES

[http.security_headers]​

The security headers API responses carry, each set or turned off on its own.
[http.security_headers]
mode = "enabled"
cross_origin_opener_policy = "same-origin"
cross_origin_resource_policy = "same-origin"
origin_agent_cluster = "origin-keyed"
referrer_policy = "no-referrer"
x_content_type_options = "nosniff"
x_dns_prefetch_control = "off"
x_download_options = "noopen"
x_frame_options = "same-origin"
x_permitted_cross_domain_policies = "none"
x_xss_protection = "off"

http.security_headers.mode​

stringrestart to apply

Whether API responses carry the security headers below. Turn it off when a proxy in front sets them all; to drop one header, set its own key to "disabled".

Default
"enabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__MODE

http.security_headers.cross_origin_opener_policy​

stringrestart to apply

The Cross-Origin-Opener-Policy header.

Default
"same-origin"
Allowed values
"same-origin"Sends same-origin.
"same-origin-allow-popups"Sends same-origin-allow-popups.
"unsafe-none"Sends unsafe-none.
"disabled"Sends no Cross-Origin-Opener-Policy header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__CROSS_ORIGIN_OPENER_POLICY

http.security_headers.cross_origin_resource_policy​

stringrestart to apply

The Cross-Origin-Resource-Policy header.

Default
"same-origin"
Allowed values
"same-origin"Sends same-origin.
"same-site"Sends same-site.
"cross-origin"Sends cross-origin.
"disabled"Sends no Cross-Origin-Resource-Policy header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__CROSS_ORIGIN_RESOURCE_POLICY

http.security_headers.origin_agent_cluster​

stringrestart to apply

The Origin-Agent-Cluster header.

Default
"origin-keyed"
Allowed values
"origin-keyed"Sends ?1, asking the browser to isolate the broker's origin.
"site-keyed"Sends ?0, letting the browser share an agent cluster across the site.
"disabled"Sends no Origin-Agent-Cluster header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__ORIGIN_AGENT_CLUSTER

http.security_headers.referrer_policy​

stringrestart to apply

The Referrer-Policy header.

Default
"no-referrer"
Allowed values
"no-referrer"Sends no-referrer.
"no-referrer-when-downgrade"Sends no-referrer-when-downgrade.
"origin"Sends origin.
"origin-when-cross-origin"Sends origin-when-cross-origin.
"same-origin"Sends same-origin.
"strict-origin"Sends strict-origin.
"strict-origin-when-cross-origin"Sends strict-origin-when-cross-origin.
"unsafe-url"Sends unsafe-url.
"disabled"Sends no Referrer-Policy header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__REFERRER_POLICY

http.security_headers.x_content_type_options​

stringrestart to apply

The X-Content-Type-Options header.

Default
"nosniff"
Allowed values
"nosniff"Sends nosniff.
"disabled"Sends no X-Content-Type-Options header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__X_CONTENT_TYPE_OPTIONS

http.security_headers.x_dns_prefetch_control​

stringrestart to apply

The X-DNS-Prefetch-Control header.

Default
"off"
Allowed values
"off"Sends off.
"on"Sends on.
"disabled"Sends no X-DNS-Prefetch-Control header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__X_DNS_PREFETCH_CONTROL

http.security_headers.x_download_options​

stringrestart to apply

The X-Download-Options header.

Default
"noopen"
Allowed values
"noopen"Sends noopen.
"disabled"Sends no X-Download-Options header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__X_DOWNLOAD_OPTIONS

http.security_headers.x_frame_options​

stringrestart to apply

The X-Frame-Options header.

Default
"same-origin"
Allowed values
"same-origin"Sends SAMEORIGIN.
"deny"Sends DENY.
"disabled"Sends no X-Frame-Options header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__X_FRAME_OPTIONS

http.security_headers.x_permitted_cross_domain_policies​

stringrestart to apply

The X-Permitted-Cross-Domain-Policies header.

Default
"none"
Allowed values
"none"Sends none.
"master-only"Sends master-only.
"by-content-type"Sends by-content-type.
"by-ftp-filename"Sends by-ftp-filename.
"all"Sends all.
"disabled"Sends no X-Permitted-Cross-Domain-Policies header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__X_PERMITTED_CROSS_DOMAIN_POLICIES

http.security_headers.x_xss_protection​

stringrestart to apply

The X-XSS-Protection header.

Default
"off"
Allowed values
"off"Sends 0, turning a browser's XSS filter off.
"on"Sends 1.
"block"Sends 1; mode=block.
"disabled"Sends no X-XSS-Protection header.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__X_XSS_PROTECTION

[http.security_headers.content_security_policy]​

The Content-Security-Policy header.
[http.security_headers.content_security_policy]
mode = "enabled"
policy = "default-src 'self'; base-uri 'self'; font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; img-src 'self' data:; object-src 'none'; script-src 'self'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; upgrade-insecure-requests"

http.security_headers.content_security_policy.mode​

stringrestart to apply

Whether API responses carry a Content-Security-Policy header.

Default
"enabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__CONTENT_SECURITY_POLICY__MODE

http.security_headers.content_security_policy.policy​

stringrestart to apply

The policy the header carries.

Default
"default-src 'self'; base-uri 'self'; font-src 'self' https: data:; form-action 'self'; frame-ancestors 'self'; img-src 'self' data:; object-src 'none'; script-src 'self'; script-src-attr 'none'; style-src 'self' https: 'unsafe-inline'; upgrade-insecure-requests"
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__CONTENT_SECURITY_POLICY__POLICY

[http.security_headers.strict_transport_security]​

The Strict-Transport-Security header, sent only on a response to a request that arrived over the TLS listener.
[http.security_headers.strict_transport_security]
mode = "disabled"
max_age = "180days"
include_subdomains = "disabled"

http.security_headers.strict_transport_security.mode​

stringrestart to apply

Whether a response to a request over the TLS listener carries Strict-Transport-Security. A browser that sees it uses HTTPS for the host until max_age passes. Off by default, since a browser that has seen it cannot reach the host over plain HTTP again until then; turn it on once HTTPS is the only way the host is reached.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__STRICT_TRANSPORT_SECURITY__MODE

http.security_headers.strict_transport_security.max_age​

durationrestart to apply

How long a browser keeps using HTTPS for the host, the header's max-age. Zero tells a browser to forget the host.

Default
"180days"
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__STRICT_TRANSPORT_SECURITY__MAX_AGE

http.security_headers.strict_transport_security.include_subdomains​

stringrestart to apply

Whether the policy also covers every subdomain of the host, the header's includeSubDomains.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__HTTP__SECURITY_HEADERS__STRICT_TRANSPORT_SECURITY__INCLUDE_SUBDOMAINS

[http.csrf]​

Cross-Site Request Forgery protection for browser clients.
[http.csrf]
mode = "disabled"
trusted_origins = []

http.csrf.mode​

stringrestart to apply

Whether a cross-site request from an origin outside http.csrf.trusted_origins is answered 403. Same-origin requests, requests with neither Origin nor Sec-Fetch-Site, and GET, HEAD and OPTIONS always go through. Off by default, since the broker itself authenticates no one. Turn it on when a proxy in front authenticates browsers, by cookie or by HTTP authentication, because a forged cross-site request would then carry the user's credentials.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__HTTP__CSRF__MODE

http.csrf.trusted_origins​

list of URLrestart to apply

The browser origins whose cross-site requests are trusted, in addition to same-origin requests.

Default
[]
Environment variable
ANDROMEDA__HTTP__CSRF__TRUSTED_ORIGINS

[database]​

The PostgreSQL database the broker stores in, and how it connects.
[database]
# connection = "postgres://andromeda:andromeda@localhost:5432/andromeda"
platform_max_connections = 32
write_reserve_percent = 25
acquire_timeout = "5s"
synchronous_commit = "on"

database.connection​

URL or tablerestart to applysensitive

The PostgreSQL server and the default tenant's database, as a connection URL or as a table of its parts. It has no default: set it here or in ANDROMEDA__DATABASE__CONNECTION, or each part in its own variable such as ANDROMEDA__DATABASE__CONNECTION__PASSWORD. It always names PostgreSQL itself, never a proxy: tenant creation, migrations and maintenance connect here even when database.pooler is set, and so do requests when it is not.

Required
Yes. Example: "postgres://andromeda:andromeda@localhost:5432/andromeda"
Sensitive
configuration show replaces the value.
Environment variable
ANDROMEDA__DATABASE__CONNECTION

database.platform_max_connections​

positive integerrestart to apply

The most connections the platform pool opens, in each broker process. It reads and writes the tenant registry every tenant load consults, the schedule of tenants with due work and the routes of forwarded subscriptions, and always connects to database.connection, even when database.pooler is set. Tenants size their own pools with tenancy.default_tenant.max_connections and tenancy.databases.max_connections.

Default
32
Must be
0 < platform_max_connections
Environment variable
ANDROMEDA__DATABASE__PLATFORM_MAX_CONNECTIONS

database.write_reserve_percent​

integerrestart to apply

The percentage of each tenant pool that read requests (queries, retrievals, discovery and temporal reads) never hold, so writes always find a connection however many reads queue. Rounded down to whole connections: a pool too small to spare one keeps every connection for reads.

Default
25
Must be
write_reserve_percent < 100
Environment variable
ANDROMEDA__DATABASE__WRITE_RESERVE_PERCENT

database.acquire_timeout​

non-zero durationrestart to apply

How long a request waits for a free database connection before it is answered 503 with Retry-After.

Default
"5s"
Must be
0 < acquire_timeout < request_limits.timeout
Environment variable
ANDROMEDA__DATABASE__ACQUIRE_TIMEOUT

database.synchronous_commit​

stringrestart to apply

The PostgreSQL synchronous_commit level set on the default tenant's database and every tenant database. It is installed with ALTER DATABASE ... SET, so every session inherits it, including sessions a transaction-pooling proxy hands out. With "off", a server crash can lose writes clients were already told succeeded.

Default
"on"
Allowed values
"on"Acknowledge a commit once its WAL is flushed to disk, and on synchronous standbys when any are configured.
"off"Acknowledge a commit before its WAL is flushed. Ingest is faster, but a server crash loses the transactions acknowledged in the last three times wal_writer_delay, and notifications for them may already have gone out.
"local"Wait for the local WAL flush only, never for synchronous standbys.
"remote-apply"Wait until synchronous standbys have applied the WAL, so a read on a standby sees the commit.
"remote-write"Wait until synchronous standbys have handed the WAL to their operating system, without waiting for it to reach disk.
Environment variable
ANDROMEDA__DATABASE__SYNCHRONOUS_COMMIT

[database.pooler]​

A transaction-pooling proxy, such as PgBouncer in transaction mode, on the request path. Left out, every connection goes straight to database.connection.
# [database.pooler]
# connection = "postgres://andromeda:andromeda@localhost:6432/andromeda"
# max_connections_per_tenant = 2

database.pooler.connection​

URL or tablerestart to applysensitive

The proxy's connection, as a URL or as a table of its parts, used by requests in place of database.connection. The proxy forwards to the same PostgreSQL, so it normally differs from database.connection only in host and port. Tenant creation, migrations and maintenance keep connecting to database.connection.

Required
Yes. Example: "postgres://andromeda:andromeda@localhost:6432/andromeda"
Sensitive
configuration show replaces the value.
Environment variable
ANDROMEDA__DATABASE__POOLER__CONNECTION

database.pooler.max_connections_per_tenant​

positive integerrestart to apply

The connections each named tenant's pool opens through the proxy, in place of tenancy.databases.max_connections. Keep it small: the proxy multiplexes every tenant onto its own backends, so a tenant needs only enough for its concurrent requests, and many loaded tenants do not exhaust the host's ports.

Required
Yes. Example: 2
Must be
0 < max_connections_per_tenant ≤ tenancy.databases.max_connections
Environment variable
ANDROMEDA__DATABASE__POOLER__MAX_CONNECTIONS_PER_TENANT

[database.name_cache]​

The in-memory caches of each tenant's attribute and entity type names.
[database.name_cache]
loading = "eager"
max_size_per_dictionary = "16 MiB"
idle_eviction_after = "8h"

database.name_cache.loading​

stringrestart to apply

When the caches are filled: as the tenant is loaded, or as names are first resolved.

Default
"eager"
Allowed values
"eager"Read every stored name into the caches when the tenant is loaded, so its first requests resolve names from memory.
"lazy"Read a name into its cache the first time it is resolved.
Environment variable
ANDROMEDA__DATABASE__NAME_CACHE__LOADING

database.name_cache.max_size_per_dictionary​

non-zero sizerestart to apply

The memory each of a tenant's two name caches may hold, in each broker process. A tenant holds at most twice this, and only as much as it has resolved. When a cache is full the least valuable names are dropped; a dropped name is read back from the database the next time it is resolved, so a full cache costs reads but never refuses a write.

Default
"16 MiB"
Must be
0 < max_size_per_dictionary
Environment variable
ANDROMEDA__DATABASE__NAME_CACHE__MAX_SIZE_PER_DICTIONARY

database.name_cache.idle_eviction_after​

string or durationrestart to apply

How long a cached name may go unused before it is dropped, or "unlimited" to drop names only when a cache is full.

Default
"8h"
Allowed values
"unlimited"No limit.
Must be
0 < idle_eviction_after
Environment variable
ANDROMEDA__DATABASE__NAME_CACHE__IDLE_EVICTION_AFTER

[database.maintenance]​

The adaptive PostgreSQL inspection and maintenance controller.
[database.maintenance]
mode = "automatic"
profile = "conservative"
repack = "reported"
max_repack_size = "4 GiB"

database.maintenance.mode​

stringrestart to apply

Whether maintenance is off, only inspects and reports, or also acts on what it finds. Acts by default, so a deployment nobody tunes still gets its wraparound and WAL retention warnings, its catch-up vacuums and its index rebuilds. An action whose right the broker's role lacks is only reported. Set "observe" where the database is maintained on its own schedule.

Default
"automatic"
Allowed values
"disabled"Do not run the controller.
"observe"Inspect the databases and report the maintenance the controller decides on, without carrying any of it out.
"automatic"Inspect the databases and carry out the maintenance the controller decides on.
Environment variable
ANDROMEDA__DATABASE__MAINTENANCE__MODE

database.maintenance.profile​

stringrestart to apply

How often the controller inspects, and how much evidence it needs before it acts.

Default
"conservative"
Allowed values
"conservative"Inspect less often and require stronger evidence before acting.
"responsive"Inspect more often and react to smaller signs of degradation.
Environment variable
ANDROMEDA__DATABASE__MAINTENANCE__PROFILE

database.maintenance.repack​

stringrestart to apply

Whether automatic maintenance also runs the online repacks of bloated tables it decides on, or only reports them. A repack copies the table while it stays in use, so the database needs free disk of up to twice the table's size, which the broker cannot measure. Repacks are only reported by default, so their decisions can be checked against the free disk first. In observe mode repacks are reported whatever this says.

Default
"reported"
Allowed values
"reported"Decide repacks and report them as would-act, without running any.
"performed"Run the repacks the controller decides on while database.maintenance.mode is "automatic".
Environment variable
ANDROMEDA__DATABASE__MAINTENANCE__REPACK

database.maintenance.max_repack_size​

string or sizerestart to apply

The largest table, its heap plus its TOAST, the controller repacks, or "unlimited" to repack a table of any size.

Default
"4 GiB"
Allowed values
"unlimited"No limit.
Must be
0 < max_repack_size
Environment variable
ANDROMEDA__DATABASE__MAINTENANCE__MAX_REPACK_SIZE

[tenancy]​

Named tenants: whether they are served, where their data lives, and how many stay open.
[tenancy]
mode = "enabled"
provisional_tenant_lifetime = "10m"

tenancy.mode​

stringrestart to apply

Whether named tenants are served. With "disabled" only the default tenant exists, and a request naming a tenant in NGSILD-Tenant is answered 501 NoMultiTenantSupport. On by default, so a client can name a tenant without any setup on the broker: the first operation that creates something in a tenant creates the tenant.

Default
"enabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__TENANCY__MODE

tenancy.provisional_tenant_lifetime​

non-zero durationrestart to apply

How long a new tenant whose database still holds nothing is kept before its database is dropped. A creating operation that names a tenant for the first time prepares its database before it runs, and the tenant is answered as nonexistent until that database holds information; a refused operation leaves such a tenant behind.

Default
"10m"
Must be
0 < request_limits.timeout < provisional_tenant_lifetime
Environment variable
ANDROMEDA__TENANCY__PROVISIONAL_TENANT_LIFETIME

[tenancy.default_tenant]​

The default tenant's pool.
[tenancy.default_tenant]
max_connections = 32

tenancy.default_tenant.max_connections​

positive integerrestart to apply

The most connections the default tenant's pool opens, in each broker process. Named tenants size theirs with tenancy.databases.max_connections.

Default
32
Must be
0 < max_connections
Environment variable
ANDROMEDA__TENANCY__DEFAULT_TENANT__MAX_CONNECTIONS

[tenancy.databases]​

How each named tenant's database is named and pooled.
[tenancy.databases]
name_prefix = "andromeda_tenant"
max_connections = 4

tenancy.databases.name_prefix​

SQL identifier prefixrestart to apply

The prefix every tenant database name starts with. Maintenance also uses it to recognise databases on the server that look like a tenant's but belong to none. Must match [A-Za-z_][A-Za-z0-9_]*, so the database names need no quoting.

Default
"andromeda_tenant"
Environment variable
ANDROMEDA__TENANCY__DATABASES__NAME_PREFIX

tenancy.databases.max_connections​

positive integerrestart to apply

The most connections each named tenant's pool opens, in each broker process. With tenancy.residency.max_resident it bounds the open connections at their product, plus the default tenant's pool. Behind a proxy, database.pooler.max_connections_per_tenant applies instead.

Default
4
Must be
0 < max_connections
Environment variable
ANDROMEDA__TENANCY__DATABASES__MAX_CONNECTIONS

[tenancy.residency]​

How many tenants stay loaded, and for how long.
[tenancy.residency]
idle_eviction_after = "15m"
max_resident = 16
sweep_interval = "30s"
min_wake_interval = "30s"
woken_lifetime = "1m"
max_wakes_per_pass = 4
max_concurrent_evictions = 8

tenancy.residency.idle_eviction_after​

non-zero durationrestart to apply

How long an unused tenant stays loaded. Unloading a tenant closes its pool and stops its background work.

Default
"15m"
Must be
0 < idle_eviction_after
Environment variable
ANDROMEDA__TENANCY__RESIDENCY__IDLE_EVICTION_AFTER

tenancy.residency.max_resident​

positive integerrestart to apply

The most tenants loaded at once. A tenant with requests in flight is never unloaded, nor is a tenant loaded for due work within tenancy.residency.woken_lifetime, so the count can exceed this until those requests complete and those lifetimes end. Room is made by unloading the least recently used of the other tenants. A tenant with a periodic notification due within tenancy.residency.min_wake_interval is unloaded only when every other candidate has one too. A tenant loaded for a periodic notification takes a place once per timeInterval: while every place is taken, until its notification is sent, and otherwise for tenancy.residency.woken_lifetime. While those shares add up to more places than this leaves beside the default tenant and the tenants requests use, the broker cannot load tenants as fast as their work falls due: their notifications fall behind without bound, and the broker logs a warning and reports the overdue wakes in andromeda_tenant_overdue_wakes.

Default
16
Must be
0 < max_resident
Environment variable
ANDROMEDA__TENANCY__RESIDENCY__MAX_RESIDENT

tenancy.residency.sweep_interval​

non-zero durationrestart to apply

How often idle tenants are unloaded and provisional tenants settled.

Default
"30s"
Must be
0 < sweep_interval
Environment variable
ANDROMEDA__TENANCY__RESIDENCY__SWEEP_INTERVAL

tenancy.residency.min_wake_interval​

non-zero durationrestart to apply

The shortest wait before a tenant that was just unloaded is loaded again for due work, such as an expiry or a periodic notification. A due time sooner than this is pushed back to it, so a tenant that is only a little overdue is not unloaded and reloaded in a loop. A failed check for due work is retried this far out. A tenant with a periodic notification due within this interval is the last to be unloaded to make room. If it is unloaded all the same, that notification can be late by up to this interval, unless the tenants with due work need more places than tenancy.residency.max_resident leaves, as described there.

Default
"30s"
Must be
0 < min_wake_interval
Environment variable
ANDROMEDA__TENANCY__RESIDENCY__MIN_WAKE_INTERVAL

tenancy.residency.woken_lifetime​

non-zero durationrestart to apply

The longest a tenant loaded for its due work keeps its place. Until its due work has run it is not unloaded, not even to make room for another tenant. While every place is taken, it gives up its place as soon as that work has run, so another tenant with due work can be loaded; while places are free, it keeps its place for this whole time. After it, such a tenant is the first to be unloaded again, yet never displaces a tenant a request used.

Default
"1m"
Must be
0 < woken_lifetime < tenancy.residency.idle_eviction_after
Environment variable
ANDROMEDA__TENANCY__RESIDENCY__WOKEN_LIFETIME

tenancy.residency.max_wakes_per_pass​

positive integerrestart to apply

The most unloaded tenants one pass loads: for due work first, then, in what that leaves, for tenants whose extensions are behind the versions the server ships. Woken tenants share tenancy.build.max_concurrent with tenants loaded for requests, so this keeps a burst of wakes from crowding requests out.

Default
4
Must be
0 < max_wakes_per_pass
Environment variable
ANDROMEDA__TENANCY__RESIDENCY__MAX_WAKES_PER_PASS

tenancy.residency.max_concurrent_evictions​

positive integerrestart to apply

The most tenants unloading at once. Loaded and unloading tenants together stay within tenancy.residency.max_resident plus this. A load that must make room while every slot is busy waits for one within tenancy.build.admission_timeout.

Default
8
Must be
0 < max_concurrent_evictions
Environment variable
ANDROMEDA__TENANCY__RESIDENCY__MAX_CONCURRENT_EVICTIONS

[tenancy.build]​

How a tenant is loaded on its first request.
[tenancy.build]
max_concurrent = 8
admission_timeout = "20s"

tenancy.build.max_concurrent​

positive integerrestart to apply

The most tenants loading at once. Loading opens a pool and, when the tenant's schema is behind or absent, runs migrations over a direct connection. Requests past the bound wait for at most tenancy.build.admission_timeout.

Default
8
Must be
0 < max_concurrent
Environment variable
ANDROMEDA__TENANCY__BUILD__MAX_CONCURRENT

tenancy.build.admission_timeout​

non-zero durationrestart to apply

How long a request may wait for its tenant to load before it is answered 503 with Retry-After. Covers the load itself and every wait ahead of it: another request loading the same tenant, the creation of a new tenant's database, a free loading slot, and a free unloading slot when the cache is full. A tenant still being created or loaded when the time runs out goes on loading, so a retry finds it further along or ready.

Default
"20s"
Must be
0 < admission_timeout < request_limits.timeout
Environment variable
ANDROMEDA__TENANCY__BUILD__ADMISSION_TIMEOUT

[expiry]​

The sweeps that delete what is past its expiresAt.
[expiry]
sweep_interval = "30s"
batch_size = 1000

expiry.sweep_interval​

non-zero durationrestart to apply

How often the expiry sweeps run, over entities and their attributes, subscriptions, context source registrations, Snapshots and Entity Maps. An expired resource may stay in storage for up to one interval, but the API never serves it.

Default
"30s"
Must be
0 < sweep_interval
Environment variable
ANDROMEDA__EXPIRY__SWEEP_INTERVAL

expiry.batch_size​

positive integerrestart to apply

The most expired entities, or entities with expired attributes, one step of the entity sweep reads.

Default
1000
Must be
0 < batch_size
Environment variable
ANDROMEDA__EXPIRY__BATCH_SIZE

[jsonld]​

How @context documents are resolved.

[[jsonld.preloaded_contexts]]​

Contexts read from files at startup, one [[jsonld.preloaded_contexts]] table each with its url and path. Set in the file only. Left out, no context is preloaded.
# [[jsonld.preloaded_contexts]]
# url = "https://example.org/ngsi-ld/context.jsonld"
# path = "contexts/example.jsonld"

jsonld.preloaded_contexts.url​

URLrestart to apply

The URL the context is known by. A preloaded URL is never downloaded.

Required
Yes. Example: "https://example.org/ngsi-ld/context.jsonld"
Also required
  • No two preloaded contexts name the same URL.

jsonld.preloaded_contexts.path​

pathrestart to apply

The file the context is read from, which must exist and hold a valid @context document. A relative path that does not resolve from the working directory is read relative to the configuration file's directory.

Required
Yes. Example: "contexts/example.jsonld"

[jsonld.fetch]​

Whether and how a remote @context is downloaded.
[jsonld.fetch]
mode = "enabled"
timeout = "10s"
max_redirects = 5
max_size = "2 MiB"
private_addresses = "allowed"
allowed_addresses = []
denied_addresses = []

jsonld.fetch.mode​

stringrestart to apply

Whether a context that is neither embedded, preloaded, stored nor cached may be downloaded. With "disabled" nothing is downloaded: only the core @context and the W3C Data Integrity context it names, preloaded documents, stored @contexts and what is already cached are used.

Default
"enabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__JSONLD__FETCH__MODE

jsonld.fetch.timeout​

durationrestart to apply

How long one download may take, its redirects included. A download that times out is not retried and is answered 504 LdContextNotAvailable. A JSON-LD alternate is a download of its own, and a request naming several remote @contexts waits for each, so keep it well below request_limits.timeout.

Default
"10s"
Must be
1s ≤ timeout < request_limits.timeout
Environment variable
ANDROMEDA__JSONLD__FETCH__TIMEOUT

jsonld.fetch.max_size​

non-zero sizerestart to apply

The largest @context document the broker downloads. A larger one is refused with 504 LdContextNotAvailable.

Default
"2 MiB"
Must be
0 < max_size
Environment variable
ANDROMEDA__JSONLD__FETCH__MAX_SIZE

jsonld.fetch.private_addresses​

stringrestart to apply

Whether a @context URL resolving into private or reserved address space is downloaded, and so every redirect and JSON-LD alternate the download follows. Checked against the address actually resolved, not the host name. jsonld.fetch.allowed_addresses exempts addresses from "refused", and jsonld.fetch.denied_addresses refuses addresses whatever this is set to. A refused download is answered 504 LdContextNotAvailable. Set "refused" when clients you do not trust can name a @context.

Default
"allowed"
Allowed values
"allowed"Any endpoint the broker's network reaches is contacted.
"refused"An endpoint whose resolved address is loopback, private or reserved is refused, so a client-supplied endpoint cannot aim the broker at internal hosts. The refusal is recorded as a failed request.
Environment variable
ANDROMEDA__JSONLD__FETCH__PRIVATE_ADDRESSES

jsonld.fetch.allowed_addresses​

list of stringrestart to apply

IP addresses and subnets ("10.2.0.0/24", "10.3.0.17", "fd00:1234::/48") that a @context download may resolve into even though jsonld.fetch.private_addresses is "refused", such as a server in the broker's own network that hosts the contexts its clients use. Empty by default. An entry in jsonld.fetch.denied_addresses takes precedence.

Default
[]
Environment variable
ANDROMEDA__JSONLD__FETCH__ALLOWED_ADDRESSES

jsonld.fetch.denied_addresses​

list of stringrestart to apply

IP addresses and subnets ("203.0.113.0/24", "198.51.100.9") that a @context download must not resolve into, public ones included and whatever jsonld.fetch.private_addresses is set to. Empty by default. Takes precedence over jsonld.fetch.allowed_addresses.

Default
[]
Environment variable
ANDROMEDA__JSONLD__FETCH__DENIED_ADDRESSES

[jsonld.cache]​

How long resolved contexts are kept in memory.
[jsonld.cache]
max_entries = 1024
default_lifetime = "1h"
hosted_revalidation_interval = "1m"
hit_flush_interval = "5s"

jsonld.cache.max_entries​

positive integerrestart to apply

The most entries each in-process context cache holds.

Default
1024
Must be
0 < max_entries
Environment variable
ANDROMEDA__JSONLD__CACHE__MAX_ENTRIES

jsonld.cache.default_lifetime​

durationrestart to apply

How long a downloaded @context is kept when its response sets no Expires and no Cache-Control max-age or s-maxage, and how long a term-cache entry lives. A response that sets one of those keeps its own lifetime.

Default
"1h"
Must be
1s ≤ default_lifetime
Environment variable
ANDROMEDA__JSONLD__CACHE__DEFAULT_LIFETIME

jsonld.cache.hosted_revalidation_interval​

durationrestart to apply

How long a broker process uses its in-memory copy of a @context the broker stores itself before reading it from the database again, since another process sharing the database may have deleted it. It is also the max-age sent when such a @context is served, in whole seconds.

Default
"1m"
Must be
1s ≤ hosted_revalidation_interval
Environment variable
ANDROMEDA__JSONLD__CACHE__HOSTED_REVALIDATION_INTERVAL

jsonld.cache.hit_flush_interval​

non-zero durationrestart to apply

How often the numberOfHits counters of stored @contexts are written to the database.

Default
"5s"
Must be
0 < hit_flush_interval
Environment variable
ANDROMEDA__JSONLD__CACHE__HIT_FLUSH_INTERVAL

[entity]​

Entity batches, their deferred side effects, and the spatial index.

[entity.batch]​

How a batch operation is cut into chunks and run.
[entity.batch]
chunk_size = 512
large_threshold = 512
prepare_blocking_threshold = 128
max_concurrent_chunks = 4
max_concurrent_chunk_writes = 4
async_side_effect_threshold = 1

entity.batch.chunk_size​

positive integerrestart to apply

The entities one chunk of a large batch holds.

Default
512
Must be
0 < chunk_size
Environment variable
ANDROMEDA__ENTITY__BATCH__CHUNK_SIZE

entity.batch.large_threshold​

positive integerrestart to apply

The batch size from which a batch is split into chunks of entity.batch.chunk_size. A smaller batch runs as one.

Default
512
Must be
0 < large_threshold
Environment variable
ANDROMEDA__ENTITY__BATCH__LARGE_THRESHOLD

entity.batch.prepare_blocking_threshold​

positive integerrestart to apply

The batch size from which entities are prepared on the blocking thread pool rather than on the request's own task.

Default
128
Must be
0 < prepare_blocking_threshold
Environment variable
ANDROMEDA__ENTITY__BATCH__PREPARE_BLOCKING_THRESHOLD

entity.batch.max_concurrent_chunks​

positive integerrestart to apply

The most chunks of a batch prepared at once.

Default
4
Must be
0 < max_concurrent_chunks
Environment variable
ANDROMEDA__ENTITY__BATCH__MAX_CONCURRENT_CHUNKS

entity.batch.max_concurrent_chunk_writes​

positive integerrestart to apply

The most chunks of a batch written to the database at once.

Default
4
Must be
0 < max_concurrent_chunk_writes
Environment variable
ANDROMEDA__ENTITY__BATCH__MAX_CONCURRENT_CHUNK_WRITES

entity.batch.async_side_effect_threshold​

positive integerrestart to apply

The smallest batch whose notifications and temporal history are deferred to background workers when the client sends Prefer: respond-async; a smaller batch runs them before it is answered. At 1, every batch that sends the preference defers them. A batch without the preference, or one scoped to a Snapshot, always runs them before it is answered.

Default
1
Must be
0 < async_side_effect_threshold
Environment variable
ANDROMEDA__ENTITY__BATCH__ASYNC_SIDE_EFFECT_THRESHOLD

[entity.side_effects]​

The durable queue of change events a Prefer: respond-async batch leaves for a worker.
[entity.side_effects]
batch_size = 32
stuck_after_attempts = 5

entity.side_effects.batch_size​

positive integerrestart to apply

The most jobs one pass claims. The pass replays them one after another before the worker claims again.

Default
32
Must be
0 < batch_size
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__BATCH_SIZE

entity.side_effects.stuck_after_attempts​

positive integerrestart to apply

Failed attempts from which a job that keeps failing is reported stuck, logged and counted on each further failure. It is never dropped, since it holds the notifications of a write the broker already accepted, and it keeps being retried, never waiting longer than entity.side_effects.queue.max_retry_interval.

Default
5
Must be
0 < stuck_after_attempts
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__STUCK_AFTER_ATTEMPTS

[entity.side_effects.queue]​

How the queue is polled, claimed and retried. A failed job is retried on a delay that doubles from entity.side_effects.queue.retry_interval up to entity.side_effects.queue.max_retry_interval, however often it fails, and is never dropped.
[entity.side_effects.queue]
poll_interval = "1s"
max_poll_interval = "30s"
lease_timeout = "30s"
retry_interval = "2s"
max_retry_interval = "5m"

entity.side_effects.queue.poll_interval​

non-zero durationrestart to apply

How soon an idle worker polls again once a commit's wake has been handled: the floor of its idle backoff. A commit in the same broker process wakes the worker at once.

Default
"1s"
Must be
0 < poll_interval
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__QUEUE__POLL_INTERVAL

entity.side_effects.queue.max_poll_interval​

durationrestart to apply

The longest the idle backoff grows to while no commit wakes the worker. Also how soon a job committed by another broker process is picked up.

Default
"30s"
Must be
entity.side_effects.queue.poll_interval ≤ max_poll_interval
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__QUEUE__MAX_POLL_INTERVAL

entity.side_effects.queue.lease_timeout​

non-zero durationrestart to apply

How long a claim keeps a job from every other worker. A worker that dies leaves its jobs unclaimable for the rest of the term. It is applied in whole seconds, rounded down.

Default
"30s"
Must be
0 < database.acquire_timeout + 5s ≤ lease_timeout
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__QUEUE__LEASE_TIMEOUT

entity.side_effects.queue.retry_interval​

non-zero durationrestart to apply

The delay before a failed job's first retry. Each later retry waits twice as long as the one before, up to the longest retry delay.

Default
"2s"
Must be
0 < retry_interval
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__QUEUE__RETRY_INTERVAL

entity.side_effects.queue.max_retry_interval​

durationrestart to apply

The longest a retry delay grows to.

Default
"5m"
Must be
entity.side_effects.queue.retry_interval ≤ max_retry_interval
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__QUEUE__MAX_RETRY_INTERVAL

[entity.side_effects.retention]​

How long a dead-lettered job is kept.
[entity.side_effects.retention]
dead_letter_after = "7days"
sweep_interval = "5m"

entity.side_effects.retention.dead_letter_after​

non-zero durationrestart to apply

How long a job whose stored changes cannot be read back is kept, as a record of a batch whose notifications were never raised. A job that succeeds is removed by its own replay, and one that fails is retried for as long as it fails.

Default
"7days"
Must be
0 < dead_letter_after
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__RETENTION__DEAD_LETTER_AFTER

entity.side_effects.retention.sweep_interval​

non-zero durationrestart to apply

How often dead-lettered jobs older than entity.side_effects.retention.dead_letter_after are removed.

Default
"5m"
Must be
0 < sweep_interval
Environment variable
ANDROMEDA__ENTITY__SIDE_EFFECTS__RETENTION__SWEEP_INTERVAL

[entity.spatial_index]​

How each tenant's in-memory spatial index stays consistent with the database.
[entity.spatial_index]
consistency = "watermark"
rebuild_interval = "30m"

entity.spatial_index.consistency​

stringrestart to applysame on all replicas

How the index is kept consistent with the database. "commit-synchronous" saves a read per geo query but is exact only when a single broker process writes the database.

Default
"watermark"
Allowed values
"watermark"Before narrowing a geo query, catch the index up with every location the database changed since its last recorded position. Exact in every deployment, including replicas sharing the database, at the cost of one indexed read per geo query.
"commit-synchronous"Update the index with every committed write before the write returns. Exact only when a single broker process writes the database: another process's writes reach this index only at the next rebuild, and until then a geo query here can miss the entity.
"store-verified"Keep no index and let the database evaluate every geo query. Exact in every deployment, at the cost of the database checking every candidate row its own spatial index yields.
Environment variable
ANDROMEDA__ENTITY__SPATIAL_INDEX__CONSISTENCY

entity.spatial_index.rebuild_interval​

non-zero durationrestart to apply

How often each tenant's index is rebuilt from the database. The first rebuild runs when the tenant is loaded, and until it completes the database evaluates every geo query. Later rebuilds drop entities deleted since and, under "commit-synchronous", bring in writes from other broker processes.

Default
"30m"
Must be
0 < rebuild_interval
Environment variable
ANDROMEDA__ENTITY__SPATIAL_INDEX__REBUILD_INTERVAL

[temporal]​

Reading, recording and storing Temporal Evolutions.

[temporal.query]​

How much of a Temporal Evolution one temporal read returns before it is paged.
[temporal.query]
default_last_n = 100
max_last_n = 1000
max_edge_group = 100000
max_aggregation_instances = 1000000

temporal.query.default_last_n​

positive integerrestart to apply

Instances per attribute a temporal read without lastN returns before it is paged forwards.

Default
100
Must be
0 < default_last_n
Environment variable
ANDROMEDA__TEMPORAL__QUERY__DEFAULT_LAST_N

temporal.query.max_last_n​

integerrestart to apply

The largest lastN answered in one response. A larger lastN is narrowed to this many instances per attribute and paged backwards with a 206 whose Content-Range still reports the requested lastN. It is also the most whole periods per attribute on one page of an aggregated read.

Default
1000
Must be
temporal.query.default_last_n ≤ max_last_n ≤ 5000
Environment variable
ANDROMEDA__TEMPORAL__QUERY__MAX_LAST_N

temporal.query.max_edge_group​

integerrestart to apply

The most instances of one attribute sharing one instant that a temporal page carries. A page never splits the instances sharing the instant at its edge, since a client resumes from a timestamp that cannot point inside an instant, so it carries them whole however far past its size that takes it. A larger group is refused with 403 TooManyResults.

Default
100000
Must be
temporal.query.max_last_n ≤ max_edge_group ≤ 1000000
Environment variable
ANDROMEDA__TEMPORAL__QUERY__MAX_EDGE_GROUP

temporal.query.max_aggregation_instances​

positive integerrestart to apply

The most raw instances per attribute one page of an aggregated temporal read folds, beside its temporal.query.max_last_n periods. A page that would fold more ends at the start of the period the first instance beyond the bound falls in; a first period holding more than the bound is read whole, since a period is never split.

Default
1000000
Must be
0 < max_aggregation_instances ≤ 100000000
Environment variable
ANDROMEDA__TEMPORAL__QUERY__MAX_AGGREGATION_INSTANCES

[temporal.history]​

Whether Core API writes are recorded in history, and how the queue that records history is drained.
[temporal.history]
core_writes = "recorded"
batch_size = 256
stuck_after_attempts = 10

temporal.history.core_writes​

stringrestart to apply

Whether Core API writes add to the history of the entities they change. With "not-recorded" only the Temporal API writes history, for a producer that publishes its history there alone; Core writes change current state, and Core queries see them, either way.

Default
"recorded"
Allowed values
"recorded"A Core API write that changes current state records the attribute instances it modified or removed and any Scope it changed or cleared; a write restating what the entity holds records nothing.
"not-recorded"Core API writes leave history untouched: only the Temporal API adds to it or removes from it.
Environment variable
ANDROMEDA__TEMPORAL__HISTORY__CORE_WRITES

temporal.history.batch_size​

positive integerrestart to apply

The most history writes one pass claims. The pass applies them in one transaction, so a larger batch spreads each statement's cost over more writes.

Default
256
Must be
0 < batch_size
Environment variable
ANDROMEDA__TEMPORAL__HISTORY__BATCH_SIZE

temporal.history.stuck_after_attempts​

positive integerrestart to apply

Failed attempts from which a history write that keeps failing is reported stuck, logged and counted on each further failure. It is never discarded, since it is history the broker has already accepted, and it keeps being retried, never waiting longer than temporal.history.queue.max_retry_interval.

Default
10
Must be
0 < stuck_after_attempts
Environment variable
ANDROMEDA__TEMPORAL__HISTORY__STUCK_AFTER_ATTEMPTS

[temporal.history.queue]​

The queue of committed history writes, including those of respond-async batches. A failed write is retried on a delay that doubles from temporal.history.queue.retry_interval up to temporal.history.queue.max_retry_interval.
[temporal.history.queue]
poll_interval = "1s"
max_poll_interval = "30s"
lease_timeout = "30s"
retry_interval = "2s"
max_retry_interval = "5m"

temporal.history.queue.poll_interval​

non-zero durationrestart to apply

How soon an idle worker polls again once a commit's wake has been handled: the floor of its idle backoff. A commit in the same broker process wakes the worker at once.

Default
"1s"
Must be
0 < poll_interval
Environment variable
ANDROMEDA__TEMPORAL__HISTORY__QUEUE__POLL_INTERVAL

temporal.history.queue.max_poll_interval​

durationrestart to apply

The longest the idle backoff grows to while no commit wakes the worker. Also how soon a job committed by another broker process is picked up.

Default
"30s"
Must be
temporal.history.queue.poll_interval ≤ max_poll_interval
Environment variable
ANDROMEDA__TEMPORAL__HISTORY__QUEUE__MAX_POLL_INTERVAL

temporal.history.queue.lease_timeout​

non-zero durationrestart to apply

How long a claim keeps a job from every other worker. A worker that dies leaves its jobs unclaimable for the rest of the term. It is applied in whole seconds, rounded down.

Default
"30s"
Must be
0 < database.acquire_timeout + 5s ≤ lease_timeout
Environment variable
ANDROMEDA__TEMPORAL__HISTORY__QUEUE__LEASE_TIMEOUT

temporal.history.queue.retry_interval​

non-zero durationrestart to apply

The delay before a failed job's first retry. Each later retry waits twice as long as the one before, up to the longest retry delay.

Default
"2s"
Must be
0 < retry_interval
Environment variable
ANDROMEDA__TEMPORAL__HISTORY__QUEUE__RETRY_INTERVAL

temporal.history.queue.max_retry_interval​

durationrestart to apply

The longest a retry delay grows to.

Default
"5m"
Must be
temporal.history.queue.retry_interval ≤ max_retry_interval
Environment variable
ANDROMEDA__TEMPORAL__HISTORY__QUEUE__MAX_RETRY_INTERVAL

[temporal.storage]​

How history is partitioned, converted to the columnstore and aged out.
[temporal.storage]
# chunk_interval = "7days"

temporal.storage.chunk_interval​

durationrestart to apply

The span of time one history partition covers. Left out, the broker leaves each history table's partitioning as it stands, which is 7 days on a table it created. A change is reconciled against the stored partitioning when the broker next opens the tenant; shorten it if the largest partition still in the rowstore keeps passing 4 GB.

Default
Not set. Example: "7days"
Must be
a whole number of days
Environment variable
ANDROMEDA__TEMPORAL__STORAGE__CHUNK_INTERVAL

[temporal.storage.columnstore]​

When history partitions are converted to the columnstore.
[temporal.storage.columnstore]
convert_after = "30days"
sweep_interval = "1h"

temporal.storage.columnstore.convert_after​

durationrestart to apply

The age past which a history partition is converted to the columnstore. Only the TimescaleDB TSL edition has a columnstore; on the Apache-2.0 edition the key has no effect.

Default
"30days"
Must be
temporal.storage.chunk_interval ≤ convert_after, a whole number of days
Environment variable
ANDROMEDA__TEMPORAL__STORAGE__COLUMNSTORE__CONVERT_AFTER

temporal.storage.columnstore.sweep_interval​

non-zero durationrestart to apply

How often partitions past temporal.storage.columnstore.convert_after are converted. The first sweep runs when a tenant opens.

Default
"1h"
Must be
0 < sweep_interval
Environment variable
ANDROMEDA__TEMPORAL__STORAGE__COLUMNSTORE__SWEEP_INTERVAL

[temporal.storage.retention]​

Whether, and at what age, history is deleted.
[temporal.storage.retention]
mode = "disabled"
# delete_after = "365days"
sweep_interval = "1h"

temporal.storage.retention.delete_after​

durationrestart to apply

How much history to keep. History partitions recorded entirely before this age are dropped, together with the Scope history no remaining instance needs. Left out, no age is set and no history is deleted.

Default
Not set. Example: "365days"
Must be
a whole number of days
Environment variable
ANDROMEDA__TEMPORAL__STORAGE__RETENTION__DELETE_AFTER

temporal.storage.retention.sweep_interval​

non-zero durationrestart to apply

How often history past temporal.storage.retention.delete_after is deleted while retention is enabled. The first sweep runs when a tenant opens.

Default
"1h"
Must be
0 < sweep_interval
Environment variable
ANDROMEDA__TEMPORAL__STORAGE__RETENTION__SWEEP_INTERVAL

[notifications]​

Delivering notifications, evaluating live changes, and draining periodic subscriptions.

[notifications.delivery]​

How notifications reach their subscribers, the queue that carries them and how long finished deliveries are kept.
[notifications.delivery]
mode = "live"
request_timeout = "10s"
max_concurrent = 20
max_error_length = 1024
private_addresses = "allowed"
allowed_addresses = []
denied_addresses = []
max_http_body = "128 MiB"
max_mqtt_packet = "128 MiB"
max_attempts = 5

notifications.delivery.mode​

stringrestart to apply

Whether notifications are sent from memory ("live") or through a queue in the tenant database ("durable").

Default
"live"
Allowed values
"live"Subscriptions are evaluated and notifications sent from memory, without persistence, retry or dead-lettering; a crashed broker loses the notifications still in flight. Deliveries already queued in the tenant database are still drained, with their retries.
"durable"Every notification is written to the durable queue in the transaction that raised it, and sent by a worker with retry, leasing and dead-lettering.
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__MODE

notifications.delivery.request_timeout​

non-zero durationrestart to apply

The longest an outgoing notification may take before it is abandoned, live or queued. A subscription's own timeout can shorten it but not lengthen it.

Default
"10s"
Must be
0 < request_timeout
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__REQUEST_TIMEOUT

notifications.delivery.max_concurrent​

positive integerrestart to apply

The most notifications one tenant sends at once, shared by all its Subscriptions. A delivery pass keeps this many in flight while the queue holds due deliveries. Once one Subscription holds half the slots, a freed slot goes to the due Subscription with the fewest in flight, and while another Subscription is active, with a notification in flight or one answered within notifications.delivery.request_timeout, the one holding half gets no more. A slow endpoint therefore leaves the others at least half the slots, and a failing one holds a single slot for its retry. A Subscription active on its own uses every slot.

Default
20
Must be
0 < max_concurrent ≤ 1024
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__MAX_CONCURRENT

notifications.delivery.max_error_length​

positive integerrestart to apply

The most characters of a failure diagnostic kept with a failed delivery attempt. It may be raised to the longest failure summary the store keeps.

Default
1024
Must be
0 < max_error_length ≤ 2048
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__MAX_ERROR_LENGTH

notifications.delivery.private_addresses​

stringrestart to apply

Whether a notification endpoint (an HTTP URL or an MQTT server) resolving into private or reserved address space is notified. Checked against the address actually resolved, not the host name. notifications.delivery.allowed_addresses exempts addresses from "refused", and notifications.delivery.denied_addresses refuses addresses whatever this is set to. Allowed by default because subscribers and MQTT servers commonly run on the broker's own private network; set "refused" when clients you do not trust create subscriptions.

Default
"allowed"
Allowed values
"allowed"Any endpoint the broker's network reaches is contacted.
"refused"An endpoint whose resolved address is loopback, private or reserved is refused, so a client-supplied endpoint cannot aim the broker at internal hosts. The refusal is recorded as a failed request.
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__PRIVATE_ADDRESSES

notifications.delivery.allowed_addresses​

list of stringrestart to apply

IP addresses and subnets ("10.2.0.0/24", "10.3.0.17", "fd00:1234::/48") that a notification endpoint (an HTTP URL or an MQTT server) may resolve into even though notifications.delivery.private_addresses is "refused". Empty by default. An entry in notifications.delivery.denied_addresses takes precedence.

Default
[]
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__ALLOWED_ADDRESSES

notifications.delivery.denied_addresses​

list of stringrestart to apply

IP addresses and subnets ("203.0.113.0/24", "198.51.100.9") that a notification endpoint (an HTTP URL or an MQTT server) must not resolve into, public ones included and whatever notifications.delivery.private_addresses is set to. Empty by default. Takes precedence over notifications.delivery.allowed_addresses.

Default
[]
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__DENIED_ADDRESSES

notifications.delivery.max_http_body​

sizerestart to apply

The largest notification body sent over HTTP. A larger notification is not sent, and its delivery fails without a retry, since every attempt would send the same body. A notification carries the entities of a change in full, so a limit at request_limits.max_body or below could refuse to notify an entity one request wrote.

Default
"128 MiB"
Must be
request_limits.max_body < max_http_body
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__MAX_HTTP_BODY

notifications.delivery.max_mqtt_packet​

non-zero sizerestart to apply

The largest MQTT packet a notification is published in, envelope and topic included. It is also the largest packet the broker accepts from an MQTT server. When an MQTT 5 server announces a smaller maximum, that maximum applies on its connection. A larger notification is not published, and its delivery fails without a retry. A notification carries the entities of a change in full, so a limit at request_limits.max_body or below could refuse to notify an entity one request wrote. No packet is longer than 256 MiB, so request_limits.max_body stays below that.

Default
"128 MiB"
Must be
0 < request_limits.max_body < max_mqtt_packet ≤ 256 MiB
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__MAX_MQTT_PACKET

notifications.delivery.max_attempts​

positive integerrestart to apply

The attempts a queued notification gets. A delivery that has failed this many times is dead-lettered and kept for notifications.delivery.retention.dead_letter_after, as a record of a notification that never arrived.

Default
5
Must be
0 < max_attempts ≤ 2147483647
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__MAX_ATTEMPTS

[notifications.delivery.queue]​

How the delivery queue is polled, claimed and retried. A failed delivery is retried on a delay that doubles from notifications.delivery.queue.retry_interval up to notifications.delivery.queue.max_retry_interval.
[notifications.delivery.queue]
poll_interval = "1s"
max_poll_interval = "30s"
lease_timeout = "30s"
retry_interval = "5s"
max_retry_interval = "5m"

notifications.delivery.queue.poll_interval​

non-zero durationrestart to apply

How soon an idle worker polls again once a commit's wake has been handled: the floor of its idle backoff. A commit in the same broker process wakes the worker at once.

Default
"1s"
Must be
0 < poll_interval
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__QUEUE__POLL_INTERVAL

notifications.delivery.queue.max_poll_interval​

durationrestart to apply

The longest the idle backoff grows to while no commit wakes the worker. Also how soon a job committed by another broker process is picked up.

Default
"30s"
Must be
notifications.delivery.queue.poll_interval ≤ max_poll_interval
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__QUEUE__MAX_POLL_INTERVAL

notifications.delivery.queue.lease_timeout​

non-zero durationrestart to apply

How long a claim keeps a job from every other worker. A worker that dies leaves its jobs unclaimable for the rest of the term. It is applied in whole seconds, rounded down.

Default
"30s"
Must be
0 < notifications.delivery.request_timeout + 5s ≤ lease_timeout ≤ 1day
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__QUEUE__LEASE_TIMEOUT

notifications.delivery.queue.retry_interval​

non-zero durationrestart to apply

The delay before a failed job's first retry. Each later retry waits twice as long as the one before, up to the longest retry delay.

Default
"5s"
Must be
0 < retry_interval
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__QUEUE__RETRY_INTERVAL

notifications.delivery.queue.max_retry_interval​

durationrestart to apply

The longest a retry delay grows to.

Default
"5m"
Must be
notifications.delivery.queue.retry_interval ≤ max_retry_interval
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__QUEUE__MAX_RETRY_INTERVAL

[notifications.delivery.retention]​

How long finished deliveries and their change events are kept.
[notifications.delivery.retention]
acknowledged_after = "1day"
dead_letter_after = "7days"
orphan_event_after = "1day"
sweep_interval = "5m"

notifications.delivery.retention.acknowledged_after​

non-zero durationrestart to apply

How long a delivered notification is kept.

Default
"1day"
Must be
0 < acknowledged_after
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__RETENTION__ACKNOWLEDGED_AFTER

notifications.delivery.retention.dead_letter_after​

non-zero durationrestart to apply

How long a delivery that ran out of attempts is kept, as a record of a notification that never arrived.

Default
"7days"
Must be
0 < dead_letter_after
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__RETENTION__DEAD_LETTER_AFTER

notifications.delivery.retention.orphan_event_after​

non-zero durationrestart to apply

How long a change event no delivery refers to any more is kept.

Default
"1day"
Must be
0 < orphan_event_after
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__RETENTION__ORPHAN_EVENT_AFTER

notifications.delivery.retention.sweep_interval​

non-zero durationrestart to apply

How often expired deliveries and events are removed. A pass runs only for a tenant that may have written since the last one.

Default
"5m"
Must be
0 < sweep_interval
Environment variable
ANDROMEDA__NOTIFICATIONS__DELIVERY__RETENTION__SWEEP_INTERVAL

[notifications.evaluation]​

How live delivery evaluates committed entity changes.
[notifications.evaluation]
max_queued_changes = 8192
max_concurrent_changes = 32
drain_timeout = "30s"

notifications.evaluation.max_queued_changes​

positive integerrestart to apply

The most committed entity changes each tenant buffers for live evaluation. While the broker runs no change is dropped: once the buffer is full, a write waits after its commit until evaluation makes room, so a burst larger than the buffer slows the tenant's writes instead of losing notifications. Changes still waiting when the broker stops or the tenant is unloaded are evaluated first, within notifications.evaluation.drain_timeout. A full buffer holds under 4 MB per tenant at the default. "durable" delivery does not use the buffer.

Default
8192
Must be
0 < max_queued_changes
Environment variable
ANDROMEDA__NOTIFICATIONS__EVALUATION__MAX_QUEUED_CHANGES

notifications.evaluation.max_concurrent_changes​

positive integerrestart to apply

The most committed entity changes evaluated at once. Changes to one entity are evaluated one at a time in commit order; changes to different entities run side by side, each reading its entity and recording a notification per matched subscription, so they share the tenant's database pool with request handling.

Default
32
Must be
0 < max_concurrent_changes
Environment variable
ANDROMEDA__NOTIFICATIONS__EVALUATION__MAX_CONCURRENT_CHANGES

notifications.evaluation.drain_timeout​

durationrestart to apply

The longest a stopping tenant spends evaluating the committed changes it already holds for live delivery, at process shutdown or when the tenant is unloaded. Evaluation that is not finished by then is abandoned and the changes still waiting are dropped, logged and counted. At process shutdown the whole broker stops within server.graceful_drain_timeout plus this, 60 seconds by default, so give it the two together plus 10 seconds before your orchestrator kills it. "durable" delivery records notifications in the commit and is not affected.

Default
"30s"
Environment variable
ANDROMEDA__NOTIFICATIONS__EVALUATION__DRAIN_TIMEOUT

[notifications.periodic]​

How the periodic (timeInterval) notification drain waits.
[notifications.periodic]
max_poll_interval = "30s"

notifications.periodic.max_poll_interval​

non-zero durationrestart to apply

The longest the periodic notification drain sleeps while no subscription is due. The drain otherwise sleeps until the next subscription is due, so a change to the periodic subscriptions is noticed within this time; due notifications are sent on time either way.

Default
"30s"
Must be
0 < max_poll_interval
Environment variable
ANDROMEDA__NOTIFICATIONS__PERIODIC__MAX_POLL_INTERVAL

[federation]​

Forwarding to Context Sources, and this broker's identity among them.

[federation.forwarding]​

How requests reach context sources: fan-out, timeouts and the addresses a source may resolve into.
[federation.forwarding]
max_concurrent = 16
connect_timeout = "3s"
request_timeout = "5s"
private_addresses = "allowed"
allowed_addresses = []
denied_addresses = []

federation.forwarding.max_concurrent​

positive integerrestart to apply

The most forwarded requests one operation has in flight at once.

Default
16
Must be
0 < max_concurrent
Environment variable
ANDROMEDA__FEDERATION__FORWARDING__MAX_CONCURRENT

federation.forwarding.connect_timeout​

non-zero durationrestart to apply

How long connecting to a context source may take.

Default
"3s"
Must be
0 < connect_timeout ≤ federation.forwarding.request_timeout
Environment variable
ANDROMEDA__FEDERATION__FORWARDING__CONNECT_TIMEOUT

federation.forwarding.request_timeout​

non-zero durationrestart to apply

How long a forwarded request may take before it counts as failed, connecting and reading the answer included. A registration's own management.timeout takes precedence.

Default
"5s"
Must be
0 < request_timeout < request_limits.timeout
Environment variable
ANDROMEDA__FEDERATION__FORWARDING__REQUEST_TIMEOUT

federation.forwarding.private_addresses​

stringrestart to apply

Whether a context source whose endpoint resolves into private or reserved address space is contacted. Checked against the address actually resolved, not the host name. federation.forwarding.allowed_addresses exempts addresses from "refused", and federation.forwarding.denied_addresses refuses addresses whatever this is set to. A redirect from a context source is never followed, whatever this is set to. Allowed by default because context sources commonly run beside the broker on a private network; set "refused" when clients you do not trust create registrations.

Default
"allowed"
Allowed values
"allowed"Any endpoint the broker's network reaches is contacted.
"refused"An endpoint whose resolved address is loopback, private or reserved is refused, so a client-supplied endpoint cannot aim the broker at internal hosts. The refusal is recorded as a failed request.
Environment variable
ANDROMEDA__FEDERATION__FORWARDING__PRIVATE_ADDRESSES

federation.forwarding.allowed_addresses​

list of stringrestart to apply

IP addresses and subnets ("10.8.0.0/16", "10.3.0.17", "fd00:1234::/48") that a context source may resolve into even though federation.forwarding.private_addresses is "refused". Empty by default. An entry in federation.forwarding.denied_addresses takes precedence.

Default
[]
Environment variable
ANDROMEDA__FEDERATION__FORWARDING__ALLOWED_ADDRESSES

federation.forwarding.denied_addresses​

list of stringrestart to apply

IP addresses and subnets ("203.0.113.0/24", "198.51.100.9") that a context source must not resolve into, public ones included and whatever federation.forwarding.private_addresses is set to. Empty by default. Takes precedence over federation.forwarding.allowed_addresses.

Default
[]
Environment variable
ANDROMEDA__FEDERATION__FORWARDING__DENIED_ADDRESSES

[federation.query]​

What a federated query means and how much it may gather from context sources: the splitEntities default, the result caps and how aggregated temporal reads are gathered.
[federation.query]
split_entities = "complete"
max_entities = 10000
max_source_rows = 30000
max_instances = 100000
aggregation = "overlapping-instances"

federation.query.split_entities​

stringrestart to apply

What splitEntities means when a request or subscription leaves it unset.

Default
"complete"
Allowed values
"split"A single entity may be split across context sources, so filters are applied only after its parts are re-assembled.
"complete"Every context source holds complete entities, so filters can be applied by each source.
Environment variable
ANDROMEDA__FEDERATION__QUERY__SPLIT_ENTITIES

federation.query.max_entities​

positive integerrestart to apply

The most distinct entities one federated query gathers from the local store and every context source together. An entity several sources answer counts once, and one only an auxiliary source answers counts too. A query that would gather more is refused with 403 TooManyResults rather than answered with a truncated collection.

Default
10000
Must be
0 < max_entities
Environment variable
ANDROMEDA__FEDERATION__QUERY__MAX_ENTITIES

federation.query.max_source_rows​

positive integerrestart to apply

The most entities the context sources of one federated query send together, duplicates included: an entity three sources answer counts three times, and auxiliary sources count too. A query whose sources send more is refused with 403 TooManyResults.

Default
30000
Must be
0 < federation.query.max_entities ≤ max_source_rows
Environment variable
ANDROMEDA__FEDERATION__QUERY__MAX_SOURCE_ROWS

federation.query.max_instances​

positive integerrestart to apply

The most attribute instances one federated temporal query gathers from the context sources whose history it reads to the end, as an aggregated representation of an entity held in several parts needs. A query that would gather more is refused with 403 TooManyResults.

Default
100000
Must be
0 < max_instances
Environment variable
ANDROMEDA__FEDERATION__QUERY__MAX_INSTANCES

federation.query.aggregation​

stringrestart to apply

How a distributed temporal query asking for aggregatedValues reads its context sources. An entity held by more than one part is aggregated by this broker over the instances of every part. "overlapping-instances" asks the sources for their aggregates and asks again only for the instances of the entities more than one part holds: cheapest when parts rarely overlap. "instances" asks for every instance in one round trip: faster when most entities are held by several sources, at the cost of moving and holding every instance.

Default
"overlapping-instances"
Allowed values
"instances"Ask the context sources for every instance of the queried window and aggregate every entity they answer here. One round trip, but every instance travels to and is held by this broker. Suits deployments where most entities are held by several sources.
"overlapping-instances"Ask the context sources for their aggregates, keep the aggregate of an entity only one part holds, and ask again for the instances of the entities more than one part holds. A second round trip only when parts overlap, and only their instances travel.
Environment variable
ANDROMEDA__FEDERATION__QUERY__AGGREGATION

[federation.response_cache]​

The per-tenant cache of forwarded GET responses.
[federation.response_cache]
max_entries = 1024

federation.response_cache.max_entries​

positive integerrestart to apply

The most forwarded GET /entities and GET /entities/{id} answers each tenant's cache holds, for registrations that set management.cacheDuration. An answer served from the cache carries a 110 warning.

Default
1024
Must be
0 < max_entries
Environment variable
ANDROMEDA__FEDERATION__RESPONSE_CACHE__MAX_ENTRIES

[federation.cooldown]​

How a context source is held back after a failed forwarded request.
[federation.cooldown]
mode = "disabled"
retry_interval = "1s"
max_retry_interval = "1day"

federation.cooldown.mode​

stringrestart to apply

How a source is held back after a failed forwarded request. The default, "disabled", holds back only registrations that set management.cooldown.

Default
"disabled"
Allowed values
"disabled"Only a registration's own management.cooldown holds a source back.
"constant"Every failure holds the source back for federation.cooldown.retry_interval.
"exponential"Each failure of an unbroken run of failures doubles the hold, from federation.cooldown.retry_interval up to federation.cooldown.max_retry_interval, with random jitter of up to the hold itself added.
Environment variable
ANDROMEDA__FEDERATION__COOLDOWN__MODE

[federation.identity]​

The identity the broker reports at /ngsi-ld/v1/info/sourceIdentity and uses to detect forwarding loops.
[federation.identity]
# source_id = "urn:ngsi-ld:ContextSourceIdentity:broker-a"
# source_alias = "broker-a"

federation.identity.source_id​

IRIrestart to apply

The id the broker reports at /ngsi-ld/v1/info/sourceIdentity. Must be an IRI. Left out, it is urn:ngsi-ld:ContextSourceIdentity: followed by the alias in effect, as federation.identity.source_alias describes.

Default
Not set. Example: "urn:ngsi-ld:ContextSourceIdentity:broker-a"
Environment variable
ANDROMEDA__FEDERATION__IDENTITY__SOURCE_ID

federation.identity.source_alias​

stringrestart to apply

The name the broker adds to the Via header of every request it forwards. A request whose Via already holds this name is treated as a forwarding loop, so every broker in a federation needs its own. Must be an HTTP token, as a Via entry requires. Left out, it is the host of server.public_url without its port, such as broker.example.org, and without a server.public_url, or with an IPv6 one, the machine's host name. The broker refuses to start when neither gives a token. Set it when two brokers share a host name.

Default
Not set. Example: "broker-a"
Environment variable
ANDROMEDA__FEDERATION__IDENTITY__SOURCE_ALIAS

[federation.identity.extras]​

Instance-specific information the broker reports verbatim as the NGSI-LD contextSourceExtras member at /ngsi-ld/v1/info/sourceIdentity, with the enabled extensions listed beside it. Its keys are reported exactly as written and none is reserved, since the member is raw JSON that is never interpreted. Set in the file only. A date-time, inf or nan, which JSON cannot spell, is refused when the broker starts. Left out, contextSourceExtras lists only the enabled extensions, and is absent when none is enabled.

[snapshot]​

Snapshot lifetimes, quotas and preparation.
[snapshot]
default_lifetime = "1h"
max_lifetime = "30days"

snapshot.default_lifetime​

non-zero durationrestart to apply

The lifetime of a Snapshot created without snapshotLifetime.

Default
"1h"
Must be
0 < default_lifetime ≤ snapshot.max_lifetime
Environment variable
ANDROMEDA__SNAPSHOT__DEFAULT_LIFETIME

snapshot.max_lifetime​

non-zero durationrestart to apply

The longest a Snapshot lives. A longer requested snapshotLifetime is cut down to this.

Default
"30days"
Must be
0 < max_lifetime
Environment variable
ANDROMEDA__SNAPSHOT__MAX_LIFETIME

[snapshot.quota]​

How many Snapshots, and how much storage, one tenant may keep.
[snapshot.quota]
max_per_tenant = "unlimited"
max_storage_per_tenant = "unlimited"

snapshot.quota.max_per_tenant​

string or positive integerrestart to apply

The most Snapshots one tenant keeps, or "unlimited" to keep any number.

Default
"unlimited"
Allowed values
"unlimited"No limit.
Environment variable
ANDROMEDA__SNAPSHOT__QUOTA__MAX_PER_TENANT

snapshot.quota.max_storage_per_tenant​

string or sizerestart to apply

The most storage one tenant's Snapshots take, or "unlimited" to let them take any amount.

Default
"unlimited"
Allowed values
"unlimited"No limit.
Must be
0 < max_storage_per_tenant
Environment variable
ANDROMEDA__SNAPSHOT__QUOTA__MAX_STORAGE_PER_TENANT

[snapshot.preparation]​

How a Snapshot is prepared.
[snapshot.preparation]
page_size = 250
max_concurrent = 4
lease_timeout = "30s"
recovery_interval = "30s"
scoped_operation_timeout = "20s"

snapshot.preparation.page_size​

positive integerrestart to apply

The results read per page while a Snapshot captures its content.

Default
250
Must be
0 < page_size
Environment variable
ANDROMEDA__SNAPSHOT__PREPARATION__PAGE_SIZE

snapshot.preparation.max_concurrent​

positive integerrestart to apply

The most Snapshots prepared at once.

Default
4
Must be
0 < max_concurrent
Environment variable
ANDROMEDA__SNAPSHOT__PREPARATION__MAX_CONCURRENT

snapshot.preparation.lease_timeout​

non-zero durationrestart to apply

How long a claim keeps a preparation from every other worker before another may take it over.

Default
"30s"
Must be
0 < lease_timeout
Environment variable
ANDROMEDA__SNAPSHOT__PREPARATION__LEASE_TIMEOUT

snapshot.preparation.recovery_interval​

non-zero durationrestart to apply

How often preparations a crash or a missed run left unfinished are resumed. Creating a Snapshot starts preparing it at once, so this sweep only recovers.

Default
"30s"
Must be
0 < recovery_interval
Environment variable
ANDROMEDA__SNAPSHOT__PREPARATION__RECOVERY_INTERVAL

snapshot.preparation.scoped_operation_timeout​

non-zero durationrestart to apply

How long a request scoped to a Snapshot waits for its capture or clone to finish. A request still waiting then is answered 503 with Retry-After.

Default
"20s"
Must be
0 < scoped_operation_timeout < request_limits.timeout
Environment variable
ANDROMEDA__SNAPSHOT__PREPARATION__SCOPED_OPERATION_TIMEOUT

[extensions]​

Andromeda's features beyond the NGSI-LD specification.
[extensions]
mode = "configured"

extensions.mode​

stringrestart to apply

Whether the extensions follow their own tables ("configured") or are all forced off ("conformance").

Default
"configured"
Allowed values
"configured"Each extension is served as its own table says.
"conformance"Every extension is off, cursor pagination included, whatever its own table says; each override is logged at startup. The ETSI conformance runs set it, so the shipped binary is the one tested.
Environment variable
ANDROMEDA__EXTENSIONS__MODE

[extensions.cursor_pagination]​

Opaque cursor page pointers, and how a request that names neither offset nor cursor is paged.
[extensions.cursor_pagination]
mode = "enabled"
fresh_requests = "offset"

extensions.cursor_pagination.mode​

stringrestart to apply

Whether cursors are offered. Off, collections page by offset only and a cursor parameter is refused with InvalidRequest. With extensions.mode set to "conformance", collections page by offset whatever this says.

Default
"enabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__CURSOR_PAGINATION__MODE

extensions.cursor_pagination.fresh_requests​

stringrestart to apply

How a request that names neither offset nor cursor is paged while cursors are offered. Read only when extensions.cursor_pagination.mode is "enabled".

Default
"offset"
Allowed values
"cursor"It walks by cursor; offset and an empty cursor= both remain available.
"offset"It pages by offset; an empty cursor= opts into a cursor walk.
Environment variable
ANDROMEDA__EXTENSIONS__CURSOR_PAGINATION__FRESH_REQUESTS

[extensions.temporal_delete_by_query]​

Temporal delete-by-query on DELETE /temporal/entities: a windowed, selector-scoped history purge the NGSI-LD temporal delete operations have no equivalent for.
[extensions.temporal_delete_by_query]
mode = "disabled"
max_matches = 100000

extensions.temporal_delete_by_query.mode​

stringrestart to apply

Whether temporal delete-by-query is served on DELETE /temporal/entities. It acts on local history only and is never forwarded.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__TEMPORAL_DELETE_BY_QUERY__MODE

extensions.temporal_delete_by_query.max_matches​

positive integerrestart to apply

The most history instances one delete-by-query may remove. The matches are counted before anything is deleted, so a larger purge is refused whole with 403 TooManyResults and deletes nothing.

Default
100000
Must be
0 < max_matches
Environment variable
ANDROMEDA__EXTENSIONS__TEMPORAL_DELETE_BY_QUERY__MAX_MATCHES

[extensions.temporal_aggregation_grouping]​

Grouped temporal aggregation through aggrGroupBy and format=groupedValues.
[extensions.temporal_aggregation_grouping]
mode = "disabled"
max_groups = 10000

extensions.temporal_aggregation_grouping.mode​

stringrestart to apply

Whether grouped temporal aggregation is served: calendar and cyclic time buckets, per-entity-member keys and value-in-effect keys, with groups of mixed units split rather than refused. Off, aggrGroupBy and groupedValues are refused with InvalidRequest.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__TEMPORAL_AGGREGATION_GROUPING__MODE

extensions.temporal_aggregation_grouping.max_groups​

positive integerrestart to apply

The most distinct groups one grouped aggregation may produce. The groups are counted before they are computed, so a larger grouping is refused whole with 403 TooManyResults.

Default
10000
Must be
0 < max_groups
Environment variable
ANDROMEDA__EXTENSIONS__TEMPORAL_AGGREGATION_GROUPING__MAX_GROUPS

[extensions.temporal_linked_retrieval]​

Linked entity retrieval on the temporal operations. On, Retrieve and Query Temporal Evolution and the temporal Entity Map accept join, joinLevel and containedBy and retrieve the linked entities' temporal evolution over the request's window. Off, those parameters are refused with InvalidRequest, and a nested projection, a q hop or a retrieving join in a query body with BadRequestData.
[extensions.temporal_linked_retrieval]
mode = "disabled"

extensions.temporal_linked_retrieval.mode​

stringrestart to apply

Whether the extension is served. Off, the broker answers as a conformant broker that never implemented it.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__TEMPORAL_LINKED_RETRIEVAL__MODE

[extensions.purge_dataset_scope]​

datasetId and deleteAll on Purge Entities. On, DELETE /entities gains the per-datasetId precision Delete Attribute already has. Off, a datasetId or deleteAll there is refused with InvalidRequest.
[extensions.purge_dataset_scope]
mode = "disabled"

extensions.purge_dataset_scope.mode​

stringrestart to apply

Whether the extension is served. Off, the broker answers as a conformant broker that never implemented it.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__PURGE_DATASET_SCOPE__MODE

[extensions.tenant_management]​

Tenant management on /tenants. On, the broker serves the tenant collection, per-tenant introspection and suspend or resume through PATCH isActive, and advertises them at /info/sourceIdentity. No API operation ever drops a tenant's database.
[extensions.tenant_management]
mode = "disabled"

extensions.tenant_management.mode​

stringrestart to apply

Whether the extension is served. Off, the broker answers as a conformant broker that never implemented it.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__TENANT_MANAGEMENT__MODE

[extensions.near_distance_band]​

A near geo-query bounded from both sides. On, a near carrying both minDistance and maxDistance matches the entities between the two, on queries, temporal queries, subscription geoQ and registration discovery. Off, the pair is refused with BadRequestData.
[extensions.near_distance_band]
mode = "disabled"

extensions.near_distance_band.mode​

stringrestart to apply

Whether the extension is served. Off, the broker answers as a conformant broker that never implemented it.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__NEAR_DISTANCE_BAND__MODE

[extensions.accept_language]​

Accept-Language read as the language filter. On, a Retrieve or Query of entities, Temporal Evolutions or context source registrations that carries no lang takes its filter from Accept-Language, and the response carries Vary: Accept-Language. Off, the header is ignored.
[extensions.accept_language]
mode = "disabled"

extensions.accept_language.mode​

stringrestart to apply

Whether the extension is served. Off, the broker answers as a conformant broker that never implemented it.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__ACCEPT_LANGUAGE__MODE

[extensions.q_target_languages]​

What a q bracket may name as a target language.
[extensions.q_target_languages]
mode = "disabled"
level = "language-tags"

extensions.q_target_languages.mode​

stringrestart to apply

Whether a q bracket may name a language tag. Off, a bracket names only what the NGSI-LD q grammar defines: [en] is admitted, [en-GB] is refused with BadRequestData. A query carrying a target language is held to the level every context source it reaches advertises.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__EXTENSIONS__Q_TARGET_LANGUAGES__MODE

extensions.q_target_languages.level​

stringrestart to apply

What a q bracket may name while the extension is on. Read only when extensions.q_target_languages.mode is "enabled".

Default
"language-tags"
Allowed values
"language-tags"Every RFC 5646 language tag, matched by case-insensitive tag equality.
"language-ranges"Every RFC 5646 tag and RFC 4647 extended range, matched by extended filtering, so [en] selects en-GB too. This changes what some queries the specification's grammar admits select.
Environment variable
ANDROMEDA__EXTENSIONS__Q_TARGET_LANGUAGES__LEVEL

[observability]​

Logging and metrics.

[observability.log]​

What the broker logs, and where.
[observability.log]
level = "info"

observability.log.level​

stringrestart to apply

The most verbose level written to standard output. A RUST_LOG environment variable takes precedence when it is set.

Default
"info"
Allowed values
"error"Writes errors only.
"warn"Writes warnings and errors.
"info"Writes operational information, warnings and errors.
"debug"Adds debug diagnostics.
"trace"Adds full trace diagnostics.
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__LEVEL

[observability.log.file]​

The optional structured log file.
[observability.log.file]
mode = "disabled"
# directory = "/var/log/andromeda"
name = "andromeda.log"
format = "json"
rotation = "daily"
compression = "gzip"
max_retained_files = 7
level = "info"

observability.log.file.mode​

stringrestart to apply

Whether structured records are written to a rotating file.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__FILE__MODE

observability.log.file.directory​

pathrestart to apply

Where the log files are written. Left out, they go in an andromeda directory in the platform state directory ($XDG_STATE_HOME, or ~/.local/state), or in the data directory on a platform without one.

Default
Not set. Example: "/var/log/andromeda"
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__FILE__DIRECTORY

observability.log.file.name​

pathrestart to apply

The name of the current log file, before the rotation suffix.

Default
"andromeda.log"
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__FILE__NAME

observability.log.file.format​

stringrestart to apply

The shape of each record in the file.

Default
"json"
Allowed values
"json"One JSON record per line, with the current span and the span list.
"jsonl"One compact JSON record per line, without the span fields (JSON Lines).
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__FILE__FORMAT

observability.log.file.rotation​

stringrestart to apply

How often a new file is started.

Default
"daily"
Allowed values
"daily"Starts a new file once per calendar day.
"hourly"Starts a new file once per hour.
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__FILE__ROTATION

observability.log.file.compression​

stringrestart to apply

Whether rotated files are compressed.

Default
"gzip"
Allowed values
"none"Keeps rotated files uncompressed.
"gzip"Compresses rotated files with gzip.
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__FILE__COMPRESSION

observability.log.file.max_retained_files​

positive integerrestart to apply

The most rotated files kept. Past it, the oldest is deleted.

Default
7
Must be
0 < max_retained_files
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__FILE__MAX_RETAINED_FILES

observability.log.file.level​

stringrestart to apply

The most verbose level written to the file, independent of observability.log.level.

Default
"info"
Allowed values
"error"Writes errors only.
"warn"Writes warnings and errors.
"info"Writes operational information, warnings and errors.
"debug"Adds debug diagnostics.
"trace"Adds full trace diagnostics.
Environment variable
ANDROMEDA__OBSERVABILITY__LOG__FILE__LEVEL

[observability.metrics]​

Which exporters the broker's metrics go to, one table each.

[observability.metrics.prometheus]​

Prometheus metrics served at GET /metrics on the management endpoints.
[observability.metrics.prometheus]
mode = "disabled"

observability.metrics.prometheus.mode​

stringrestart to apply

Whether metrics are recorded and served at GET /metrics on the management endpoints.

Default
"disabled"
Allowed values
"disabled"Turn the feature off.
"enabled"Turn the feature on.
Also required
Environment variable
ANDROMEDA__OBSERVABILITY__METRICS__PROMETHEUS__MODE