Skip to main content

Entity configuration

[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