> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hoox.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# idempotency

# 🔒 Idempotency & Durable Objects

How Hoox utilizes Cloudflare Durable Objects to guarantee exactly-once execution and prevent catastrophic duplicate orders during network dropouts.

***

## ⚠️ The Danger: How Webhook Retries Lead to Double-Ordering

Without idempotency, a typical signal failure sequence looks like this:

```text theme={null}
[TradingView Webhook] ─── (Signal Post) ───> [Gateway Node] ─── (Submit Order) ───> [Exchange API]
                                                                                            │
                                                                                    (Order Filled!)
                                                                                            │
[TradingView Webhook] <── (TLS/TCP Dropout) ── [Gateway Node] <── (Send Success) ─── (Connection drops)
         │
(No response: Retries!)
         │
[TradingView Webhook] ─── (Signal Post) ───> [Gateway Node] ─── (Submit Order) ───> [Exchange API]
                                                                                            │
                                                                                   (DOUBLE-FILLED! ❌)
```

***

## 🛡️ The Hoox Solution: Durable Objects Mutex Locking

To enforce exactly-once execution, Hoox implements an **atomic dedup lock** inside `workers/hoox` utilizing **Cloudflare Durable Objects**.

A Durable Object is a unique, single-threaded compute isolate managed by Cloudflare that maintains its own highly optimized, in-memory state and persistent on-disk SQLite storage. Because access to a specific Durable Object instance is single-threaded, it acts as an absolute **distributed lock** (mutex).

### The Idempotency Workflow

```text theme={null}
[Incoming Webhook Payload]
         │
         ▼
[Extract Trace ID / Mutex Key]
         │
         ▼
[Ping Dedicated Durable Object Isolate]
         │
 ┌───────┴──────────────────────────────────────────┐
 │ Single-Threaded Mutex Lock Acquired              │
 │                                                  │
 │ Check local SQLite dedup log:                    │
 │ "Has Trace ID '9b1deb4d...' been seen?"          │
 └───────┬──────────────────────────────────────────┘
         │
         ├─► [YES: Duplicate Detected] ─────────────────────┐
         │                                                 │
         │                                                 ▼
         │                                     [Silent Dropping of Request]
         │                                                 │
         │                                                 ▼
         │                                     [Return 409 Conflict Response]
         │
         └─► [NO: Unique Transaction] ─────────────────────┐
                                                           │
                                                           ▼
                                               [Record ID in SQLite Log]
                                                           │
                                                           ▼
                                               [Process Pipeline Execution]
                                                           │
                                                           ▼
                                               [Set TTL-based DO Alarm]
```

***

## 🔍 The Dedup & Cleanup Algorithm

### 1. Trace ID Generation

When a trade signal is fired, it must include a unique transaction signature.

* For TradingView webhooks, this is automatically generated as a combination of alert parameters and timestamps.
* If a client does not supply a transaction ID, the Hoox Gateway dynamically hashes the symbol, exchange, action, and timestamp to create a unique **Idempotency Key**.

### 2. Atomic Evaluation

Before executing any order routing:

<ol>
  <li>
    The gateway routes the request to the namespace-mapped Durable Object using
    the transaction ID as the binding key.
  </li>

  <li>
    The Durable Object checks its internal state. Since DOs are single-threaded,
    there is <strong>zero risk of race conditions</strong>—if two identical HTTP
    requests hit Cloudflare simultaneously, they are processed sequentially
    inside the DO.
  </li>

  <li>
    If the ID exists in the DO's SQLite log, the DO immediately intercepts the
    request and throws a <code>409 Conflict</code> exception, stopping the
    pipeline before hitting exchange APIs.
  </li>

  <li>
    If unique, it registers the ID, saves the current timestamp, and returns a
    lock approval.
  </li>
</ol>

### 3. Automatic TTL & Storage Alarms

To prevent the Durable Object's persistent storage from growing indefinitely and consuming unnecessary memory:

* The DO registers an **atomic alarm** scheduled for 24 hours in the future.
* When the alarm fires, the DO runs an automatic garbage collection script that purges old IDs from its local storage.
* This ensures that while you are 100% protected against duplicates during network dropouts, your storage footprint remains lightweight.

### 4. Cold-Start Resilience

When a DO instance has been idle (no requests for the TTL period), Cloudflare may evict it from memory. Upon the next request:

<ol>
  <li>
    The DO is <strong>reconstructed</strong> from its persisted SQLite state on
    disk.
  </li>

  <li>All previously recorded trace IDs are loaded back into memory.</li>

  <li>
    The dedup check continues seamlessly — no data loss, no duplicate risk.
  </li>
</ol>

This means idempotency protection **survives worker restarts, cold starts, and infrastructure failovers** without any manual intervention.

***

## 📊 Performance Impact

| Metric                  | Value        | Notes                            |
| ----------------------- | ------------ | -------------------------------- |
| DO ping overhead        | **\< 2ms**   | Per-request latency added        |
| Lock acquisition        | **\< 1ms**   | Single-threaded, no contention   |
| Dedup check (cache hit) | **\< 0.5ms** | In-memory SQLite query           |
| Storage alarm cleanup   | **\< 5ms**   | Runs in background, non-blocking |

<Warning>
  Never disable idempotency check bindings in your `wrangler.jsonc` file in
  production. The performance cost of pinging the DO is less than **2
  milliseconds**, while the cost of a duplicate order could be catastrophic.
</Warning>

### 🔗 Next Steps

* [**Signals & Trade Specifications**](signals-and-trades) — Learn how to configure your Pine Script webhook payloads to transmit unique idempotency keys.
* [**Platform Security Guides**](../guides/secrets-security) — Deepen your understanding of Zero Trust headers and edge firewall configurations.
