latlng
Documentation

Configure and operate latlng.

Reference material for the native server configuration, transport surfaces, authorization model, and durable storage behavior.

Configuration

Server options

latlng-server reads JSON or TOML from --config or LATLNG_CONFIG. Environment variables and explicit CLI flags override file values.

latlng-server --print-config-reference
latlng-cli config-reference

latlng-server --config ./latlng.toml --check-config
latlng-cli config-validate ./latlng.toml

Production guardrails

Set production_mode = true to convert security-sensitive warnings into startup failures. This catches disabled auth, static-bearer-only production auth, JWT/JWKS without issuer or audience checks, non-HTTPS JWKS URLs, wildcard CORS with auth, and weak follower replication credentials.

Storage shape

[storage]
type = "aof"
path = "./data/appendonly.aof"

HTTP limits

http_max_body_bytes = 10485760
http_request_timeout_ms = 30000
http_rate_limit_enabled = false
Name Kind Default Description
production_mode bool false Enables strict production startup guardrails.
listen_addr string "127.0.0.1:7421" HTTP listen address.
capnp_enabled bool false Enables the Cap'n Proto RPC and replication listener.
capnp_listen_addr string "127.0.0.1:7422" Cap'n Proto listen address.
server_id string "<generated uuid>" Stable server identity used in replication status.
storage storage_mode "memory" Storage backend. Use memory or aof with a path.
read_only bool false Rejects mutating commands when true.
command_timeouts map<string,float> {} Per-command timeout overrides in seconds.
subscriber_queue_capacity usize 4096 Per-subscriber event queue capacity.
webhook_queue_path path|null null SQLite webhook queue path. Defaults near the AOF or current directory.
webhook_timeout_ms u64 5000 HTTP timeout for webhook deliveries.
webhook_concurrency_limit usize 128 Maximum concurrent webhook delivery attempts.
webhook_retry_count u32 8 Maximum webhook retry attempts before dead-lettering.
webhook_retry_initial_backoff_ms u64 200 Initial webhook retry backoff.
webhook_retry_max_backoff_ms u64 30000 Maximum webhook retry backoff.
webhook_lease_ms u64 30000 Webhook job lease duration.
native_executor_threads usize <available CPU parallelism> Native worker thread count for core operations.
native_executor_queue_limit usize <native_executor_threads * 64> Native executor queue limit.
aof_writer_queue_limit usize 4096 AOF writer queue limit.
aof_group_commit_delay_ms u64 1 Maximum AOF group commit delay.
aof_group_commit_max_requests usize 128 Maximum requests per AOF commit cycle.
follow_host string|null null Leader host for follower replication.
follow_port u16|null null Leader Cap'n Proto port for follower replication.
replication_credential string|null null Dedicated credential for replication streams.
replication_batch_size usize 512 Maximum entries per replication stream response.
replication_reconnect_backoff_ms u64 1000 Follower reconnect backoff after failures.
http_cors_enabled bool false Enables HTTP CORS middleware.
http_cors_allowed_origins list<string> [] Allowed CORS origins. Avoid * with auth.
http_cors_allowed_methods list<string> ["GET","POST","PUT","DELETE","OPTIONS"] Allowed CORS methods.
http_cors_allowed_headers list<string> ["authorization","content-type","x-request-id"] Allowed CORS headers.
http_cors_max_age_seconds u64|null null Optional CORS preflight cache max-age.
http_max_body_bytes usize 10485760 Maximum accepted HTTP request body size.
http_request_timeout_ms u64 30000 Maximum HTTP request duration.
http_rate_limit_enabled bool false Enables a simple global HTTP token-bucket rate limit.
http_rate_limit_requests_per_second u64 1000 Global HTTP rate-limit refill rate.
http_rate_limit_burst u64 1000 Global HTTP rate-limit burst capacity.
http_principal_rate_limit_enabled bool false Enables per-principal HTTP token-bucket rate limiting.
http_principal_rate_limit_requests_per_second u64 100 Per-principal HTTP rate-limit refill rate.
http_principal_rate_limit_burst u64 200 Per-principal HTTP rate-limit burst capacity.
logging_enabled bool true Enables structured server logging.
log_format compact|json "compact" Log output format.
log_level string "info" Tracing filter level.
log_destination stderr|stdout|file|none "stderr" Log destination.
log_file_path path|null null Required when log destination is file.
require_auth bool false Rejects unauthenticated requests when true.
bearer_token string|null null Static full-admin bearer token.
disable_bearer_token bool false Disables static bearer-token authentication even when configured.
jwt_secret string|null null HMAC JWT verification secret.
jwt_public_key_pem string|null null PEM public key for asymmetric JWT validation.
jwt_issuer string|null null Expected JWT issuer.
jwt_audience string|null null Expected JWT audience.
jwt_algorithm string|null null JWT algorithm override.
jwks_url string|null null JWKS endpoint URL.
jwks_provider_id string|null null Provider ID for logs and docs.
jwks_refresh_interval_seconds u64 300 JWKS background refresh interval.
jwks_cache_ttl_seconds u64 3600 JWKS cache TTL.
jwks_http_timeout_ms u64 3000 JWKS HTTP request timeout.
jwt_leeway_seconds u64 0 JWT clock-skew leeway.
Transports and auth

