# F5 persistence: why the same user must hit the same server

Source: https://ai.techclick.in/blog_f5_ltm_persistence_cookie_source_addr
Markdown: https://ai.techclick.in/blog_f5_ltm_persistence_cookie_source_addr.md
Publisher: Techclick Infosec Pvt Ltd

Learn F5 BIG-IP cookie persistence vs source-address affinity. Fix users stuck on a down member, read persist-records, and set Action On Service Down.

## The ticket

 Same HR portal as the SNAT lesson:  hr.techclick-lab.in  on VIP  203.0.113.25 . Users log in. The next click either shows an empty session or sends them back to the login page. The application team says “it works if you pin the user to one server.” The network team says “F5 is load balancing — that is what it is supposed to do.”

 Both sentences are half-true. Load balancing picks a member for a  new  session. Persistence says “this is not a new session — send it back to the member that already has the user’s data.”

   Quick interview answer

   Persistence tracks which pool member already serviced this client and sends the rest of the session there, so the client can bypass a new load-balancing decision. F5 stores that pointer in a persistence profile on the virtual server. Cookie persistence puts the pointer in an HTTP cookie. Source address affinity (simple persistence) uses only the client IP. If the member later goes down,  Action On Service Down  on the pool decides whether the user stays stuck or is reselected.

   Hero · stickiness is not load balancing

   First request can pick either member. Persistence makes request 2, 3 and 4 return to the same one.

## What persistence actually is

 F5’s own words: when you enable session persistence, BIG-IP “tracks and stores session data, such as the specific pool member that serviced a client request,” so later requests go to the  same  member for the life of the session.

 That is the whole idea. The pool still has two (or ten) members. Load balancing still exists. Persistence is a  memory  that sits in front of the load-balancing method.

   Flow 1 · first request vs next request

       First request is load balanced; later requests follow the persist record

