Sticky reads after a write, and the window they cover

Routing reads to a replica is correct except immediately after a write by the same user, and the usual fix is a time window rather than a guarantee.

// after any write, this connection reads the primary for
// the rest of the request
DB::connection()->recordsHaveBeenModified();

// what it does NOT cover: the NEXT request, arriving 400ms
// later, on a different worker.

// so the window has to outlive the request:
Cache::put("primary_until:{$user->id}", now()->addSeconds(5), 10);

The per-request version is the default in most frameworks and covers the case where a controller writes and then reads, which is not the case that produces support tickets. A user who saves a form and is redirected makes a second request, and only a window that outlives the request handles it — measured against the actual replication lag rather than guessed.