1 · The three families
Every custom variable in Adobe Analytics belongs to one of three families. They look similar in
code — they're all just properties of s — but they behave differently in the
reporting database. Confusing them is the most common cause of "the numbers don't match"
escalations.
| Family | Purpose | Slots | Querystring |
|---|---|---|---|
| Props | Traffic dimensions — what was on the page | 1–75 | c1=…c75 |
| eVars | Conversion dimensions — what caused success | 1–250 | v1=…v250 |
| Events | Metrics — count of things that happened | 1–1000 | events=event1,event2… |
The mental model: props describe the page; eVars describe the cause; events are the count. A product detail page is described by props (category = "telescopes"), the SKU that led to a sale is captured by an eVar (eVar4 = "ASTRO-3000"), and the act of viewing it is incremented by an event (event1 = "Product View").
2 · Props — traffic variables
Props are simple. They report on the hit they fire with — nothing more. A prop set on a page view shows up in reports as the value for that page view's row.
s.prop1 = "logged-in";
s.prop4 = "telescopes";
s.prop15 = "homepage-hero-v3";
s.t();
If the same user later loads a new page and you don't set prop1 again, prop1 is empty on the next hit. Props don't remember. They report only on the hit that carried them.
Because props don't persist, they're cheap to process and fast to report. Use them for things you want sliced against page views: site sections, login state, page templates, search keywords. Don't use them for conversion attribution — that's what eVars are for.
2.1 — Pathing on props
Props have one unique superpower: they can enable pathing. When pathing is enabled on a prop, Adobe stores not just the value, but the sequence of values across a visit. This produces the Pathing reports — "Next Page Flow," "Fallout," "Previous Value."
You enable pathing per-prop in the Admin Console (Report Suites → Edit Settings → Traffic → Traffic Variables). Once enabled, that prop produces pathing reports for that report suite.
Pathing has a cost: it's computed at hit time. Enabling it on too many props slows your report suite. Pick deliberately — usually pageName, site section, and one or two business-specific flows.
2.2 — List props
A regular prop carries one value. A list prop carries many, comma-delimited, and each value is reported as its own row. Useful for things that genuinely co-occur on one page: all tags on an article, all filters applied to a search.
// Article tagged "science", "space", "telescopes" on one page
s.prop10 = "science,space,telescopes";
// In the prop10 report, each tag gets credit for one page view
The delimiter is configurable in Admin Console. The default is comma. If your values contain commas naturally (e.g. "Smith, John"), change the delimiter to a pipe and adjust your code.
3 · eVars — conversion variables
eVars are how Adobe Analytics models attribution. An eVar set on one hit can persist to later hits, where it then gets credit for events that fire there. This is the entire foundation of "Revenue by Last Internal Campaign" and similar reports.
// Hit 1 — page view
s.eVar15 = "homepage-hero-summer-sale"; // tracks the campaign
s.t();
// Hit 2 — later, on checkout, no eVar15 set
s.events = "purchase";
s.purchaseID = "ORD-9981";
s.t();
In the eVar15 report, "homepage-hero-summer-sale" will show 1 purchase and the order's revenue — even though eVar15 was not on the hit that fired the purchase event. That's persistence.
Persistence is governed by two settings on each eVar, both configured in the Admin Console: allocation and expiration.
4 · Allocation — who gets credit?
Imagine eVar15 was set to two different campaign names during one visit. Then a purchase happened. Which campaign value gets credit for the revenue? Allocation answers that.
| Allocation | Behaviour | Use case |
|---|---|---|
| Most Recent (Last) | Default. The last value set before the event wins all credit. | Last-touch attribution. "What did the user see right before they bought?" |
| Original Value (First) | The first non-empty value of the session wins, and never changes after. | First-touch attribution. "What introduced the user to us?" |
| Linear | Every value that was set during the period gets equal fractional credit. | Multi-touch view. Each campaign gets 1/N of the revenue. |
Allocation cannot be changed retroactively. The value is baked into the eVar at the report-suite level, and it applies from the moment you change it forward. Pick wisely up front.
Setting the same eVar twice within the same hit. AA only sees the final assignment — the intermediate value is lost. If you need to capture both, use two eVars or concatenate values deliberately.
5 · Expiration — how long does it persist?
Expiration tells AA when to "forget" the eVar value. The default is Visit, but you can choose anything from one hit to never.
| Setting | Lifetime |
|---|---|
| Page View | Cleared at the end of the hit it fired on (rarely useful — same as a prop minus pathing) |
| Visit | Cleared when the visit ends (30 min of inactivity, default) |
| Day / Week / Month / Quarter / Year | Calendar-based, in the report suite's time zone |
| Visitor | Never expires — persists until the visitor cookie does |
| On event (event1, purchase, etc.) | Expires when a chosen event fires. e.g. campaign eVar expires on "purchase". |
"Expire on event" is powerful and underused. A classic pattern: campaign eVar set to "Most Recent" allocation, expiring on the purchase event. The user clicks a Google Ads campaign, browses for a week, then buys — the campaign value persists across all those visits and finally credits the purchase. The moment the purchase fires, the eVar resets, so the next browsing session starts clean.
5.1 — Worked example
The same user touches the site four times across two visits:
Visit 1 (Tuesday)
Hit A: eVar15 = "google-paid-summer" → page view
Hit B: no eVar15 set → page view
Hit C: eVar15 = "email-newsletter-08" → page view
Visit 2 (Friday)
Hit D: no eVar15 set, events = "purchase" → checkout
With allocation = Last, expiration = Visit:
- Visit 1's pageviews show their respective campaign values.
- Visit 2's purchase is credited to nothing — the eVar expired with Visit 1.
With allocation = Last, expiration = on event "purchase":
- Visit 2's purchase is credited to email-newsletter-08 — the most recent value, persisted across visits, expiring now.
That single configuration change rewrites how every campaign report reads.
6 · Events
Events are metrics — counts, sums, or counters. They are configured in the report suite as one of four types:
| Type | Behaviour | Example |
|---|---|---|
| Counter | Adds 1 every time the event fires. Default. | event1 = "Add to Cart" |
| Numeric | Adds the value you pass. | event2=12.50 = "Shipping cost" |
| Currency | Adds value, formatted as currency. | event3=89.99 = "Donation amount" |
| Unique (counter variant) | Counts only once per visitor / visit, configurable. | event5 = "First-time donor" |
Syntax for the wire:
// Counter — just name it
s.events = "event1";
// Numeric or currency — name + value
s.events = "event2=12.50";
// Multiple events at once — comma-delimited
s.events = "event1,event2=12.50,event3=89.99";
There are also standard events baked in: prodView,
scAdd, scOpen, scRemove, scView,
scCheckout, purchase. They behave like counters with a special role in
the Products report — particularly purchase, which is the only event that registers
revenue, units, and orders from the products string.
7 · Event serialization
Serialization solves "double-count this event if the page is refreshed." Tell AA: this event has an ID; if you ever see the same ID again, ignore it.
// Without serialization — a browser refresh counts the purchase twice
s.events = "purchase";
s.purchaseID = "ORD-9981";
// With explicit serialization
s.events = "purchase:ORD-9981";
// You can serialize any event, not just purchase
s.events = "event5:LEAD-2025-04-1199";
The syntax is eventName:uniqueID. AA keeps that ID for ~30 days and dedupes any
hit that arrives with the same ID. Two patterns are common:
- purchaseID — the dedicated mechanism for the purchase event. Always use it. A confirmation page that the user bookmarks and reloads must not double-count revenue.
- Custom serialization — for any event where duplication is possible (lead form, signup, milestone). Generate a stable unique ID server-side and emit it.
8 · Merchandising eVars
The hardest variable type in AA. A merchandising eVar binds itself to a specific product, so when revenue arrives later, the eVar credits the right SKU.
Example. A user opens two product pages in one visit:
// Page 1 — viewing the telescope
s.pageName = "PDP: Astro-3000";
s.products = ";ASTRO-3000;;;;eVar20=organic-search";
s.events = "prodView";
s.t();
// Page 2 — viewing the camera, arrived via paid ad
s.pageName = "PDP: AstroCam";
s.products = ";ASTROCAM;;;;eVar20=google-paid";
s.events = "prodView";
s.t();
// Page 3 — purchase, two items
s.products = ";ASTRO-3000;1;299.00,;ASTROCAM;1;599.00";
s.events = "purchase";
s.purchaseID = "ORD-1122";
s.t();
With eVar20 configured as a Product Syntax merchandising eVar, the report shows:
- ASTRO-3000 revenue ($299) credited to
organic-search - ASTROCAM revenue ($599) credited to
google-paid
A non-merchandising eVar20 would credit both products' revenue to the last value ("google-paid"), because that's how regular allocation works. Merchandising binds the value to a specific product across hits.
When a user can have multiple products in flight at once, and you need to attribute each product back to a different cause. Cart products coming from different campaigns. Multi-product affiliate sources. Plan ahead — merchandising eVars are configured at the report-suite level and re-configuring them later does not retroactively fix data.
9 · Hierarchy variables
Five slots (hier1 to hier5) designed to capture site structure as a
single path string. They produce a drill-down report — useful for sites with a deep, stable
information architecture.
s.hier1 = "Shop|Telescopes|Refractor|Astro-3000";
// Delimiter is configurable in Admin; default is the pipe character.
The Hierarchy report lets you click "Shop" → see Telescopes / Cameras / Mounts → click Telescopes → see Refractor / Reflector. It's a tree.
Hier variables are powerful but under-used because most modern sites prefer flat eVars per level (eVar1 = section, eVar2 = sub-section, eVar3 = product) — which gives more flexibility in Workspace. Pick one approach; don't double-instrument.
10 · List variables
Three slots (list1, list2, list3) — like list props, but
on the eVar side: persistent, allocated, expirable. Each value in the delimited list gets
attributed independently.
// User filters search by three criteria
s.list1 = "color:blue,size:medium,brand:acme";
// Wire format: l1=…
// Each criterion shows in the list1 report as its own row
Configure delimiter and expiration in Admin Console → List Variables. Maximum 100 values per hit per list var.
11 · Lab 05 — Variable mechanics, hands-on
The sandbox is fully wired. Edit, run, and watch the hit decode. Every exercise below is solvable in this lab — try each before peeking at the next.
Run the code below. You'll see two hits in the network panel: a page view that sets eVar15, and a later purchase event that does not set eVar15. In a real implementation, Adobe's servers would attribute the purchase to "summer-sale" because eVar15 persists. The sandbox shows you the raw wire — it can't replay server-side allocation, but it can show you that the variable is not on the second hit and the event is. That's the entire premise of conversion variables.
11.1 — Exercises
Numeric event
Replace events = "purchase" with a multi-event string that also fires
event50=4.99 (shipping cost). Verify both events appear in the decoded
events= parameter.
Merchandising syntax
Re-write Hit 2 so the products string carries a merchandising eVar20 value
of "organic-search". Reference section 8.
Serialize the purchase
Change Hit 3's events to use serialization syntax. Verify events=purchase:ORD-44210
on the wire.
Build a list var
Add s.list1 = "blue,medium,acme" to Hit 2. Verify the l1
parameter on the decoded hit.
12 · Checkpoint
You should now be able to:
- Pick prop vs eVar vs event for any given business question.
- Choose allocation (last / first / linear) and explain the consequence.
- Set expiration on event for cross-visit attribution.
- Serialize an event correctly.
- Read a
productsstring with merchandising syntax. - Know when to reach for hier and list variables.
This is the conceptual ceiling of Adobe Analytics. Everything from module 06 onward — link tracking, SPA, mobile, Web SDK — is delivery mechanisms for the variables you understand now.