- User login POST VIP 203.0.113.25 no persist yet Round robin pick member .41 10.20.30.41 session cart / login state Same user, click 2 cookie or src-IP Skip load balance use persist pointer Back to .41 not a new pick of .42 Later requests If click 2 lands on .42 , persistence did not fire — or the pointer was pointing at the wrong thing. Say this out loud Load balancing answers “who gets a brand-new session?” Persistence answers “who already owns this session?” If you mix those two questions, every later command will be read wrong. Pre-train the words before the GUI: #### Persistence profile The object that says how F5 remembers the member (cookie, source IP, dest IP, SSL session ID, universal…). #### Default persistence The profile attached on the virtual server. Applies to sessions on that VIP unless an iRule overrides it. #### Fallback persistence Plan B if the primary key is missing (example: cookie not present → use source-addr). #### persist-records The table on BIG-IP for methods that store the pointer on the box . Cookie insert often stores the pointer on the browser instead. Lab data · dummy only VIP 203.0.113.25:443 · VS vs_hr_https · pool pool_hr_80 · members 10.20.30.41:80 , .42:80 · cookie profile persist_hr_cookie · source-addr fallback persist_hr_src . Not a live customer. ## Cookie vs source-addr vs dest-addr How to choose Cookie is per browser. Source-addr is per client IP. Dest-addr is per destination IP (rare on inbound HTTP VIPs). Official BIG-IP types you will actually use on an HTTP VIP: Type F5 also calls it What it keys on Use when Main lie Cookie HTTP cookie persistence A cookie in the HTTP header (often BIGipServerpool_hr_80 ) Web apps, shopping carts, login sessions Needs an HTTP profile. Invisible on FastL4. Browser can drop the cookie. Source address affinity Simple persistence Client source IP (plus optional mask) TCP/UDP apps with no HTTP cookie, or fallback A proxy / CGNAT / Zscaler egress makes 200 users look like one IP. Destination address affinity Sticky persistence Destination IP of the packet Outbound / cache-style designs Wrong tool for “keep this user on one HR server.” Universal / hash — Any bytes you name (iRule / hash of fields) SIP, custom headers, multi-field keys Hash persistence is not allowed on FastL4. SSL persistence — SSL session ID on non-terminated SSL Passthrough TLS where you cannot see HTTP Does not help if you already terminate TLS on a client-ssl profile. Cookie itself has four methods. Students mix them in interviews: Cookie method Who writes the cookie persist-records on F5? HTTP Cookie Insert BIG-IP inserts BIGipServer  Usually no — the browser holds the pointer HTTP Cookie Rewrite Server sends a cookie; F5 rewrites it. F5 K83419154 prefers this when you need a record on the box. Yes HTTP Cookie Passive Server cookie, F5 does not change it Uses the server cookie value Cookie Hash Named cookie is hashed into a record Yes — this is the cookie method that fills persist-records Weak vs strong interview line Weak: “We use persistence so load balancing works.” That sentence is backwards. Strong: “We use persistence so a stateful app does not get a new member mid-session. Cookie insert for HTTP. Source-addr only as fallback or for non-HTTP. I check Action On Service Down so a down member does not keep the cookie.” ## How you configure it Three objects. Always in this order. Side A is the profile. Side B is the virtual server. Side C is the pool behaviour when the member dies. ### Side A — build the persistence profile GUI path from F5 docs and the standard TMOS tree: Local Traffic → Profiles → Persistence → Create . https://bigip-lab.techclick-lab.in/tmui/…/ltm/profile/persist Training mock · not live Local Traffic → Profiles → Persistence → Create ### New Persistence Profile Name persist_hr_cookie Persistence Type Cookie Cookie Method HTTP Cookie Insert Cookie Name BIGipServerpool_hr_80 Expiration Session Cookie (browser close) Always Send Cookie Enabled Cancel Finished Source: F5 Session Persistence Profiles — assign a persistence profile to a virtual server. Cookie insert uses the HTTP cookie header. Dummy lab names only. Side A · dummy tmsh tmsh create ltm persistence cookie persist_hr_cookie \ cookie-name BIGipServerpool_hr_80 \ method insert \ expiration 0:0:0:0:0:0 \ always-send enabled tmsh create ltm persistence source-addr persist_hr_src \ timeout 180 \ mask 255.255.255.255 ### Side B — attach it on the virtual server GUI: Local Traffic → Virtual Servers → vs_hr_https → Resources . Fields: Default Persistence Profile and Fallback Persistence Profile . The VS also needs an HTTP profile or cookie insert has nothing to read or write. https://bigip-lab.techclick-lab.in/tmui/…/ltm/virtual_server/vs_hr_https?tab=resources Training mock · not live Local Traffic → Virtual Servers → vs_hr_https → Resources ### Resources Default Pool pool_hr_80 Default Persistence Profile persist_hr_cookie Fallback Persistence Profile persist_hr_src HTTP Profile (on Properties / Profiles) http Cancel Update Source: F5 persistence chapter — “the primary tool is to configure a persistence profile and assign it to a virtual server.” Fallback is plan B if the cookie is missing. Side B · dummy tmsh tmsh modify ltm virtual vs_hr_https \ persist replace-all-with { persist_hr_cookie { default yes } } \ fallback-persistence persist_hr_src \ profiles add { http { } } ### Side C — what happens when the member dies This is the setting students forget. It lives on the pool , not on the persist profile: Action On Service Down (K15095). Default behaviour leaves existing sessions on the member that just went down. New sessions go elsewhere. The cookie still says “.41” — so the user stays on a corpse. #### None (default) Keep using the persisted member even after the monitor marks it down. This is the “stuck on dead member” ticket.

- #### Reselect Pick another up member and rebind the client. Use this for HTTP apps where the session can be rebuilt or is stored in a shared DB.

- #### Reject / Drop Reset or silently drop. Brutal, but honest — the user is not silently talking to a dead box.

  Side C · dummy tmsh  tmsh modify ltm pool pool_hr_80 \
    service-down-action reselect

