How is persistence achieved for clients that do not support cookies (mobile apps, API clients)?
Short answer
Persistence is bound to another value that the client sends in every request. The most flexible way is to use, as the Hash key in Hash persistence, a Smart Variable that gives the value of an HTTP header (e.g. X-Client-ID, API key, Authorization); docs also recommends header-based Hash for API clients. The HDR or URL Param algorithms also select a server according to a header or a URL parameter. The client IP is used as a last resort. Since New cookie, Current cookie and SAM require cookies, they do not work for these clients.
Problem: The Client Does Not Store Cookies
Mobile apps, API clients, IoT devices and server-to-server integrations often do not store cookies or open a new connection for every request. Since the cookie added by TR7 or produced by the application does not come back, cookie-based persistence does not work; the requests are distributed across the servers and the session information kept locally on the server is lost.
Solution: Six Methods
| Your situation | Suitable method |
|---|---|
| There is a header that carries the client identity; the mapping must be preserved | Method 1: Hash + header key |
| There is a header; a hash without keeping a table is enough | Method 2: HDR algorithm |
| The identity is in a URL parameter | Method 3: URL Param algorithm |
| There is no value that identifies the client | Method 4: Client IP |
| TCP (TLS passthrough, RDP) traffic | Method 5: Hash / RDP Cookie on L7 TCP |
| I want to do it from the command line | Method 6: WEB-CLI |
Method 1: Hash + Header Key Recommended
- How it works The value of the specified header becomes the key; on the first request, the Backend Service selected by the algorithm is written to the table, and requests with the same value go there until the duration expires.
- Where it is opened vService → Edit → Details → LB Algorithm box → Persistence → Hash → Hash Key
- Requirement The client must send the same header in every request
- vService type HTTP
Step-by-Step Configuration
On the Load Balancer → Load Balancer vService List screen, the HTTP vService is selected and Edit is clicked.
In the Details → LB Algorithm box, it is checked that an algorithm that is not self-persistent (e.g. Round Robin, Least Connection) is selected.
Hash is selected in the Persistence field.
The Hash Key list opens with the first suitable Smart Variable; in the row, the variable that gives the content of a request header is selected and the header name (e.g. X-Client-ID) is written (HTTP Header Info). For long values (e.g. the JWT in Authorization), a short and stable value is produced by adding the Hash or JWT Payload Query function to the key (functions).
Hash Key List Size (default 3,000,000; 10,000 – 100,000,000) and Hash Key Expire Time (default 7 days; 10 min – 365 days) are adjusted if needed.
Save is clicked. The Hash table is device-local and is rebuilt when the vService is reloaded; while Clustering is on and Manual Sync Mode is off (default), the settings are transferred to the peer device automatically.
Verification
Several requests are sent with the same header value (e.g. from the client, curl -I -H "X-Client-ID: abc" https://192.0.2.80/); the Backend Service column is checked on the HTTP Logs screen.
Same value → same Backend ServiceMethod 2: HDR Algorithm
- How it works The server is selected with the hash of the value of the specified header; no table is kept. Requests without the header are distributed with round robin.
- Where it is opened vService → Edit → Details → LB Algorithm → HDR
- Requirement The client must send the same header in every request
- vService type HTTP
Step-by-Step Configuration
On the Load Balancer → Load Balancer vService List screen, the HTTP vService is selected and Edit is clicked.
In the Details → LB Algorithm box, HDR is selected in the Algorithm field and the header name (e.g. X-Client-ID) is written in the required HDR Name field. When HDR is selected, the Persistence field is hidden.
Save is clicked.
Verification
Several requests are sent with the same header value (e.g. from the client, curl -I -H "X-Client-ID: abc" https://192.0.2.80/); the Backend Service column is checked on the HTTP Logs screen.
Same value → same Backend ServiceMethod 3: URL Param Algorithm
- How it works The server is selected with the hash of the value of the specified URL parameter; if Check Post Parameters is on, the parameter is also searched for in the POST body.
- Where it is opened vService → Edit → Details → LB Algorithm → URL Param
- Requirement The identity must be present in a URL parameter (or in the POST body) in every request
- vService type HTTP
Step-by-Step Configuration
On the Load Balancer → Load Balancer vService List screen, the HTTP vService is selected and Edit is clicked.
In the Details → LB Algorithm box, URL Param is selected in the Algorithm field, and the parameter name (e.g. client_id) is written in the required URL Parameter to Use field; if needed, Check Post Parameters is turned on (off by default).
Save is clicked.
Verification
Several requests are sent with the same parameter value and the Backend Service column is checked in HTTP Logs.
Same value → same Backend ServiceMethod 4: Client IP
- How it works Persistence is bound to the client's IP address. On mobile clients, the IP changes as the network changes; users behind a NAT gather on a single server.
- Where it is opened HTTP: LB Algorithm → Source or Persistence → Hash + client IP address · Network: L4 Persistence
- Requirement The client IPs must be fixed and diverse
- vService type All
Step-by-Step Configuration
If there is a proxy or CDN in front of TR7, a Trusted Proxies profile is required to resolve the real client IP (HTTP vService only); otherwise, steps 1–3 and 5 are skipped. Load Balancer → Profiles → Trusted Proxies → Add is clicked.
A profile name is entered in the Trusted Proxy Profile Name field; Real IP from is selected and the IP ranges of the proxy or CDN are entered as CIDR in the Trusted Networks field.
The Add button in the form is clicked.
On the Load Balancer → Load Balancer vService List screen, the vService is selected and Edit is clicked.
In the Details panel, Trusted Proxy is checked and the profile created in steps 1–3 is selected in the Trusted Proxy Profile field (How to add to a vService). After the profile is assigned, the Client IP Address variable in the Hash key carries the resolved real client IP; the Real client IP (trusted proxy) variable, on the other hand, is the address of the proxy in front and is not used as the key. Details: There is a CDN such as Cloudflare / Akamai in front of TR7; how do I get the Real client IP (trusted proxy)?
In the LB Algorithm box: on an HTTP vService, the Source algorithm or the client IP address key in Hash persistence; on L7 TCP, Hash + client IP address; on Network, L4 Persistence is used.
Save is clicked.
Verification
It is seen in HTTP Logs that the requests coming from the same IP go to the same Backend Service.
Same IP → same Backend ServiceMethod 5: Hash / RDP Cookie on L7 TCP
- How it works On L7 TCP, Hash produces a key from connection-level values such as SNI, JA4 and the client IP; for RDP clients, the RDP Cookie algorithm selects a server according to the cookie in the RDP connection.
- Where it is opened L7 TCP vService → Details → LB Algorithm box
- Requirement The value that will be the key must be present in every connection
- vService type L7 TCP
Step-by-Step Configuration
On the Load Balancer → Load Balancer vService List screen, the L7 TCP vService is selected and Edit is clicked.
In the Details → LB Algorithm box, Persistence → Hash is selected and a suitable connection variable is added to the Hash Key list, or for RDP, Algorithm → RDP Cookie is selected and mstshash is written in the required RDP cookie name field.
Save is clicked.
Verification
On the TCP Logs screen, the server column of the same client's connections is checked.
Same key → same serverMethod 6: WEB-CLI
- How it works Persistence and the algorithm are written from the command line.
- Where it is opened TR7 WEB-CLI →
lb service update - Requirement WEB-CLI access
- vService type HTTP, L7 TCP
Step-by-Step Configuration
The Server persistence fields are written; the vService ID is written in place of <vService> (Tab lists them). The key is given in Smart Variable format; for header content, %REQHEADER(header-name) is used, and since it contains parentheses, it is written in single quotes:
lb service update id <vService> --persistence dynamicPersistence --dynamicPersistenceKeys.0 '%REQHEADER(X-Client-ID)'.0 writes the first key in the list; if the vService already has a Hash key, it replaces the first key. The existing keys are seen with lb service show <vService>.
The algorithm and the required name field are written together with the Distribution algorithm field:
lb service update id <vService> --algorithm hdr --hdrName X-Client-IDVerification
The persistence and algorithm fields are checked in the lb service show <vService> output.
Persistence dynamicPersistence (Hash)Unsuitable Methods
- New cookie / Current cookie: They do not work if the client does not send the cookie back.
- Session Affinity Manager (SAM): Requests that do not carry a cookie are not recorded in the session table.
- Cookie Based Connection Persistency action: It is cookie-based.
Common Mistakes
- Overlooking that the key header does not arrive in every request. Requests without the header share the same empty key and gather on a single server.
- Using a long token directly as the key. It is recommended to produce a short and stable value with the Hash or JWT Payload Query function.
- Looking for Hash while a self-persistent algorithm is selected. While HDR, URL Param or Source is selected, the Persistence field does not appear; for Hash, an algorithm other than these is selected.
- Relying on IP-based persistence for mobile clients. The IP changes as the network changes.
How it is done in the documentation
