Every UHF RFID tag on the planet holds a small piece of internal state that rarely gets any attention. It lacks a battery, has a minimal processor, and contains just enough silicon to store an EPC number. Yet hidden within its memory are four single-bit indicators known as session flags, and grasping how they function is what separates a system that smoothly reads 500 tags from one that struggles with just 50.
If you have ever seen a reader count the same tag repeatedly, or questioned why two readers aimed at the same group of tags seem to clash with one another, the explanation almost always comes down to sessions. This concept is built into the EPC Gen2 standard (ISO 18000-63), and it controls something essential: how a reader determines which tags it has already communicated with and which ones it has not.
Here is the core challenge. A UHF RFID reader does not single out tags one by one the way a barcode scanner focuses on a single label. Rather, it broadcasts a signal and listens for replies. When tens or hundreds of tags answer at once, signal collisions occur. The reader needs a structured way to work through the entire group: communicate with one tag, set it aside, then proceed to the next. That structured process is called an inventory round, and sessions are what make inventory rounds function.
The Anti-Collision Challenge
Every EPC Gen2 tag keeps four session flags, designated S0 through S3. Each flag exists in one of two states: A or B. When a reader starts an inventory round, it picks a session and signals the tag group that it wants to communicate with tags whose flag for that session is currently set to A. Each time a tag is successfully singulated (read individually without a collision), it switches its flag from A to B. Once a tag is in state B for that session, it no longer responds to queries targeting that session. The reader continues through the group until no more A-state tags reply, at which point the round ends.
Straightforward in concept. The real complexity lies in what happens afterward.
Persistence: How Long Does the “Already Read” State Hold?
The four sessions differ significantly in how long they retain their state. S0 is highly volatile. A tag’s S0 flag flips back from B to A almost as soon as the reader’s RF field disappears, often within just a few milliseconds. S1 holds its state for a brief window, generally between 500 milliseconds and 5 seconds depending on the specific tag. S2 and S3 are the long-lasting options: their flags remain set for a minimum of 2 seconds and can persist considerably longer, with the Gen2 specification permitting retention of minutes or more depending on how the tag is implemented.
Why is persistence important? Because it defines what “already read” actually means in a real-world setting.
Picture a conveyor belt setup where items pass through a read zone over a second or two. The goal is to read each tag exactly once, reliably, without duplicates. S1 works well here. The reader performs its inventory using S1, tags switch to B as they are read, and by the time they leave the read zone, the flag has not yet reset. One read per tag. Had you used S0 instead, tags would flip back to A nearly instantly, causing the reader to count them over and over for as long as they stayed within range.
Now imagine a warehouse with stationary readers installed at dock doors, where a forklift occasionally passes through carrying a pallet. In this case, S2 or S3 would be a better fit, since tags read at one door will not immediately show up again at the next door a few seconds later. The extended persistence creates a window during which those tags remain silent for downstream readers.
Multi-Reader Coexistence
This is where things get particularly interesting in environments with multiple readers. The session mechanism was designed in part to allow several readers to operate on the same tag population without interfering with one another. If Reader A runs its inventory on S2 and Reader B uses S3, each maintains independent flag state on every tag. What Reader A does has no effect on how tags respond to Reader B, and the reverse is also true. They can work at the same time on overlapping tag groups without conflict, at least as far as sessions are concerned.
In real-world deployments, RF interference and dense reader mode (DRM) protocols introduce additional layers of complexity, but session separation remains the logical foundation that makes coexistence achievable.
Ping-Ponging and Continuous Monitoring
There is a subtle detail here that trips many people up. When a reader transmits a Query command to start an inventory round, it specifies three parameters that determine which tags take part: the session, the target state (A or B), and optionally a select mask to filter by EPC or other memory content. The target parameter is what allows a reader to intentionally inventory tags in state B. A widely used pattern is to alternate: inventory tags from A to B, then from B back to A, and keep repeating. This “ping-pong” method enables ongoing monitoring of a tag population because tags that were set aside in one round become available again in the next, without depending on flag persistence timers.
Ping-ponging on S0 is the most straightforward continuous-read approach. Since S0 resets so rapidly, a reader using S0 with target A will naturally pick up all tags again each round regardless. But deliberately ping-ponging on S1, S2, or S3 gives you finer control. You can track which tags appeared in each round, identify tags that have left the area (they stop toggling), and build event-driven logic on top of the raw read data.
This is where your session choice begins to shape the overall application architecture, not just the RF behavior. A system that needs to detect when tags arrive and when they leave (a portal reader, for instance) will perform very differently depending on whether it relies on S0 with rapid re-reads and software-level deduplication, or on S2 with alternating targets and firmware-managed state tracking. Neither method is universally superior. The best option depends on how fast tags are moving, how large the population is, how many readers are deployed, and how much processing you want to handle at the edge versus in middleware.
Pre-Filtering with Select
One more concept worth knowing: the select command. Before launching an inventory round, a reader can send Select commands that adjust session flags on specific subsets of the tag population based on EPC, TID, or user memory content. This is how you pre-filter a group before inventory, essentially instructing certain tags to switch to state A or B for a given session before the Query command is even issued. When used together with sessions, Select provides a powerful (if occasionally finicky) set of tools for dividing and sequencing reads across large or mixed tag populations.
If you want to observe how sessions and flag states interact in real time without needing any hardware on hand, I created an interactive session demo that simulates two readers operating on a single tag. You can see how each reader’s session choice independently affects the tag’s flag states, and understand precisely why session separation is critical for multi-reader coexistence. It turns abstract protocol mechanics into something tangible in a way that specification documents seldom manage.
The Gen2 session mechanism is one of those protocol-level details that distinguishes people who simply configure RFID systems from people who truly understand them. Most commercial middleware conceals it behind “automatic” mode settings, and for basic applications that works perfectly well. But when read rates decline, when duplicate reads surge, or when two readers begin competing for the same tags, sessions are almost always part of the root cause. Understanding how they work gives you the vocabulary to ask the right questions and a mental framework for predicting how a system will perform before you ever switch it on.