tmsh list ltm pool pool_hr_80 service-down-action
ltm pool pool_hr_80 {
    service-down-action reselect
}

## Four persistence failures

 Read the explanation, then the CLI. The command only confirms the story.

### 1 · User stuck on a down member

  What this is.  Member  .41  was green when the user logged in. Cookie / source-addr still points at  .41 . The monitor later marks  .41  down. Action On Service Down is None. The user keeps going to a dead member.  .42  is green and unused for that user.

  What you see.  Pool shows one member down, one up. The VIP may stay available. That one user (or that one source IP) fails. Other new users are fine on  .42 .

   Stuck on the down member

   Green pool is not the same as “this user’s pointer is healthy.” Persistence can outlive the member.

  Broken · persist still names the down member · dummy  tmsh show ltm pool pool_hr_80 members
Ltm::Pool Member: pool_hr_80/10.20.30.41:80
  Status.Availability : offline
  Status.Reason       : monitor /Common/http_hr down
Ltm::Pool Member: pool_hr_80/10.20.30.42:80
  Status.Availability : available

tmsh show ltm persistence persist-records mode source-address virtual vs_hr_https
Sys::Persistent Connections
source-address  198.51.100.80  ->  10.20.30.41:80  (age 142)

# Cookie insert: look at the browser instead
# Set-Cookie: BIGipServerpool_hr_80=1677787402.20480.0000; path=/

  Takeaway.  Change Action On Service Down to Reselect  or  delete that persist record / tell the user to drop the cookie after you accept the session will rebuild.

### 2 · Source-addr behind a proxy — 200 users, one server

  What this is.  Source address affinity keys on client IP. Office traffic, Zscaler / SWG, or CGNAT makes hundreds of laptops share  198.51.100.80 . F5 treats them as one client. One pool member takes the entire floor.

  What you see.   persist-records  has one fat source-addr entry. Member connections are wildly uneven. Cookie persist would have spread them, because each browser has its own cookie.

  Broken · one source IP owns the pool · dummy  tmsh show ltm persistence persist-records mode source-address
Sys::Persistent Connections
source-address  198.51.100.80  ->  10.20.30.41:80  (age 1800)   # 214 mirrored sessions

tmsh show ltm pool pool_hr_80 members
  10.20.30.41:80   current-sessions 214
  10.20.30.42:80   current-sessions 3

  Takeaway.  For HTTP, prefer cookie. If you must use source-addr, tighten the mask only when the IPs are truly unique — a  /24  mask makes this worse, not better, when the whole office is one /24.

### 3 · Cookie persist on a FastL4 / no HTTP profile

  What this is.  Cookie persistence “uses the HTTP cookie header.” A Performance (Layer 4) / FastL4 virtual does not parse HTTP. Hash persistence is officially disallowed on FastL4. The profile may be attached, but F5 never sees  Cookie:  or writes  Set-Cookie .

  What you see.  Login works (TCP is fine). Next request is a new load-balance pick. Browser has no  BIGipServer  cookie.  persist-records  is empty. Students blame the app.

  Broken · standard VS missing HTTP, or FastL4 · dummy  tmsh list ltm virtual vs_hr_https profiles
ltm virtual vs_hr_https {
    profiles {
        fastL4 { }
        # no http profile — cookie persist cannot fire
    }
    persist {
        persist_hr_cookie { default yes }
    }
}

# From the laptop (dummy):
# curl -vk https://hr.techclick-lab.in/app -D- | grep -i set-cookie
# (empty)

  Takeaway.  Cookie persist needs a Standard virtual + HTTP profile. FastL4 can do source-addr / dest-addr / universal — not cookie, not hash.

