# ENTRY Lock Contention Spike Runbook

## Incident description
A profile experiences repeated failures to acquire the row-based entry lock, blocking ENTRY signals and indicating pressure on horizontal scaling.

## Symptoms
- `lockContentionCount` increments in `/internal/health` and `/metrics`.
- Logs show fn_try_acquire_entry_lock_row returning false with owner tokens different from the caller.
- Trading loop reports `lock acquisition failed` warnings and may skip signals.

## Metrics to check
- `/internal/health` ? `lockContentionCount`, `tradingLoopHealthy`, `reconciliationLoopHealthy`.
- `/metrics` ? `entry_lock_contention_total`, `lock_acquisition_latency_seconds`, `entry_lock_holder_info` (if available).

## Immediate mitigation
1. Identify the profile_id and symbol from logs; confirm if another worker legitimately holds the lock.
2. Ensure the existing lock owner is still alive or has not crashed; use Supabase to inspect `entry_locks` TTL.
3. Wait for TTL expiry (default 30s) before retrying if owner appears stuck.
4. Avoid forcing lock release unless owner is confirmed dead; manual deletion risks concurrent exchange submission.

## Expected self-recovery
- The TTL expires, the lock row updates or deletes itself, and the next signal acquires the lock.
- Metrics return to baseline if contention was transient.

## When to escalate
- Contention persists beyond three TTL cycles (90s).
- Multiple profiles report contention simultaneously.
- Lock rows show expired timestamps but fail to refresh.
Escalate to Platform Ops and refer to docs/runbooks/lock-timeout.md (if it exists) for lock escalation.

## What NOT to do
- Do not delete lock rows manually while other workers are active.
- Do not restart all workers; indiscriminate restarts magnify contention.
- Do not trigger new ENTRY signals for the affected profile until lock clears.
