Docs

Sticky Sessions

Pin your requests to a single backend node using the DWSESSION cookie. Useful for consistent state across sequential calls like eth_getFilterChanges, eth_subscribe, and trace workflows.

Dwellir endpoints are backed by multiple blockchain nodes behind a load balancer. By default, each request may land on a different node. Sticky sessions let you pin all your requests to the same backend node using a cookie, which is important when your workflow depends on consistent state across sequential calls.

When You Need Sticky Sessions

  • Filter-based workflows -- eth_newFilter / eth_getFilterChanges require the same node because filters are local to the node that created them.
  • Pending transaction monitoring -- eth_newPendingTransactionFilter followed by eth_getFilterChanges.
  • Debug and trace sequences -- multi-step trace workflows where intermediate state lives on a single node.
  • Any stateful JSON-RPC sequence -- whenever a later call depends on state created by an earlier call on the same node.

WebSocket connections are inherently sticky because they maintain a single long-lived TCP connection to one backend. Sticky sessions are only relevant for HTTP requests.

How It Works

  1. First request (no cookie) -- the load balancer picks a healthy backend node, serves the response, and returns a Set-Cookie header:

    Text
    Set-Cookie: DWSESSION=<node-id>; Path=/; Max-Age=604800; SameSite=Lax
  2. Subsequent requests -- your HTTP client sends the cookie back. The load balancer routes the request to the same node. No new Set-Cookie is returned when the session is maintained.

  3. Cookie expiry -- the cookie is valid for 7 days (Max-Age=604800). After that, the next request is treated as a first request and a new node is assigned.

Usage Examples

cURL

Bash
# Step 1: Make the first request and save the cookie
curl -c cookies.txt -X POST \
  -H "Content-Type: application/json" \
  https://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY \
  -d '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"fromBlock":"latest"}],"id":1}'

# Step 2: Subsequent requests reuse the cookie
curl -b cookies.txt -X POST \
  -H "Content-Type: application/json" \
  https://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY \
  -d '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x1"],"id":2}'

Python (requests)

Python
import requests

url = "https://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY"

# Use a Session -- it stores and sends cookies automatically
session = requests.Session()

# First request receives the DWSESSION cookie
response = session.post(url, json={
    "jsonrpc": "2.0",
    "method": "eth_newFilter",
    "params": [{"fromBlock": "latest"}],
    "id": 1
})
filter_id = response.json()["result"]

# Subsequent requests send the cookie and hit the same node
response = session.post(url, json={
    "jsonrpc": "2.0",
    "method": "eth_getFilterChanges",
    "params": [filter_id],
    "id": 2
})

JavaScript (fetch)

JavaScript
// In browsers, fetch sends cookies automatically with credentials: "include"
const url = "https://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY";

const response = await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  credentials: "include",
  body: JSON.stringify({
    jsonrpc: "2.0",
    method: "eth_newFilter",
    params: [{ fromBlock: "latest" }],
    id: 1,
  }),
});

const { result: filterId } = await response.json();

// The browser stores the DWSESSION cookie and sends it on the next request
const changes = await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  credentials: "include",
  body: JSON.stringify({
    jsonrpc: "2.0",
    method: "eth_getFilterChanges",
    params: [filterId],
    id: 2,
  }),
});

Node.js (ethers.js / web3.js)

Standard provider classes in ethers.js and web3.js do not send cookies. If your workflow requires sticky sessions from a Node.js backend, use a cookie-aware HTTP client like the Python requests.Session example above, or use a WebSocket connection which is inherently sticky:

JavaScript
import { WebSocketProvider } from "ethers";

// WebSocket connections are always sticky -- single TCP connection to one node
const provider = new WebSocketProvider(
  "wss://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY"
);

const filterId = await provider.send("eth_newFilter", [
  { fromBlock: "latest" },
]);
const changes = await provider.send("eth_getFilterChanges", [filterId]);

Important Notes

  • Health takes priority -- if your pinned node becomes unhealthy (e.g., falls behind on block height), the load balancer may route you to a different node and return a new Set-Cookie. This is by design to avoid sending requests to a degraded node.
  • Not a guarantee -- sticky sessions are best-effort. Always handle the case where your session-dependent call fails (e.g., filter not found) by re-creating the filter.
  • WebSocket is simpler -- if your use case allows it, prefer WebSocket connections. They are inherently sticky and also support server-pushed subscriptions like eth_subscribe.
  • Cookie scope -- the DWSESSION cookie is scoped to Path=/, so it applies to all requests to the same endpoint domain. If you use multiple chains, each domain gets its own independent cookie.