Configuration
Configure how your Laravel offline sync client stores mutation logs, identifies itself to the server, connects to sync endpoints, runs queue-based sync, batches pushes, retries failures, and tracks pull cursors.
Publish the config file with:
php artisan vendor:publish --tag=tether-client-config
This creates config/tether-client.php in your application.
connection
'connection' => env('TETHER_DB_CONNECTION', null),
The database connection used for tether_mutation_logs and tether_sync_state. null uses the application default.
table
'table' => env('TETHER_TABLE', 'tether_mutation_logs'),
The table name for the local mutation log.
sync_key
'sync_key' => env('TETHER_SYNC_KEY', 'tether_id'),
The default sync identity column on Syncable models. It must match the server's sync key. Override per model with protected string $tetherKeyName = 'custom_column'.
model_namespace
'model_namespace' => env('TETHER_MODEL_NAMESPACE', 'App\\Models'),
The namespace used when resolving model classes from incoming server pull snapshots. A snapshot with model: "Task" resolves to App\Models\Task.
server_routes
'server_routes' => [
'push' => env('TETHER_SERVER_PUSH_URL', ''),
'pull' => env('TETHER_SERVER_PULL_URL', ''),
],
Full URLs for the server sync endpoints. Push and pull can point to different hosts.
client_id
'client_id' => env('TETHER_CLIENT_ID', ''),
A fixed client identifier sent with every sync request. If empty and no resolver is registered, Tether auto-generates a ULID and persists it in tether_sync_state.
client_id_resolver
'client_id_resolver' => null,
An invokable class that returns the client ID at runtime. Config-cache safe alternative to closures.
Resolution order: callable via resolveClientIdUsing() -> client_id_resolver class -> client_id env -> auto-generated ULID.
auto_sync
'auto_sync' => env('TETHER_AUTO_SYNC', false),
When true, a push-only PushJob is dispatched after every Syncable model write. Requires a running queue worker.
auto_sync_queue
'auto_sync_queue' => env('TETHER_AUTO_SYNC_QUEUE', null),
The queue name for PushJob when auto_sync is enabled. null uses the application's default queue.
auto_sync_throttle
'auto_sync_throttle' => (int) env('TETHER_AUTO_SYNC_THROTTLE', 0),
When greater than 0, PushJob uses Laravel's unique-job lock to coalesce rapid mutation-triggered push jobs (aka "throttle") for this many seconds. 0 disables deduplication.
pull_page_size
'pull_page_size' => env('TETHER_PULL_PAGE_SIZE', null),
Maximum number of snapshots returned per pull request. When set, the client automatically pages through all results. null fetches everything in one request.
push_batch_size
'push_batch_size' => env('TETHER_PUSH_BATCH_SIZE', 100),
Maximum number of pending mutations sent in a single push request. When the queue exceeds this, multiple requests are made sequentially.
max_retry_attempts
'max_retry_attempts' => env('TETHER_MAX_RETRY_ATTEMPTS', 3),
How many times a mutation rejected with reason error will be automatically re-queued. Once the retry count reaches this limit, the mutation stays in failed permanently. Set to 0 to disable retries.
sync_lock
'sync_lock' => env('TETHER_SYNC_LOCK', true),
When true, Tether uses Laravel's atomic cache lock to prevent concurrent sync cycles. Operations return skipped = true if the lock is already held.
Requires a compatible cache driver: memcached, redis, dynamodb, database, file, or array.
debug_level
'debug_level' => env('TETHER_DEBUG_LEVEL', 0),
Controls package debug logging (Log::debug()). 0 disables debug logging, 1 logs lifecycle summaries, 2 logs decisions and outcomes, and 3 logs verbose diagnostics. All package debug messages are prefixed with [TETHER].
Events
Use Laravel events from tether/client to react to sync lifecycle changes, push and pull completion, skipped runs, and detected conflicts.
Server Setup
Install tether/server, register Syncable Eloquent models, expose push and pull endpoints, and reconcile offline client mutations on your Laravel server.