One auth model across native transports.

HTTP, WebSocket, and Cap'n Proto share the same authentication configuration. The server speaks plain HTTP/WebSocket/TCP, so production deployments should terminate TLS upstream.

HTTP/JSON

Primary command and query surface for native deployments. The server exposes generated OpenAPI and supports request body limits, timeouts, CORS, metrics, and auth middleware.

WebSocket

Subscription transport for live geofence events. Clients authenticate with the same auth model and subscribe to channels with collection-scoped subscription permissions.

Cap'n Proto

Async RPC transport for command/query flows and native replication. Enable it with capnp_enabled and expose capnp_listen_addr when RPC or followers need network access.

Authentication modes

  • Static bearer token for local development or trusted service flows.
  • HMAC JWT verification with jwt_secret.
  • PEM-configured asymmetric JWT verification with jwt_public_key_pem.
  • JWKS-configured asymmetric JWT verification with jwks_url.

Exactly one JWT verification source may be configured. For production, prefer JWT or JWKS, set require_auth = true, and disable the static bearer token.

JWT claim shape

{
  "sub": "user-123",
  "iss": "https://id.example.com",
  "aud": "latlng",
  "exp": 4102444800,
  "latlng_permissions": [
    {
      "collections": ["fleet-eu"],
      "actions": ["collections:list", "objects:read", "queries:read"]
    }
  ]
}

Authorization actions

Name Description
collections:list List collections visible to the principal. The /collections response is filtered by this permission.
collections:create Create new collections in the instance.
collections:delete Delete collections and their stored objects.
collections:inspect Read collection metadata and inspection endpoints.
objects:read Fetch objects and object data from permitted collections.
objects:write Create, replace, or update objects in permitted collections.
objects:delete Remove objects from permitted collections.
queries:read Run spatial and text query routes. This is separate from live subscriptions.
subscriptions:read Subscribe to live collection events over WebSocket subscribe and psubscribe flows.
hooks:manage Create, list, update, and delete webhook hooks. List responses are filtered to manageable resources.
channels:manage Create, list, update, and delete event channels. List responses are filtered to manageable resources.
metrics:read Read the Prometheus metrics endpoint without granting broader admin access.
admin:* Use operational and administrative routes.
Hooks

Durable hook delivery with explicit retry state.

Hooks turn geofence events into outbound webhook jobs. The native server stores hook definitions, enqueue intents, delivery results, retries, and dead-letter state so operators can recover and inspect delivery behavior.

Register

Create hooks through the /hooks HTTP routes. A hook stores a name, endpoint, and geofence definition scoped to a collection.

Enqueue

When a mutation produces a matching geofence event, the command and WebhookEnqueue records are persisted in one atomic storage batch before the mutation becomes visible.

Dispatch

