A session groups the events your app sends into one period of user activity, so you can analyze behavior per visit: how long users stay, what they do in a single sitting, and in which visit a conversion happened. The Treasure AI mobile SDKs (Android, iOS, Unity, Cordova, and React Native) provide two session mechanisms — instance sessions and global sessions — that differ in scope, in the columns they write, and in whether they record session start and end events. This page defines both mechanisms, shows what each writes to your tables, and helps you choose the right one. For installation and general event tracking, see the individual SDK pages linked in Session APIs by SDK.
An instance session is scoped to one TreasureData instance. Starting it records an explicit start event, and ending it records an explicit end event, in a table you specify. A global session is shared across every TreasureData instance in the app. It records no events of its own; instead, it stamps a shared td_session_id on every event tracked while it is active, and it can resume after a short interruption so that brief app switches count as one session.
| Aspect | Instance Session | Global Session |
|---|---|---|
| Scope | One TreasureData instance | The whole app — shared across all TreasureData instances |
| How you start and end it | Instance methods that take a table name, for example startSession("demotbl") and endSession("demotbl") | Static (class-level) methods with no table argument, for example TreasureData.startSession(context) and TreasureData.endSession(context) on Android |
Records td_session_event start and end events | Yes — one record at start and one at end, in the table you specify | No — a global session never writes any event by itself |
Adds td_session_id to tracked events | Yes, while the session is active | Yes, while the session is active. If both session types are active, the global session ID wins |
| Designed for | Explicit session boundaries with start and end records — for example, tracking a checkout flow as a unit | Treating short interruptions (screen rotation, brief app switches) as one continuous session, using the session timeout |
There is no separate SDK-managed session table. Sessions add columns to the tables you already stream events into:
td_session_id— a UUID string identifying the session. The SDK adds it automatically to every event tracked while a session is active.td_session_event—startorend. Written only by instance sessions:startSessionandendSessioneach add one record containing this column to the table you pass them.
For example, calling startSession("demotbl") and later endSession("demotbl") produces two records in demotbl:
[
{"td_session_id": "cad88260-67b4-0242-1329-2650772a66b1", "td_session_event": "start", "time": 1418880000},
{"td_session_id": "cad88260-67b4-0242-1329-2650772a66b1", "td_session_event": "end", "time": 1418880123}
]Any other event you track between those two calls carries the same td_session_id in whatever table you send it to. You can pass your main event table to startSession and endSession so that boundaries and events live together, or use a dedicated table for the start and end records — either way, you analyze a session by grouping events on td_session_id. Optional columns such as td_uuid (device ID) appear alongside if you enable them; see About Mobile Tracking and Mobile SDKs.
A global session does not end immediately when you call the global endSession. The session ID is retained for the length of the session timeout — 10 seconds by default. If your app calls the global startSession again within that window, the previous session resumes with the same td_session_id; a new session is not created. After the window passes, the next startSession generates a new session ID. This is what lets a session survive an Android Activity being destroyed and recreated, or a user briefly switching away from the app.
Key behaviors:
- On Android and iOS, change the window with
TreasureData.setSessionTimeoutMilli(...)before starting the session. On Unity, the resume window is 10 seconds. - After the global
endSession, the globalgetSessionIdreturnsnull, even while the session can still resume. - Call
resetSessionId(Android and iOS) to generate a new global session ID immediately, so subsequent events are no longer associated with the previous session. - Session IDs are held in memory only. If the app process is killed, the current session ID is discarded and the next launch starts a new session, regardless of the timeout.
- The SDKs never start or end sessions on their own, and a session does not expire from inactivity while the app stays in the foreground. A session ends only when your app calls
endSessionor the process terminates. Call the session APIs from your app lifecycle callbacks — for exampleonStart/onStopon Android, orapplicationDidBecomeActive:/applicationDidEnterBackground:on iOS.
A common convention in web and app analytics is a 30-minute inactivity window. To get that behavior, set the timeout to 30 minutes and start/end the global session when the app enters and leaves the foreground:
// Android — in onCreate
TreasureData.setSessionTimeoutMilli(30 * 60 * 1000); // 30 minutes
// in onStart / when the app enters the foreground
TreasureData.startSession(this);
// in onStop / when the app leaves the foreground
TreasureData.endSession(this);
TreasureData.sharedInstance().uploadEvents();With this configuration, foreground visits separated by less than 30 minutes share one td_session_id, and returning after 30 or more minutes (or after the process was killed) starts a new session.
Only instance sessions write td_session_event records. The global startSession and endSession change which td_session_id is stamped on events, but they do not send any event — so if you track sessions only with the global API, your tables contain no explicit start or end records.
If you manage sessions with the global API and also need boundary events — for example, to analyze session starts or to trigger downstream logic — record them yourself with addEvent at the same points where you start and end the session:
// Android
TreasureData.startSession(this);
Map<String, Object> event = new HashMap<>();
event.put("event", "session_start");
TreasureData.sharedInstance().addEvent("demotbl", event);Because the global session is active, the record automatically carries the current td_session_id.
Note the interaction with the session timeout: if the user leaves and returns within the timeout window, each visit produces its own start and end records, but they all share one td_session_id, because the SDK resumed the same session. This is expected — the records mark each foreground visit, and the shared ID groups those visits into one session. If you want every visit to be its own session instead, shorten the timeout or call resetSessionId before starting the new session.
Avoid running both session types at the same time. If an instance session and a global session are both active, the global session wins: every tracked event — including the start and end records written by the instance startSession and endSession — carries the global session's td_session_id, and the instance session's ID is ignored. The SDK logs a warning when this happens. The two IDs are independent, differently generated values; the instance session's ID is simply never written while a global session is active.
Pick one mechanism per app: the global session when you want one app-wide session that survives short interruptions, or instance sessions when you want explicit start and end records without extra code.
The method names differ by SDK. The Cordova and React Native plugins expose instance sessions only.
| SDK | Instance Session | Global Session |
|---|---|---|
| Android | startSession(table), endSession(table), getSessionId() | TreasureData.startSession(context), TreasureData.endSession(context), TreasureData.getSessionId(context), TreasureData.setSessionTimeoutMilli(millis), TreasureData.resetSessionId(context) |
| iOS | startSession:, endSession:, getSessionId | [TreasureData startSession], [TreasureData endSession], [TreasureData getSessionId], [TreasureData setSessionTimeoutMilli:], [TreasureData resetSessionId] |
| Unity | StartSession(tableName), EndSession(tableName), GetSessionId() | StartGlobalSession(), EndGlobalSession(), GetGlobalSessionId() |
| Cordova | startSession(sessionTable, sessionDatabase), endSession(sessionTable, sessionDatabase) | Not exposed by the plugin |
| React Native | startSession(sessionTable, sessionDatabase), endSession(sessionTable, sessionDatabase) | Not exposed by the plugin |
Global sessions never write td_session_event. Only the instance startSession(table) and endSession(table) methods record start and end events. If you use the global session API and need boundary records, add them yourself with addEvent — see Recording session_start and session_end Events.
Yes. Session IDs are held in memory only, so force-quitting the app (or the OS terminating the process) discards the current global session ID. The next launch starts a new session with a new td_session_id, even if it happens within the session timeout window.
They can technically both be active, but the SDK logs a warning and the instance session's ID is ignored: all events, including the instance session's own start and end records, carry the global td_session_id. Use one mechanism per app — see Using Global and Instance Sessions Together.
Use the mechanism that matches what you need recorded. If your in-app messaging logic triggers on explicit session start and end events, instance sessions provide them automatically; with the global session you must record boundary events yourself. See Mobile In-App Messaging for how the trigger flow works.
Yes. If your events already have timestamps and a user or device identifier, the TD_SESSIONIZE_WINDOW window function assigns session IDs at query time using an inactivity timeout you choose. See TD_SESSIONIZE_WINDOW in the Trino function reference.
- Android SDK — full lifecycle code examples
- iOS SDK — Objective-C and Swift examples
- Unity SDK — global and instance session usage
- About Mobile Tracking and Mobile SDKs — SDK features and account setup