### 4 · Cookie missing and no fallback — mid-session hop

  What this is.  Cookie insert is primary. The browser never stores it (IT policy, wrong path, HTTP cookie on an HTTPS site, user in a private window that dropped it, or the app overwrote  Set-Cookie ). There is no fallback profile. Request 2 is a new round-robin pick. Login state lives only on  .41 .

  What you see.  Intermittent. Some browsers work. Some do not. Incognito fails. Mobile app fails. Desktop Chrome works.

  Broken · no cookie, no fallback · dummy  tmsh list ltm virtual vs_hr_https persist fallback-persistence
ltm virtual vs_hr_https {
    persist { persist_hr_cookie { default yes } }
    # fallback-persistence missing
}

# After you add fallback:
tmsh modify ltm virtual vs_hr_https fallback-persistence persist_hr_src

  Takeaway.  Cookie first, source-addr fallback, and still check Action On Service Down. OneConnect (next lesson in this series) can also make F5 re-evaluate persistence on every HTTP request inside one TCP connection — that is a feature, not a mystery, once you expect it.

## How to prove it

   Proof cockpit

   Proof is three artefacts: the profile on the VS, the cookie or persist-record, and the member the user actually landed on.

   Flow 2 · prove the pointer before you change config

       Five proof steps for persistence

- 1. list persist on the VS 2. HTTP profile? not FastL4 3. cookie or record browser / tmsh 4. member health is pointer down? 5. service-down reselect? Do not delete persist-records as step 1. First prove what the pointer is, then decide if it is allowed to move. Proof ladder · dummy tmsh list ltm virtual vs_hr_https persist fallback-persistence profiles tmsh list ltm persistence cookie persist_hr_cookie tmsh show ltm persistence persist-records virtual vs_hr_https tmsh show ltm persistence persist-records mode source-address client-addr 198.51.100.80 tmsh show ltm pool pool_hr_80 members tmsh list ltm pool pool_hr_80 service-down-action # Delete ONE bad pointer after change-control (not the whole table) tmsh delete ltm persistence persist-records \ mode source-address client-addr 198.51.100.80 virtual vs_hr_https Proof the change worked VS lists persist_hr_cookie as default and persist_hr_src as fallback.

- VS has an HTTP profile (not FastL4-only).

- Browser shows Set-Cookie: BIGipServerpool_hr_80=… on the first HTTPS response.

- Two clicks from the same browser land on the same member (connection table or app log).

- If you mark .41 down in the lab, Action On Service Down = reselect sends the next request to .42 .

- You did not delete persist-records for the whole box as a first fix.

## Traps

     Trap  Looks like  First proof  Do not

      Empty persist-records with cookie insert  “Persistence is broken”  Look at the browser cookie. Insert stores the pointer there.  Switch to source-addr just because the table is empty.
      Source-addr + shared egress IP  One server hot, one idle   persist-records  count vs unique users  Add more members to “fix load.”
      Cookie on FastL4  Random member every click   list ltm virtual … profiles   Rebuild the pool.
      Action On Service Down = None  One user broken, pool half-green  Record still names the down member  Reboot the healthy member.
      Timeout too short  Cart dies after lunch  Profile timeout vs idle time  Blame the database first.
      OneConnect + persist  “Same TCP, different member”  F5 can re-LB each HTTP request when OneConnect is on  Call it a TMM bug on day one.

  Interview close:  “Persistence is a pointer, not a load-balancing method. I name the key (cookie or source IP), I prove it with the cookie or persist-records, and I name Action On Service Down so a down member cannot keep the pointer.”

