# Visitors (/docs/tracking/visitors)

## The visitor cookie [#the-visitor-cookie]

A visitor is a random id in the first-party `obelism_visitor_id` cookie: `visi_` and 26 characters, kept for 30 days from the last visit. The Improve SDK uses the same cookie, so a visitor in a test and in numbers is the same one. The old `visitorId` cookie is still read and written while the rename settles, so a site with an older Improve SDK doesn't count one person as two.

A visitor is **new** on their first visit and **recurring** after that. With the SDK, `numbers.visitor()` returns `{ id, recurring }`.

## Counting without a cookie [#counting-without-a-cookie]

A site that doesn't want to ask for analytics consent can count without a cookie:

- `storage: 'session'` (or `data-storage="session"`) keeps the id in sessionStorage for the tab: a visitor stays one visitor across pages, and starts new in a new tab or window.
- `storage: 'none'` (or `data-storage="none"`) makes a new id on every client, so every full page load in a site that isn't a single-page app. Visits and page views still count, but each page looks like a new visitor.

Neither sets a cookie. `session` does write to the device's sessionStorage, which ePrivacy generally treats like a cookie — it is not automatically consent-free; `none` stores nothing. `none` also starts a new session on every load, so most page views count as bounces and unique visitors stop being meaningful.

## Sessions [#sessions]

A session ends after 30 minutes without an event. A **bounce** is a session of one page view and nothing else, counted out of the sessions with a page view. Both are worked out when you read the report, from the events themselves.

## Device [#device]

The client sorts each visitor into categories from the user agent and screen, never the full user agent:

| Field     | Values                                                                       |
| --------- | ---------------------------------------------------------------------------- |
| `device`  | `desktop`, `mobile`, `tablet`, `console`, `smarttv`, `wearable`, `embedded`  |
| `browser` | `chrome`, `safari`, `firefox`, `edge`, `samsung internet`, `social`, `other` |
| `os`      | `mac os`, `ios`, `android`, `windows`, `unix`                                |
| `screen`  | `small`, `medium`, `large`, `huge`                                           |
| `pointer` | `fine` or `coarse`                                                           |

Pass your own with the SDK's `device` option or `setDevice`.

## Country [#country]

The country comes from the request's network location, as Cloudflare reports it. The IP address itself is not stored: it is only used to rate limit, for a minute.