The native outbox leases due jobs up to webhook_concurrency_limit and sends each event as an HTTP POST to http:// or https:// endpoints.

Finalize

Successful 2xx responses append WebhookAck. Failed attempts append WebhookRetryScheduled or WebhookDeadLetter after the retry budget is exhausted.

Storage and guarantees

  • Delivery is at-least-once. Consumers should deduplicate with the stable event and job identifiers.
  • Webhook payloads include the geofence event as JSON. HTTP requests include X-LatLng-Event-Id and X-LatLng-Job-Id when those IDs are present.
  • Durable storage keeps enqueue, acknowledgement, retry, and dead-letter state in the primary log. The SQLite queue is rebuilt from that log on startup.
  • AOF-backed servers recover unresolved jobs across restarts. Memory storage keeps the runtime queue file, but durable webhook recovery is not guaranteed because the primary log is ephemeral.
  • A truncated final AOF batch cannot replay only part of a command and its webhook enqueue records.
  • AOF compaction preserves active hooks, channels, and unresolved webhook jobs.
  • FLUSHDB clears collections, geofence definitions, geofence state, and the materialized webhook queue in one coordinated reset.

Delivery settings

webhook_queue_path = "./data/webhook-queue.sqlite"
webhook_timeout_ms = 5000
webhook_concurrency_limit = 128
webhook_retry_count = 8
webhook_retry_initial_backoff_ms = 200
webhook_retry_max_backoff_ms = 30000
webhook_lease_ms = 30000
Name Description
webhook_queue_path SQLite queue path. Defaults next to the AOF as *.webhooks.sqlite, or ./data/webhook-queue.sqlite in memory mode.
webhook_timeout_ms Per-attempt HTTP delivery timeout.
webhook_concurrency_limit Maximum number of webhook delivery attempts in flight.
webhook_retry_count Number of retries after the first attempt. A value of 8 means up to 9 total attempts.
webhook_retry_initial_backoff_ms Initial retry delay used by the exponential backoff calculation.
webhook_retry_max_backoff_ms Upper bound for retry backoff.
webhook_lease_ms Lease duration for in-flight jobs. Expired leases are returned to pending state for another attempt.

Operations and observability

Signal Description
GET /admin/webhook-queue Admin-only queue summary with pending, leased, dead_letter, and oldest_pending_age_ms fields.
latlng_hook_attempts_total Total webhook delivery attempts.
latlng_hook_success_total Successful webhook deliveries.
latlng_hook_failure_total Failed delivery attempts.
latlng_hook_retry_total Attempts that scheduled a retry.
latlng_hook_dead_letter_total Deliveries moved to dead-letter state.
latlng_webhook_jobs_pending Current pending jobs.
latlng_webhook_jobs_leased Current leased jobs.
latlng_webhook_jobs_dead_letter Current dead-letter jobs.
Persistence

Durable logs and recovery behavior.

Use AOF for the runnable server when durability matters. Keep the default safe fsync behavior unless measured workload data points to tuning the writer queue or group commit settings.

Memory

Ephemeral, process-local storage for development and disposable workloads.

AOF

Append-only file storage with replay, compaction, integrity verification, backup, and restore tooling.

SQLite

Embedded/native storage backend. The runnable server currently exposes memory and AOF storage modes.

AOF operations

latlng-cli aof-verify ./data/appendonly.aof
latlng-cli aof-backup ./data/appendonly.aof ./backup/appendonly.backup.json
latlng-cli aof-restore ./backup/appendonly.backup.json ./restore/appendonly.aof

aof-backup is an offline tool. Use it against a stopped server or a copied AOF that is no longer being written. For live systems, prefer graceful shutdown or crash-consistent filesystem snapshots followed by verification.

Recovery guarantees

  • Replay keeps the valid prefix when the final frame is truncated.
  • Complete corrupt payloads fail startup with a codec error.
  • Truncated final batches are ignored as one unit, preserving command-plus-webhook atomicity.
  • Startup replay is incremental, so the core applies entries as they are read.
  • Expirations are persisted as absolute deadlines so restart and AOFSHRINK do not extend TTLs.