Bob logged in and saw Alice's profile

In this controlled demo, the server caches the profile page by its address only. Alice opens her profile first, so Bob gets Alice's name, email and address when he opens his.

Technical name: Personal page cached without a per-user keyControlled demo · fake data

Why did one user see another user's profile?

Often because a personal page was cached by its address alone. The first user's page is saved, and everyone who asks for the same address gets that copy. In our controlled demo, Bob opened /profile after Alice and got Alice's name, email and address. The fix: cache personal pages per user, or keep them out of shared caches, and check permissions before serving anything cached.

How to tell if your app has this

No code needed.

  1. Log in as two test accounts in two different browsers. Open the same personal page (profile, orders, settings) in one, then the other. Each should see only their own data.
  2. Ask your AI tool: "Which pages or API responses do we cache, and does the cache key include the signed-in user?"
  3. Check your hosting or CDN caching rules for pages that show personal data. They should be private or not cached.

Before and after

Before
Demo Shop · signed in as bob
My profile
NameAlice Demo
Emailalice@demo.test
Address12 Demo Street

Bob opened his profile. He got Alice's.

After
Demo Shop · signed in as bob
My profile
NameBob Demo
Emailbob@demo.test
Address7 Sample Road

Each user gets their own page. Alice still gets hers.

Why AI-built apps end up with this

Caching is a common speed-up suggestion, and a cache keyed only by the page address works perfectly while you test alone. The problem only appears when a second user asks for the same address.

Fix it yourself

How do I fix it? Paste this into your AI tool

My app caches pages or API responses that contain personal data using only the URL as the cache key, so one user can get another user's page. Find every cache we use (server, CDN or edge). For anything with personal data, either keep it out of shared caches (send Cache-Control: private or no-store) or include the signed-in user's ID in the cache key, and check permissions before serving a cached response. Then test with two accounts that each user only sees their own data.
Works with Lovable, Bolt, Cursor, Replit and similar tools. Then run the check-up below on your own app.

How we checked the fix

Same request before and after the fix
Same requestBeforeAfter
Alice opens /profile, then Bob opens /profileBob gets Alice's pageBob gets his own page
Alice opens /profile againAlice's pageAlice's page

Results from our demo test, run against the same demo before and after the fix.

Common mistakes when fixing this

  • Clearing the cache only hides the bug until the next two users arrive.
  • Public pages can still be cached. Only personal ones need a per-user key or no shared cache.

Questions people ask

Is caching bad?

No. Caching public pages, like a landing page or a product list, is great. Personal pages need a cache key that includes the user, or no shared cache at all.

Where else can this happen?

In a CDN or edge cache in front of your app, in server-side page caching, and in API responses cached by URL.

What should personal pages send?

Responses with personal data usually send Cache-Control: private or no-store, so shared caches don't keep them. Check how your host treats these headers.

For developers: the cause and the fix in code
− cache["/profile"]
+ cache[(user_id, "/profile")]  # or no shared cache

Simplified. Your stack will look different; the principle is the same.

Learn more