You suspend an account. The Admin Console says it worked. You go back to the user list to check, and there it is, still active.
So you refresh. Still active. You start wondering whether your tool is caching something, whether the change actually applied, whether you clicked the wrong row. Then you look again a minute later and it is fine.
Nothing was broken. You were reading a different view from the one you wrote to, and it had not caught up yet.
The short answer
Two different reads, two different answers. Looking an account up directly and finding it in a list are not the same operation, and they do not update at the same time.
A direct account lookup is effectively instant. In 25 trials we could never catch it showing the old value — it had already changed by the time our first read came back, under about 1.2 seconds.
A search or filtered list took about eleven seconds, every single time. Median 11.3 seconds, and every one of 25 trials landed between 10.9 and 11.7.
It does not flicker. Once the new value appeared it stayed. Zero regressions across 50 measurements.
But Google only promises "up to 36 hours". Its published expectation for the searchable view is far more conservative than what we measured, and that gap matters if you are building anything — see below.
So the honest rule of thumb for a single-attribute change to one account: the change is real immediately, and any list showing it is about eleven seconds behind. Treat that as what to expect, never as what to rely on. The operation we timed was an unsuspend rather than a suspend — our test accounts sit suspended, so that is the direction that was repeatable across 25 clean trials. It is one attribute flipping on one existing account either way, but we have not put a stopwatch on the suspend direction and are not going to imply we did.
Why there are two answers
Google's Directory API gives you two different ways to ask about a user.
Fetch the account directly, by address. This reads the account record itself. It is what the Admin Console does when you open one person's page.
Search or list, with a filter — everyone suspended, everyone in an organizational unit, everyone matching a query. Google documents this as a separate operation with its own query syntax, and our measurements show that this queryable view updates separately from the account record and becomes consistent several seconds later.
The behavior is consistent with an asynchronously updated search index sitting behind the queryable view. We should be clear that this is an inference from timing, not something Google documents: Google publishes the two access paths and their behavior, not the implementation underneath them.
Almost every screen an administrator actually looks at is the second kind. User lists, filtered views, "show me everyone in this OU", the export you just ran. All of them go through the queryable path. So the read that lags is the read you spend your day looking at, and the read that is instant is the one you only use when you already know whose name to type.
That is the entire phenomenon.
What Google documents
Google is explicit that these are two different operations. Manage user accounts separates Retrieve a user — a request for one account by key — from Retrieve all users in a domain, which takes query, orderBy, and paging parameters.
More usefully, Google publishes an expectation for how current the searchable view is. From Search for users:
Most user data updates within 1 hour; however, it may take up to 36 hours for new data to be reflected in all search results.
Read that carefully, because it is doing two jobs. It tells you the searchable view is not guaranteed current. And it sets an outer bound — up to a day and a half — that is deliberately conservative and covers cases we did not test: newly created data, and consistency across all search results rather than one query for one account.
So Google has already told you the answer at the scale that matters for guarantees. What it has not told you is what actually happens on an ordinary Tuesday when you flip one attribute on one existing account, which is the situation an administrator is in roughly all of the time. That is the gap we measured.
What we measured
Environment. One Google Workspace for Education tenant. 25 trials, each on a separate never-before-touched test account, all starting from the same state (suspended, same organizational unit).
Operation. Unsuspending an account — a single attribute change, chosen because it is unambiguous and because it is something districts do in bulk.
Method. For each trial: issue the change, then poll two reads as fast as they would answer — a direct account fetch and a filtered search for the same account — recording the moment each one first returned the new value. Trials ran one at a time with a pause between them.
We recorded a bracket, not a single number: the last read that still showed the old value, and the first that showed the new one. The change happened somewhere between those two. We also measured our own floor first — how fast the reads themselves complete — because nothing below that is measurable.
Floor: about 1.2 seconds for the direct read, 0.9 for the search.
Results
| direct account fetch | search / filtered list | |
|---|---|---|
| trials | 25 | 25 |
| last read showing OLD value | never observed | 10.4s median (9.9–10.8) |
| first read showing NEW value | under 1.2s (censored — see below) | 11.3s median (10.9–11.7) |
| standard deviation | — | 0.22s |
| flickered back to old | 0 | 0 |
The direct read never once showed us the old value. All 25 trials were censored — already changed on the first read. So we cannot give you a number for it, only a ceiling: under about 1.2 seconds, which is as fast as we could look.
The queryable view is the interesting one. Not because eleven seconds is long, but because of how consistent it is. A standard deviation of 0.22 seconds across 25 trials is not what variable replication lag looks like. Random propagation scatters. This does not — every trial landed within a 0.8-second window.
That consistency suggests something running on a schedule rather than racing: a pipeline with a fixed cadence, not a queue under contention. We cannot see inside Google to confirm that, and we are not going to pretend otherwise. But if you are wondering whether waiting longer helps when a list looks wrong, the shape of this data says the answer arrives on its own timetable rather than depending on how busy anything is.
What we did not establish
One operation, one tenant, one edition. We measured a suspend on a Workspace for Education tenant. We have separately seen a group membership change take closer to two minutes to become visible — an order of magnitude longer than this. So do not take eleven seconds as a universal Google constant. Different changes clearly move at different speeds, and the number for the operation you care about may not be this one.
We did not test under load, at different times of day, or across editions. A tenant mid-way through a bulk operation is a different situation from an idle one.
We measured the API, not the Admin Console. The console is a client of the same systems, so expect the same behavior, but we did not put a stopwatch on the browser.
What this means if you are writing anything
If you have a script, an integration, or a tool that changes something and then reads it back to confirm:
Do not read back immediately and treat a mismatch as failure. You will get the old value and conclude the write failed when it succeeded. This is the single most common way this bites people.
Know which read you are doing. If you confirm by fetching the account directly, you can check almost at once. If you confirm by listing or filtering, you need to wait — about eleven seconds for this operation, longer for others.
Re-check with a bounded backoff rather than once. Name the change you expect, look for it, wait, look again, a handful of times. Then, if it still has not appeared, say the directory has not caught up — not that the operation failed. Those are different messages and the second one sends people looking for a bug that does not exist.
Do not chain a dependent bulk operation straight onto a filtered read. If step two selects its targets by querying for what step one just changed, step two is reading a stale view. Either carry the identifiers forward from step one, or wait.
Do not hard-code eleven seconds. This is the most important sentence in the article. Eleven seconds is what we measured, not what Google promises — and what Google promises is up to 36 hours. A sleep of fifteen seconds will work almost every time and fail in exactly the situation you will not be watching. Wait for the condition, with a timeout; do not wait for a duration.
What this means if you are just an administrator
A list showing the old value briefly is normal. It is not your tool, not your browser cache, and not a failed change.
Verify a single change by opening the person's record, not by looking for them in a filtered list. The direct view is the one that is current.
After a bulk change, give it a moment before you count. Counting immediately gives you a number that is partly before and partly after, which is worse than either.
If something still looks stale well beyond that, then start investigating. In this operation and this environment the list view caught up at around eleven seconds every time. A result still stale minutes later is worth a look — but note that Google's own published expectation is far wider than what we measured, and elapsed time on its own is not evidence that the original write failed.
Common mistakes
Concluding the write failed. It did not. The read is behind.
Blaming caching. Reasonable guess, wrong. This is not an HTTP cache, and refreshing harder does not help.
Assuming one number covers everything. Group membership behaved very differently from a suspend in our experience. Measure the operation you actually care about.
Treating a mid-flight count as a result. During bulk work, a count is a moment, not a fact.
Sources
The timing figures above are our own measurement. Google's documentation of the two read paths, and of its own guarantee:
- Manage user accounts — Google for Developers. Separates retrieving one user from retrieving a filtered list.
- Search for users — Google for Developers. Documents the
querysyntax and the "1 hour, up to 36 hours" expectation. users.list— Google for Developers.
Related field guides
We built the measurement because we needed the answer ourselves: a tool that reports "done" and then shows you a list contradicting it is worse than one that waits. What ORINEX Workspace does.