seppv0.1.0
Reference

Server capabilities

The GetServerInfo response: version, protocol versions, limits and feature flags clients use to self-validate.

Clients call GetServerInfo to discover a server's version, its advertised limits and its feature flags. Use the response to validate jobs locally before enqueuing them, or to size producers and workers for the server they're connecting to.

The RPC takes an empty request and returns a GetServerInfoResponse. Every field is always populated; the server never returns optional values. Storage failures produce an INTERNAL gRPC error. The response cannot fail otherwise.

Version and protocol fields

FieldTypeSourceDescription
server_version (1)stringCARGO_PKG_VERSIONSemver server version.
supported_protocol_versions (2)repeated stringhardcodedProtocol versions the server supports. Currently ["v1"].
server_time (3)Timestamprequest-time wall clockServer's current time. Compare with your local clock to detect drift and validate scheduled_at offsets.

Clock-skew detection

Subtract your local monotonic time from server_time to estimate the skew. A negative difference means the server is ahead; scheduled_at expressed relative to your clock may overshoot max_schedule_horizon. Same-sign skew under a few seconds is normal NTP jitter.

Advertised limits

Every advertised limit is drawn from the live configuration. When the config is hot-reloaded, the next GetServerInfo call reflects the new values. These are the global defaults — per-queue overrides set in a [[queues]] entry are not reflected here.

Request ceilings

Limits that cap the size or scope of gRPC requests. Exceeding these produces a whole-request gRPC error, never a per-job JobRejection.

FieldTypeConfig keyDefaultgRPC error
max_enqueue_batch (14)uint32limits.max_enqueue_batch256INVALID_ARGUMENT
max_reserve_batch (15)uint32limits.max_reserve_batch256Clamped silently
max_reserve_queues (16)uint32limits.max_reserve_queues32INVALID_ARGUMENT
max_wait_timeout (17)Durationlimits.max_wait_timeout_ms300000 (5 min)Clamped silently
max_lease_duration (18)Durationlimits.max_lease_duration_ms300000 (5 min)Clamped silently

max_reserve_batch, max_wait_timeout, and max_lease_duration are clamped: the server silently caps the caller's request to the advertised maximum rather than rejecting it. max_enqueue_batch and max_reserve_queues are enforced — exceeding them produces an error.

Per-job limits

Limits checked against each individual job. Exceeding these produces a deterministic JobRejection returned inside the response.

FieldTypeConfig keyDefaultRejection reason
max_payload_bytes (6)uint64limits.max_payload_bytes1048576 (1 MiB)PayloadTooLarge
max_custom_entries (7)uint32limits.max_custom_entries64CustomEntriesTooMany
max_custom_total_bytes (8)uint64limits.max_custom_total_bytes16384 (16 KiB)CustomMapTooLarge
max_custom_key_bytes (9)uint32limits.max_custom_key_bytes256CustomKeyTooLong
max_queue_name_bytes (10)uint32limits.max_queue_name_bytes512QueueNameTooLong
max_job_type_bytes (11)uint32limits.max_job_type_bytes256JobTypeNameTooLong
max_idempotency_key_bytes (12)uint32limits.max_idempotency_key_bytes256IdempotencyKeyTooLong
max_schedule_horizon (13)Durationlimits.max_schedule_horizon_ms30 daysScheduledTooFar

Encoding allowlist

FieldTypeConfig keyDefault
restricts_encodings (4)boollimits.allowed_encodingsfalse
allowed_encodings (5)repeated stringlimits.allowed_encodings[] (empty list)

When restricts_encodings is false, the server accepts any encoding — allowed_encodings is irrelevant. When true, only the encodings listed in allowed_encodings are accepted; anything else triggers EncodingNotAllowed. A non-empty allowed_encodings list always means restricts_encodings is true, even if the list contains every encoding a client might send.

Limits not advertised

Several config limits are deliberately excluded from GetServerInfoResponse because they are server-internal, non-actionable for clients, or per-queue only.

Config keyDefaultOmitted because
limits.max_message_bytes16 MiBgRPC frame size ceiling. The client's transport handles this at the protocol level.
limits.default_max_attempts3Clients supply their own max_attempts; the server's default is an internal fallback.
limits.max_attempts_ceiling100The server silently clamps the client's max_attempts to this ceiling.
limits.default_priority0Clients supply their own priority; the server's default is an internal fallback.
limits.max_queue_depthNone (unlimited)Per-queue cap. A depth limit is transient (QueueFull), not a validation ceiling.
storage.dedup_window_ms24 hIdempotency deduplication window. Determines whether a retry is deduplicated, not whether a job is accepted.
limits.allowed_job_typesNone (unrestricted)Queue-only field; there is no global allowed_job_types.

Feature flags

Two boolean flags describe server-wide behaviour modes.

FieldTypeConfig keyDefaultHot-reload
strict_queues (19)boolserver.strict_queuesfalseYes
dead_letter_retention_enabled (20)boolstorage.dead_letter_retention_msfalseNo (restart-only)

When strict_queues is true, enqueuing to an undeclared queue is rejected with UnknownQueue. When false, queues are created on first use. The server reads this from the live config, so a hot-reload takes effect immediately.

dead_letter_retention_enabled is true when storage.dead_letter_retention_ms > 0. When false, jobs that exhaust their max_attempts are deleted immediately and DrainDeadLetters always returns an empty list. This value is captured at startup and does not change until the server restarts.

Using capabilities for local validation

Clients can validate jobs locally before sending them, catching rejections early and avoiding wasted round trips.

Size checks. Compare payload.data.len() against max_payload_bytes, custom entry counts and byte totals against max_custom_*, and queue name, job type, and idempotency key string lengths against their respective max_*_bytes fields. These limits are deterministic — if the client and the server see the same values, the outcome is the same.

Schedule horizon. Convert your intended scheduled_at to milliseconds-since-epoch, subtract server_time (also in epoch millis), and compare the delta to max_schedule_horizon. Use server_time, not your local clock, because the server checks the horizon against its own wall clock.

Encoding validation. Check restricts_encodings first. If true, your payload's encoding must appear in allowed_encodings.

Strict mode. When strict_queues is true, the client should consult its own registry of known queues. Queues not in that list will be rejected with UnknownQueue. When false, any valid queue name is accepted.

Re-fetch after configuration changes

The server's limits reflect the live config and may change at any time due to a hot-reload. Cache the GetServerInfoResponse but re-fetch it after receiving an unexpected deterministic rejection — the limit may have been tightened since your last call.

See also

  • Rejection catalogue — every rejection reason and which advertised limit triggers it
  • Configuration reference — exhaustive key tables for every config field that governs these capabilities
  • Protocol reference — the full gRPC service definition, request and response messages
  • Queues — how strict_queues and per-queue overrides interact with global limits

On this page