## Knowledge check

   Eight judgment questions. Pick one answer, then Check. Reasons name the section to re-read.

       Q1
       What does persistence do on a BIG-IP virtual server?

           It replaces the pool so only one member can ever be used
           It remembers which pool member already owns this session and skips a new load-balance pick
           It changes the source IP toward the server (SNAT)
           It is the same as a health monitor

       Correct:  b . Re-read “What persistence actually is.” SNAT is a different lesson.

       Q2
       Cookie insert is configured, but the browser never gets a  BIGipServer  cookie. The virtual uses only a FastL4 profile. What is the first fix?

           Add more pool members
           Disable SNAT
           Use a Standard virtual with an HTTP profile — cookie persist cannot parse FastL4
           Set Action On Service Down to Drop

       Correct:  c . Failure 3. Hash persist is also disallowed on FastL4.

       Q3
       Office users behind one Zscaler / proxy IP all land on member  .41 . Persistence type is source-addr. What happened?

           Hundreds of users share one source IP, so they share one persist key
           The VIP address is wrong
           Cookie insert always pins a whole office
           The monitor send string is case-sensitive

       Correct:  a . Failure 2. Cookie persist would have given each browser its own key.

       Q4
       Member  .41  is monitor-down. One user still fails. New users on  .42  are fine. persist-records still maps that user to  .41 . What should you look at first?

           Rebuild both servers
           The self-IP netmask
           Whether HTTP/2 is enabled
           Pool Action On Service Down — default None keeps the pointer on the corpse

       Correct:  d . Failure 1 and K15095. Reselect (or reject) is the pool-side answer.

       Q5
        tmsh show ltm persistence persist-records  is empty. Cookie method is HTTP Cookie Insert and users are fine. What is true?

           Persistence is off; you must enable source-addr
           Insert usually stores the pointer in the browser cookie, not in the persist table
           You must reboot TMM to populate the table
           Empty table always means FastL4

       Correct:  b . Cookie Hash / Rewrite are the cookie methods that create records on the box.

       Q6
       Some browsers keep the session. Incognito and a mobile app hop to the other member after login. Cookie is primary. What is the missing object?

           Fallback persistence (source-addr) when the cookie is absent
           A second VIP address
           Destination address affinity as default
           Disabling the HTTP profile

       Correct:  a . Failure 4. Fallback is plan B, not a replacement for cookie on HTTP.

       Q7
       Which official statement is true about hash persistence?

           It is required on every FastL4 VIP
           It is the same as SNAT Automap
           You cannot associate hash persistence with a virtual managing Fast L4 traffic
           Hash persistence ignores pool member state forever

       Correct:  c . F5 Session Persistence Profiles — “use of hash persistence for Fast L4 traffic is disallowed.”

       Q8
       You need to clear one bad source-addr pointer after change-control. Safest dummy command shape?

            tmsh delete ltm pool pool_hr_80
            tmsh reboot
            tmsh delete ltm persistence persist-records  with no filters
            tmsh delete ltm persistence persist-records mode source-address client-addr &lt;that-ip&gt; virtual vs_hr_https

       Correct:  d . Official persist-records syntax filters by client-addr / mode / virtual. A bare delete wipes every pointer on the box.

       Check answers
       Reset

  F5 LTM series:
 F5 LTM troubleshooting path  ·
 F5 SNAT concept and issues  ·
 F5 cookie vs source-address persistence  ·
 F5 SSL offload vs passthrough .

## Sources

- F5 TechDocs: Session Persistence Profiles — definition, cookie / source-addr / dest-addr / hash / universal / SSL; hash not allowed on FastL4; OneConnect changes per-request LB.

- F5 tmsh: ltm persistence persist-records — show / delete by mode, client-addr, virtual, node.

- F5 K15095 — Action On Service Down (pool) rebinds or keeps the client on a down member.

- F5 K83419154 — cookie persistence overview; Rewrite creates a persist record on BIG-IP.

- Techclick Fast Track PDF — green objects, user still fails; isolate before you change config.

 Related:  SNAT concept and issues  ·  User-to-VIP / firewall / iRule lab  ·  Virtual servers and pools  ·  Command ladder .

  Series (1 of 10):  Persistence → SSL offload → Health monitors → Load-balancing methods → HA failover → tcpdump both VLANs → FastL4 vs Standard → iRule Host/URI switch → GTM vs LTM → ASM blocking vs transparent.

---
Cite this Techclick lesson with the source URL. Do not invent fees, batch dates, or job guarantees.
Browse all lessons: https://ai.techclick.in/blogs
AI index: https://ai.techclick.in/llms.txt
