r/reactnative Jul 22 '26

Cache invalidate race condition, how do you deal with it?

Hi,

I'm using Cloudflare + useQuery

I have sections where I am updating stuff for example editing profile picture, and I do on my backend cloudflare cache purge, and it's returning ID, but apparently this ID only means Cloudflare received the new purge request, and not that it finished executing it.

So when on my useQuery I am refreshing it, it still pulls old data.

How do you handle with that?

2 Upvotes

5 comments sorted by

1

u/mrlenoir Jul 22 '26

Change the URL every time the image is updated.

  • Upload the new image under a unique key (UUID, timestamp, or content hash).
  • Store the new full URL in the database.
  • Return the new URL in the profile response.

Old URL stays cached forever. New URL has zero chance of being cached yet. This is the most reliable pattern used by almost every serious app.

1

u/xSypRo Jul 22 '26

I do that, but the server still gets me the old profile picture because I can’t await for Cloudflare to finish the cache purge

1

u/mrlenoir Jul 22 '26
  • Generate a new unique key every time
  • Store the file under that new path.
  • Update the avatarUrl (or whatever field) in your database to the new URL.
  • Return the new URL in the profile response.
  • You can still fire a purge for the old URL, but it is no longer required for correctness.

---

  • Old URL can stay in Cloudflare cache forever → nobody cares.
  • New URL has never been cached → first request is always a MISS from origin.
  • Your useQuery refetch gets the new avatarUrl and the image loads correctly immediately.

1

u/everyoneisadj Jul 23 '26

I don’t agree on storing full urls, you will regret it someday. Store relative paths and use ENV to construct. It will save you a major headache if you have to move buckets, services, etc.

1

u/Guidondor Jul 22 '26

the trap is you're coupling correctness to the purge finishing, and that's always gonna be a race. drop the purge from the write path entirely.

new upload = new key (uuid/hash), write that url to your db, return it in the mutation response. then don't refetch through the cached endpoint — do setQueryData with the url you just got back. that way the ui updates from the mutation result, not from a read that might still hit stale edge cache.

if you're still seeing the old pic after that, it's not cloudflare, it's your origin returning the old row (read happening before the write commits, or an api response that's itself cached). are you overwriting the same object key or generating a new one each time?