# `Snakepit.Defaults`
[🔗](https://github.com/nshkrdotcom/snakepit/blob/v0.13.0/lib/snakepit/defaults.ex#L1)

Centralized defaults for all configurable values in Snakepit.

This module provides functions that read from `Application.get_env(:snakepit, key, default)`
for every configurable value. This allows operators to override defaults via application
configuration while maintaining backward compatibility.

All defaults are the EXACT values that were previously hardcoded throughout the codebase.
Snakepit behaves identically before and after this change unless configuration is explicitly
provided.

## Configuration Example

    # config/runtime.exs
    config :snakepit,
      # Timeouts
      default_command_timeout: 30_000,
      pool_request_timeout: 60_000,
      pool_streaming_timeout: 300_000,
      pool_startup_timeout: 10_000,
      pool_queue_timeout: 5_000,
      checkout_timeout: 5_000,
      grpc_worker_execute_timeout: 30_000,
      grpc_worker_stream_timeout: 300_000,
      grpc_command_timeout: 30_000,
      executor_batch_timeout: 30_000,
      health_check_interval: 30_000,
      circuit_breaker_reset_timeout: 30_000,
      graceful_shutdown_timeout_ms: 6_000,

      # Pool settings
      pool_max_queue_size: 1000,
      pool_max_workers: 150,
      pool_max_cancelled_entries: 1024,
      pool_cancelled_retention_multiplier: 4,
      pool_startup_batch_size: 10,
      pool_startup_batch_delay_ms: 500,

      # Retry settings
      retry_max_attempts: 3,
      retry_max_backoff_ms: 30_000,
      retry_jitter_factor: 0.25,
      retry_backoff_sequence: [100, 200, 400, 800, 1600],

      # Circuit breaker settings
      circuit_breaker_failure_threshold: 5,
      circuit_breaker_half_open_max_calls: 1,

      # Crash barrier settings
      crash_barrier_taint_duration_ms: 60_000,
      crash_barrier_max_restarts: 1,
      crash_barrier_backoff_ms: [50, 100, 200],

      # Health monitor settings
      health_monitor_crash_window_ms: 60_000,
      health_monitor_max_crashes: 10,

      # Lifecycle manager settings
      lifecycle_check_interval: 60_000,
      lifecycle_health_check_interval: 300_000,
      lifecycle_check_max_concurrency: 8,
      lifecycle_worker_action_timeout_ms: 2_000,

      # Session store settings
      session_cleanup_interval: 60_000,
      session_default_ttl: 3600,
      session_max_sessions: 10_000,
      session_warning_threshold: 0.8,
      affinity: :hint,

      # Process registry settings
      process_registry_cleanup_interval: 30_000,
      process_registry_unregister_cleanup_delay: 500,
      process_registry_unregister_cleanup_attempts: 10,
      process_registry_dets_flush_interval_ms: 25,

      # gRPC settings
      grpc_num_acceptors: 20,
      grpc_max_connections: 1000,
      grpc_socket_backlog: 512,
      grpc_stream_open_timeout_ms: 5_000,
      grpc_stream_control_timeout_ms: 2_000,

      # Heartbeat settings
      heartbeat_ping_interval_ms: 2_000,
      heartbeat_timeout_ms: 10_000,
      heartbeat_max_missed: 3,
      heartbeat_initial_delay_ms: 0

## Usage

Instead of hardcoding values like `30_000`, modules now call:

    Snakepit.Defaults.default_command_timeout()

This returns the configured value or the original default if not configured.

## Timeout Profiles (v0.8.8+)

Snakepit supports profile-based timeout configuration for different deployment scenarios:

| Profile | default_timeout | stream_timeout | queue_timeout |
|---------|-----------------|----------------|---------------|
| :balanced | 300_000 (5m) | 900_000 (15m) | 10_000 (10s) |
| :production | 300_000 (5m) | 900_000 (15m) | 10_000 (10s) |
| :production_strict | 60_000 (60s) | 300_000 (5m) | 5_000 (5s) |
| :development | 900_000 (15m) | 3_600_000 (60m) | 60_000 (60s) |
| :ml_inference | 900_000 (15m) | 3_600_000 (60m) | 60_000 (60s) |
| :batch | 3_600_000 (60m) | :infinity | 300_000 (5m) |

Configure via:

    config :snakepit, timeout_profile: :production

Legacy per-key configuration is still supported and takes precedence when set.

# `affinity_cache_ttl_seconds`

```elixir
@spec affinity_cache_ttl_seconds() :: pos_integer()
```

TTL for session affinity cache entries in seconds.
Used in `Snakepit.Pool` for ETS affinity caching.

Default: 60 seconds (1 minute)

# `checkout_timeout`

```elixir
@spec checkout_timeout() :: timeout()
```

Default timeout for checking out a worker for streaming.
Used in `Snakepit.Pool` for worker checkout during streaming operations.

When not explicitly configured, derives from `queue_timeout/0` based on the
current timeout profile.

Default: derived from profile (10_000 ms for :balanced)

# `circuit_breaker_failure_threshold`

```elixir
@spec circuit_breaker_failure_threshold() :: pos_integer()
```

Default failure threshold before circuit opens.
Used in `Snakepit.CircuitBreaker`.

Default: 5

# `circuit_breaker_half_open_max_calls`

```elixir
@spec circuit_breaker_half_open_max_calls() :: pos_integer()
```

Default max calls allowed in half-open state.
Used in `Snakepit.CircuitBreaker`.

Default: 1

# `circuit_breaker_reset_timeout_ms`

```elixir
@spec circuit_breaker_reset_timeout_ms() :: pos_integer()
```

Default reset timeout before transitioning to half-open.
Used in `Snakepit.CircuitBreaker`.

Default: 30_000 ms (30 seconds)

# `cleanup_on_stop_timeout_ms`

```elixir
@spec cleanup_on_stop_timeout_ms() :: pos_integer()
```

Timeout for cleanup on stop.
Used in `Snakepit.Application`.

Default: 3_000 ms (3 seconds)

# `cleanup_poll_interval_ms`

```elixir
@spec cleanup_poll_interval_ms() :: pos_integer()
```

Poll interval for cleanup operations.
Used in `Snakepit.Application`.

Default: 50 ms

# `config_default_batch_delay`

```elixir
@spec config_default_batch_delay() :: pos_integer()
```

Default batch delay for process profile.
Used in `Snakepit.Config`.

Default: same as `pool_startup_batch_delay_ms/0`

# `config_default_batch_size`

```elixir
@spec config_default_batch_size() :: pos_integer()
```

Default batch size for process profile.
Used in `Snakepit.Config`.

Default: same as `pool_startup_batch_size/0`

# `config_default_threads_per_worker`

```elixir
@spec config_default_threads_per_worker() :: pos_integer()
```

Default threads per worker for thread profile.
Used in `Snakepit.Config`.

Default: 10

# `crash_barrier_backoff_ms`

```elixir
@spec crash_barrier_backoff_ms() :: [pos_integer()]
```

Default backoff sequence for crash barrier retries.
Used in `Snakepit.CrashBarrier`.

Default: [50, 100, 200]

# `crash_barrier_checkout_timeout`

```elixir
@spec crash_barrier_checkout_timeout() :: timeout()
```

Timeout for checking out worker during crash barrier retry.
Used in `Snakepit.Pool` crash barrier retry logic.

Default: 5_000 ms (5 seconds)

# `crash_barrier_max_restarts`

```elixir
@spec crash_barrier_max_restarts() :: pos_integer()
```

Default max restarts for crash barrier retry.
Used in `Snakepit.CrashBarrier`.

Default: 1

# `crash_barrier_taint_duration_ms`

```elixir
@spec crash_barrier_taint_duration_ms() :: pos_integer()
```

Default taint duration for crashed workers.
Used in `Snakepit.CrashBarrier`.

Default: 60_000 ms (1 minute)

# `default_affinity_mode`

```elixir
@spec default_affinity_mode() :: :hint | :strict_queue | :strict_fail_fast
```

Default session affinity mode for pools.

- `:hint` - Prefer the last worker when available, otherwise fall back
- `:strict_queue` - Queue when preferred worker is busy
- `:strict_fail_fast` - Return `{:error, :worker_busy}` when preferred worker is busy

Default: `:hint`

# `default_capacity_strategy`

```elixir
@spec default_capacity_strategy() :: :pool | :profile | :hybrid
```

Default capacity strategy.
Used in `Snakepit.Config`.

Default: :pool

# `default_command_timeout`

```elixir
@spec default_command_timeout() :: timeout()
```

Default command timeout for worker execute operations.
Used in `Snakepit.Pool` for command timeout calculation.

When not explicitly configured, derives from `rpc_timeout(default_timeout())` based on the
current timeout profile.

Default: derived from profile (rpc_timeout of default_timeout)

# `default_pool_size`

```elixir
@spec default_pool_size() :: pos_integer()
```

Default pool size based on system schedulers.
Used when no explicit pool_size is configured.

Default: System.schedulers_online() * 2

# `default_timeout`

```elixir
@spec default_timeout() :: timeout()
```

Returns the default timeout for regular execute operations based on the current profile.

This is the primary user-facing timeout API. Legacy getters derive from this value
when not explicitly configured.

# `default_worker_profile`

```elixir
@spec default_worker_profile() :: :process | :thread
```

Default worker profile.
Used in `Snakepit.Config`.

Default: :process

# `executor_batch_timeout`

```elixir
@spec executor_batch_timeout() :: timeout()
```

Default timeout for batch operations in Executor.
Used in `Snakepit.Executor.execute_batch/2`.

Default: 30_000 ms (30 seconds)

# `graceful_shutdown_timeout_ms`

```elixir
@spec graceful_shutdown_timeout_ms() :: pos_integer()
```

Graceful shutdown timeout for Python process termination.
Must be >= Python's shutdown envelope: server.stop(2s) + wait_for_termination(3s) = 5s.

Default: 6_000 ms (6 seconds)

# `grpc_batch_inference_timeout`

```elixir
@spec grpc_batch_inference_timeout() :: timeout()
```

Timeout for batch inference commands.
Used in `Snakepit.Adapters.GRPCPython` for batch inference operations.

Default: 300_000 ms (5 minutes)

# `grpc_client_execute_timeout`

```elixir
@spec grpc_client_execute_timeout() :: timeout()
```

Default timeout for gRPC client execute calls.
Used in `Snakepit.GRPC.Client`.

Default: derived from `grpc_command_timeout/0`

# `grpc_command_timeout`

```elixir
@spec grpc_command_timeout() :: timeout()
```

Default command timeout for gRPC adapter.
Used in `Snakepit.Adapters.GRPCPython` for default command timeouts.

When not explicitly configured, derives from `rpc_timeout(default_timeout())` based on the
current timeout profile.

Default: derived from profile (rpc_timeout of default_timeout)

# `grpc_internal_host`

```elixir
@spec grpc_internal_host() :: String.t()
```

Default host for internal-only gRPC listeners.
Used when `grpc_listener.mode` is `:internal`.

Default: "127.0.0.1"

# `grpc_large_dataset_timeout`

```elixir
@spec grpc_large_dataset_timeout() :: timeout()
```

Timeout for large dataset processing commands.
Used in `Snakepit.Adapters.GRPCPython` for large dataset processing operations.

Default: 600_000 ms (10 minutes)

# `grpc_listener_port_check_interval_ms`

```elixir
@spec grpc_listener_port_check_interval_ms() :: pos_integer()
```

Interval (ms) between port readiness checks when reusing an existing gRPC listener.

Default: 25 ms

# `grpc_listener_ready_timeout_ms`

```elixir
@spec grpc_listener_ready_timeout_ms() :: pos_integer()
```

Timeout for waiting on the gRPC listener to publish its assigned port.

Default: 5_000 ms

# `grpc_listener_reuse_attempts`

```elixir
@spec grpc_listener_reuse_attempts() :: pos_integer()
```

Number of attempts to reuse or rebind a gRPC listener before failing.

Default: 3

# `grpc_listener_reuse_retry_delay_ms`

```elixir
@spec grpc_listener_reuse_retry_delay_ms() :: pos_integer()
```

Delay (ms) between gRPC listener reuse retries.

Default: 100 ms

# `grpc_listener_reuse_wait_timeout_ms`

```elixir
@spec grpc_listener_reuse_wait_timeout_ms() :: pos_integer()
```

Max wait (ms) for an already-started gRPC listener to publish its port before retrying.

Default: 500 ms

# `grpc_max_connections`

```elixir
@spec grpc_max_connections() :: pos_integer()
```

Default maximum connections for gRPC server.
Used in `Snakepit.Application`.

Default: 1000

# `grpc_num_acceptors`

```elixir
@spec grpc_num_acceptors() :: pos_integer()
```

Default number of acceptors for gRPC server.
Used in `Snakepit.Application`.

Default: 20

# `grpc_port`

```elixir
@spec grpc_port() :: pos_integer()
```

Default gRPC port for Elixir server.
Legacy: used when `grpc_listener` is not configured.

Default: 50_051

# `grpc_port_pool_size`

```elixir
@spec grpc_port_pool_size() :: pos_integer()
```

Default port pool size for external pooled listeners.
Used when `grpc_listener.mode` is `:external_pool`.

Default: 32

# `grpc_server_ready_timeout`

```elixir
@spec grpc_server_ready_timeout() :: timeout()
```

Timeout for waiting for gRPC server to become ready.
Used in `Snakepit.GRPCWorker` during initialization.

Default: 30_000 ms (30 seconds)

# `grpc_socket_backlog`

```elixir
@spec grpc_socket_backlog() :: pos_integer()
```

Default socket backlog for gRPC server.
Used in `Snakepit.Application`.

Default: 512

# `grpc_stream_control_timeout_ms`

```elixir
@spec grpc_stream_control_timeout_ms() :: pos_integer()
```

Timeout for sending telemetry control messages to Python workers.
Used in `Snakepit.Telemetry.GrpcStream`.

Default: 2_000 ms

# `grpc_stream_open_timeout_ms`

```elixir
@spec grpc_stream_open_timeout_ms() :: pos_integer()
```

Timeout for opening telemetry streams to Python workers.
Used in `Snakepit.Telemetry.GrpcStream`.

Default: 5_000 ms

# `grpc_worker_execute_timeout`

```elixir
@spec grpc_worker_execute_timeout() :: timeout()
```

Default timeout for GRPCWorker execute calls.
Used in `Snakepit.GRPCWorker.execute/4`.

When not explicitly configured, derives from `rpc_timeout(default_timeout())` based on the
current timeout profile.

Default: derived from profile (rpc_timeout of default_timeout)

# `grpc_worker_health_check_interval`

```elixir
@spec grpc_worker_health_check_interval() :: pos_integer()
```

Interval for health checks in GRPCWorker.
Used in `Snakepit.GRPCWorker` for periodic health check scheduling.

Default: 30_000 ms (30 seconds)

# `grpc_worker_health_check_timeout_ms`

```elixir
@spec grpc_worker_health_check_timeout_ms() :: pos_integer()
```

Timeout for periodic GRPCWorker health-check RPCs.
Used in `Snakepit.GRPCWorker` when issuing `Client.health/3`.

Default: 5_000 ms (5 seconds)

# `grpc_worker_stream_timeout`

```elixir
@spec grpc_worker_stream_timeout() :: timeout()
```

Default timeout for GRPCWorker streaming calls.
Used in `Snakepit.GRPCWorker.execute_stream/5`.

Default: derived from `stream_timeout/0`

# `health_monitor_check_interval`

```elixir
@spec health_monitor_check_interval() :: pos_integer()
```

Default interval for health monitor cleanup.
Used in `Snakepit.HealthMonitor`.

Default: 30_000 ms (30 seconds)

# `health_monitor_crash_window_ms`

```elixir
@spec health_monitor_crash_window_ms() :: pos_integer()
```

Default crash window for health monitor.
Rolling window for crash counting.

Default: 60_000 ms (1 minute)

# `health_monitor_max_crashes`

```elixir
@spec health_monitor_max_crashes() :: pos_integer()
```

Default max crashes before pool is considered unhealthy.
Used in `Snakepit.HealthMonitor`.

Default: 10

# `heartbeat_initial_delay_ms`

```elixir
@spec heartbeat_initial_delay_ms() :: non_neg_integer()
```

Initial delay before starting heartbeat monitoring.
Used in `Snakepit.GRPCWorker` heartbeat configuration.

Default: 0 ms

# `heartbeat_max_missed`

```elixir
@spec heartbeat_max_missed() :: pos_integer()
```

Maximum missed heartbeats before worker is considered unhealthy.
Used in `Snakepit.GRPCWorker` heartbeat configuration.

Default: 3

# `heartbeat_ping_interval_ms`

```elixir
@spec heartbeat_ping_interval_ms() :: pos_integer()
```

Default heartbeat ping interval.
Used in `Snakepit.GRPCWorker` heartbeat configuration.

Default: 2_000 ms (2 seconds)

# `heartbeat_timeout_ms`

```elixir
@spec heartbeat_timeout_ms() :: pos_integer()
```

Default heartbeat timeout.
Used in `Snakepit.GRPCWorker` heartbeat configuration.

Default: 10_000 ms (10 seconds)

# `instance_token`

```elixir
@spec instance_token() :: String.t() | nil
```

Default instance token for runtime isolation.

Default: nil

# `lifecycle_check_interval`

```elixir
@spec lifecycle_check_interval() :: pos_integer()
```

Default interval for lifecycle checks.
Used in `Snakepit.Worker.LifecycleManager`.

Default: 60_000 ms (1 minute)

# `lifecycle_check_max_concurrency`

```elixir
@spec lifecycle_check_max_concurrency() :: pos_integer()
```

Maximum concurrent workers evaluated during each lifecycle check cycle.
Used in `Snakepit.Worker.LifecycleManager`.

Default: 8

# `lifecycle_health_check_interval`

```elixir
@spec lifecycle_health_check_interval() :: pos_integer()
```

Default interval for health checks in lifecycle manager.
Used in `Snakepit.Worker.LifecycleManager`.

Default: 300_000 ms (5 minutes)

# `lifecycle_worker_action_timeout_ms`

```elixir
@spec lifecycle_worker_action_timeout_ms() :: pos_integer()
```

Timeout (ms) per worker action during lifecycle check tasks.
Used in `Snakepit.Worker.LifecycleManager`.

Default: 2_000 ms

# `pool_await_ready_timeout`

```elixir
@spec pool_await_ready_timeout() :: timeout()
```

Default timeout for awaiting pool readiness.
Used in `Snakepit.Pool.await_ready/2`.

Default: 15_000 ms (15 seconds)

# `pool_cancelled_retention_multiplier`

```elixir
@spec pool_cancelled_retention_multiplier() :: pos_integer()
```

Multiplier for cancelled request retention time.
Retention time = queue_timeout * this multiplier.

Default: 4

# `pool_max_cancelled_entries`

```elixir
@spec pool_max_cancelled_entries() :: pos_integer()
```

Maximum number of cancelled request entries to track.
Used in `Snakepit.Pool` for cancelled request management.

Default: 1024

# `pool_max_queue_size`

```elixir
@spec pool_max_queue_size() :: pos_integer()
```

Maximum queue size for pending requests.
Used in `Snakepit.Pool` for queue management.

Default: 1000

# `pool_max_workers`

```elixir
@spec pool_max_workers() :: pos_integer()
```

Maximum number of workers allowed per pool.
Used in `Snakepit.Pool` for worker limit enforcement.

Default: 150

# `pool_queue_timeout`

```elixir
@spec pool_queue_timeout() :: timeout()
```

Default timeout for queued requests.
Used in `Snakepit.Pool` for queue management.

When not explicitly configured, derives from `queue_timeout/0` based on the
current timeout profile.

Default: derived from profile (10_000 ms for :balanced)

# `pool_reconcile_batch_size`

```elixir
@spec pool_reconcile_batch_size() :: pos_integer()
```

# `pool_reconcile_interval_ms`

```elixir
@spec pool_reconcile_interval_ms() :: non_neg_integer()
```

# `pool_reply_margin_ms`

```elixir
@spec pool_reply_margin_ms() :: pos_integer()
```

Margin reserved for pool reply overhead.

This is subtracted from the total timeout budget to derive the RPC timeout.

Default: 200 ms

# `pool_request_timeout`

```elixir
@spec pool_request_timeout() :: timeout()
```

Default timeout for pool execute calls.
Used in `Snakepit.Pool.execute/3`.

When not explicitly configured, derives from `default_timeout/0` based on the
current timeout profile.

Default: derived from profile (300_000 ms for :balanced)

# `pool_startup_batch_delay_ms`

```elixir
@spec pool_startup_batch_delay_ms() :: non_neg_integer()
```

Delay between worker startup batches in milliseconds.
Used in `Snakepit.Pool` for batched startup.

Default: 500 ms

# `pool_startup_batch_size`

```elixir
@spec pool_startup_batch_size() :: pos_integer()
```

Number of workers to start per batch during pool initialization.
Used in `Snakepit.Pool` for batched startup.

Default: 10

# `pool_startup_timeout`

```elixir
@spec pool_startup_timeout() :: timeout()
```

Default timeout for worker startup.
Used in pool initialization.

Default: 10_000 ms (10 seconds)

# `pool_streaming_timeout`

```elixir
@spec pool_streaming_timeout() :: timeout()
```

Default timeout for pool streaming calls.
Used in `Snakepit.Pool.execute_stream/4`.

When not explicitly configured, derives from `stream_timeout/0` based on the
current timeout profile.

Default: derived from profile (900_000 ms for :balanced)

# `process_group_kill_enabled?`

```elixir
@spec process_group_kill_enabled?() :: boolean()
```

Whether process-group based termination is enabled.
Used in cleanup and worker shutdown paths.

Default: true

# `process_registry_cleanup_interval`

```elixir
@spec process_registry_cleanup_interval() :: pos_integer()
```

Default cleanup interval for process registry.
Used in `Snakepit.Pool.ProcessRegistry`.

Default: 30_000 ms (30 seconds)

# `process_registry_dets_flush_interval_ms`

```elixir
@spec process_registry_dets_flush_interval_ms() :: pos_integer()
```

Interval (ms) for batching DETS fsync operations in `Snakepit.Pool.ProcessRegistry`.

Default: 25 ms

# `process_registry_unregister_cleanup_attempts`

```elixir
@spec process_registry_unregister_cleanup_attempts() :: pos_integer()
```

Maximum attempts to retry unregister cleanup.
Used in `Snakepit.Pool.ProcessRegistry`.

Default: 10

# `process_registry_unregister_cleanup_delay`

```elixir
@spec process_registry_unregister_cleanup_delay() :: pos_integer()
```

Delay before retrying unregister when external process is still alive.
Used in `Snakepit.Pool.ProcessRegistry`.

Default: 500 ms

# `queue_timeout`

```elixir
@spec queue_timeout() :: timeout()
```

Returns the default queue timeout based on the current profile.

# `retry_backoff_multiplier`

```elixir
@spec retry_backoff_multiplier() :: float()
```

Default backoff multiplier for exponential backoff.
Used in `Snakepit.RetryPolicy`.

Default: 2.0

# `retry_backoff_sequence`

```elixir
@spec retry_backoff_sequence() :: [pos_integer()]
```

Default backoff sequence for retries.
Used in `Snakepit.RetryPolicy`.

Default: [100, 200, 400, 800, 1600]

# `retry_base_backoff_ms`

```elixir
@spec retry_base_backoff_ms() :: pos_integer()
```

Default base backoff for retry calculations.
Used in `Snakepit.RetryPolicy`.

Default: 100 ms

# `retry_jitter_factor`

```elixir
@spec retry_jitter_factor() :: float()
```

Default jitter factor for retry delays.
Used in `Snakepit.RetryPolicy`.

Default: 0.25 (25%)

# `retry_max_attempts`

```elixir
@spec retry_max_attempts() :: pos_integer()
```

Default maximum retry attempts.
Used in `Snakepit.RetryPolicy`.

Default: 3

# `retry_max_backoff_ms`

```elixir
@spec retry_max_backoff_ms() :: pos_integer()
```

Default maximum backoff delay.
Used in `Snakepit.RetryPolicy`.

Default: 30_000 ms (30 seconds)

# `rogue_cleanup_defaults`

```elixir
@spec rogue_cleanup_defaults() :: map()
```

Default rogue cleanup configuration.
Used in `Snakepit.Pool.ProcessRegistry`.

# `rogue_cleanup_run_markers`

```elixir
@spec rogue_cleanup_run_markers() :: [String.t()]
```

Default command markers used to identify run ids for rogue cleanup.

# `rogue_cleanup_scripts`

```elixir
@spec rogue_cleanup_scripts() :: [String.t()]
```

Default script names considered for rogue cleanup process matching.

# `rpc_timeout`

```elixir
@spec rpc_timeout(timeout()) :: timeout()
```

Derives the RPC (inner) timeout from the total timeout budget.

Formula: `rpc_timeout = total_timeout - worker_call_margin_ms - pool_reply_margin_ms`

This ensures inner timeouts expire before outer GenServer.call timeouts,
producing structured error returns instead of unhandled exits.

## Examples

    iex> Snakepit.Defaults.rpc_timeout(60_000)
    58_800  # 60_000 - 1000 - 200

    iex> Snakepit.Defaults.rpc_timeout(:infinity)
    :infinity

# `session_cleanup_interval`

```elixir
@spec session_cleanup_interval() :: pos_integer()
```

Default cleanup interval for expired sessions.
Used in `Snakepit.Bridge.SessionStore`.

Default: 60_000 ms (1 minute)

# `session_default_ttl`

```elixir
@spec session_default_ttl() :: pos_integer()
```

Default TTL for sessions in seconds.
Used in `Snakepit.Bridge.SessionStore`.

Default: 3600 seconds (1 hour)

# `session_max_sessions`

```elixir
@spec session_max_sessions() :: pos_integer() | :infinity
```

Default maximum number of sessions.
Used in `Snakepit.Bridge.SessionStore`.

Default: 10_000

# `session_warning_threshold`

```elixir
@spec session_warning_threshold() :: float()
```

Session warning threshold as a fraction of max_sessions.
When session count exceeds this percentage, warnings are emitted.

Default: 0.8 (80%)

# `shutdown_margin_ms`

```elixir
@spec shutdown_margin_ms() :: pos_integer()
```

Margin added to graceful_shutdown_timeout for supervisor shutdown.
This gives the worker time to complete its terminate/2 callback.

Default: 2_000 ms (2 seconds)

# `stream_timeout`

```elixir
@spec stream_timeout() :: timeout()
```

Returns the default timeout for streaming operations based on the current profile.

# `timeout_profile`

```elixir
@spec timeout_profile() :: atom()
```

Returns the currently configured timeout profile.

Defaults to `:balanced` if not configured.

# `timeout_profiles`

```elixir
@spec timeout_profiles() :: %{required(atom()) =&gt; %{required(atom()) =&gt; timeout()}}
```

Returns all available timeout profiles.

Each profile contains `default_timeout`, `stream_timeout`, and `queue_timeout` values.

# `worker_call_margin_ms`

```elixir
@spec worker_call_margin_ms() :: pos_integer()
```

Margin reserved for GenServer.call overhead when routing to workers.

This is subtracted from the total timeout budget to derive the RPC timeout.

Default: 1000 ms

# `worker_ready_timeout`

```elixir
@spec worker_ready_timeout() :: timeout()
```

Timeout for worker ready notification to pool.
Used in `Snakepit.GRPCWorker` when notifying pool of readiness.

Default: 30_000 ms (30 seconds)

# `worker_starter_max_restarts`

```elixir
@spec worker_starter_max_restarts() :: non_neg_integer()
```

# `worker_starter_max_seconds`

```elixir
@spec worker_starter_max_seconds() :: pos_integer()
```

# `worker_supervisor_cleanup_max_retries`

```elixir
@spec worker_supervisor_cleanup_max_retries() :: pos_integer()
```

Maximum retries while waiting for worker external resource cleanup.
Used in `Snakepit.Pool.WorkerSupervisor`.

Default: 20

# `worker_supervisor_cleanup_retry_interval_ms`

```elixir
@spec worker_supervisor_cleanup_retry_interval_ms() :: pos_integer()
```

Retry interval in milliseconds while polling for worker external resource cleanup.
Used in `Snakepit.Pool.WorkerSupervisor`.

Default: 50 ms

# `worker_supervisor_max_restarts`

```elixir
@spec worker_supervisor_max_restarts() :: non_neg_integer()
```

# `worker_supervisor_max_seconds`

```elixir
@spec worker_supervisor_max_seconds() :: pos_integer()
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
