Safari ITP and SaaS attribution: what the 7-day cap deletes

Safari ITP caps JavaScript cookies at 7 days, or 1 day after some ad clicks, so SaaS payments land in Direct. What it deletes and how to keep the source.

Muzahid Maruf — Founder of TrackRev.io

Muzahid MarufUpdated

Revenue attribution · 7 min read
On this page
  1. 01What Safari ITP caps and deletes
  2. 02Safari ITP attribution loss in a 14-day trial
  3. 03Which attribution setups ITP breaks
  4. 04Moving the source out of Safari's reach
  5. 05What TrackRev does with Safari traffic

Explore with AI

Opens this article inside the chosen assistant with a ready-made prompt.

Safari ITP attribution loss comes from the way Intelligent Tracking Prevention (ITP) shortens anything your site writes to the browser with JavaScript.

Since February 2019, a cookie created that way expires after 7 days, and after 1 day when a classified tracker domain sent the visitor to a URL with a query string.

A 14-day trial can reach Stripe with no source, and the payment is filed under Direct. A source stored in your own database and on the Stripe payment survives.

Key takeaways

  • ITP 2.1 capped JavaScript-written cookies at 7 days in February 2019, and ITP 2.2 cut that to 1 day after a tagged link from a classified domain.
  • Since March 2020 Safari also deletes LocalStorage, IndexedDB and other script-writable storage after 7 days of use without interaction.
  • Cookies your server sets in a response have no ITP cap, except third-party CNAME-cloaked ones, which get 7 days.
  • A day-0 signup keeps its source while the day-14 payment loses it and lands in Direct.
  • Log the click at a redirect you own, bind the email at signup and store the visitor ID in Stripe metadata.

What Safari ITP caps and deletes

Apple shipped ITP in 2017 and has added rules since.

RuleLimitsTriggerAnnounced
7-day cookie capdocument.cookie cookiesAny persistent cookie created with JavaScriptITP 2.1, Safari 12.1, iOS 12.2, Feb 21, 2019
1-day cookie capdocument.cookie cookies set on the landing pageClassified sender plus a query string or fragmentITP 2.2, iOS 12.3, Apr 24, 2019
7-day storage deletionLocalStorage, IndexedDB, SessionStorage, media keys, service workers7 days of Safari use without interactionITP 2.3 on tagged navigations, Sep 23, 2019; Safari 13.1 on every site, iOS 13.4, Mar 24, 2020
Third-party cookie blockCross-site cookiesAlways, unless the Storage Access API grants accessSafari 13.1, iOS 13.4, Mar 24, 2020
CNAME cloaking capCookies set in HTTP responses, capped at 7 daysA subresource resolves through a third-party CNAMESafari 14, iOS 14, Nov 12, 2020

Dates are the WebKit blog post dates.

A machine learning model picks the classified domains, and WebKit's tracking prevention page publishes no list, so you cannot check a campaign in advance.

Tagged links always meet the query-string condition, which leaves the sender to decide whether the 1-day cap applies.

Cookies set in an HTTP response

WebKit limited the 2019 caps to cookies created through document.cookie, so a cookie your server sets in a response keeps its expiry, with or without the HttpOnly flag.

The exception is CNAME cloaking: cookies set in responses from a subdomain such as track.blog.example that resolves to tracker.example get 7 days.

Apple's definition covers subresources, and I found nothing from Apple on a top-level redirect through a vendor domain, so read the cookie's expiry in Safari if your tracking subdomain points at a vendor.

Safari ITP attribution loss in a 14-day trial

A visitor clicks a tagged newsletter link in Safari, starts a trial in the same session and pays on day 14. The day-0 signup carries its source.

What the payment finds depends on the gap since the last page view that ran your pixel.

Last page view with your pixelCookie expires after a normal view (7-day cap)Cookie expires after a tagged landing from a classified domain (1-day cap)
Day 0Day 7Day 1
Day 5Day 12Day 6
Day 8Day 15Day 9
Day 12Day 19Day 13
Day 14Day 21Day 15

The payment lands on day 14, so a cookie that expires on day 14 or earlier is already gone. Assumes the pixel rewrites its cookie on every page view.

A prospect who ignores the onboarding emails and pays on the day-14 reminder is the first row: the cookie is gone, the charge lands in Direct and the click row at your redirect is untouched.

Paid social is the likeliest to meet both conditions of the 1-day cap, since a social app is a plausible classified sender and ad URLs carry parameters.

For scale, Statcounter's September 2026 data puts Safari at 18.27% of worldwide browser usage and 46.38% of US mobile usage. Your customer mix sets the real figure.

Take 80 new customers every month at $79 each, 40% of them on Safari, with Direct absorbing every lost source.

Safari customers losing their sourceFiled as DirectMRR12-month revenue
25%8$632$7,584
50%16$1,264$15,168
75%24$1,896$22,752

Invented numbers: 80 new customers per month, 40% on Safari (32), each paying $79 monthly for 12 months.

Which attribution setups ITP breaks

Where the source livesExpiry in Safari
Cookie your pixel writes with JavaScript7 days, or 1 day after a tagged landing from a classified domain
UTM tags in LocalStorage or SessionStorageDeleted after 7 days of Safari use without interaction
Cookie your server sets on your own domainNo cap since ITP 2.1
Cookie from a subdomain that CNAMEs to a vendor7 days when it counts as CNAME cloaking
Third-party cookie on a vendor domainBlocked since Safari 13.1
Click row or visitor ID in your database or Stripe metadataOutside the browser; Stripe takes 50 keys of 500 characters

Link Tracking Protection, which removes known tracking parameters from links opened in Messages, Apple Mail and Private Browsing, is a separate Apple feature, covered in iOS 17 Link Tracking Protection and what survives.

Moving the source out of Safari's reach

1. Log the click at a redirect you own

Send shared links through a short link such as go.example.com/spring-launch.

The redirect stores the click (visitor ID, link, timestamp, user agent, referrer) and sets the visitor cookie in its 302 response, with Domain set to your registrable domain, outside the script caps.

The server-side versus client-side comparison covers what that log sees.

2. Bind the email to the visitor on day 0

Read the visitor ID from the cookie your redirect set and save it in the same request that creates the user, the one moment the ID and the email arrive together.

A script-written cookie may not last from the click to a signup 8 days later, and an ID that never reaches the user record leaves that click unlinked.

3. Write the visitor ID onto the payment

Stripe Checkout takes a client_reference_id of up to 200 characters, and metadata allows 50 pairs with keys up to 40 characters and values up to 500. Metadata on the session stays on the session. subscription_data.metadata saves to the Subscription.

The Stripe metadata attribution setup post has a field mapping.

A Checkout Session that carries the visitor ID and UTM tags onto the subscription
// vid comes from the cookie your server set at the redirectconst click = await db.clicks.findFirstByVisitor(vid); const session = await stripe.checkout.sessions.create({  mode: "subscription",  line_items: [{ price: "price_123", quantity: 1 }],  client_reference_id: vid,  subscription_data: {    metadata: {      vid,      utm_source: click?.utmSource ?? "",      utm_medium: click?.utmMedium ?? "",      utm_campaign: click?.utmCampaign ?? "",    },  },  success_url: "https://app.example.com/welcome",  cancel_url: "https://www.example.com/pricing",});

4. Set the attribution window past the trial

Windows count back from the payment.

A trial of 14 days under a window of 30 days means a click counts only if it came within 16 days of the trial start, so a pricing-page visit 21 days earlier drops out.

Cover the trial plus your usual research time.

5. Test in Safari before you trust the numbers

The ITP 2.3 post describes ITP Debug Mode (Develop menu, Safari 13 on macOS) and a defaults command that classifies a test domain as a tracker. WebKit wrote those steps in 2019, so confirm them on your version.

WebKit says ITP Debug Mode was available in Safari Technology Preview well before regular Safari 13 got it.

From the ITP 2.3 post: classify a test domain (macOS)
defaults write com.apple.Safari ITPManualPrevalentResource sender.example

Click from that domain to a URL with a query string, write a cookie with JavaScript, and read its expiry in Web Inspector.

Then split the last 30 days of paying customers into Safari and other browsers and compare how many in each group have a source.

What TrackRev does with Safari traffic

TrackRev is SaaS affiliate software with link tracking and revenue attribution built in, so partner and campaign links share one click log.

A TrackRev link logs each click server-side and sets a vid cookie in the HTTP response, good for 365 days.

The destination URL carries the ID as _vid, and your pixel copies it into a JavaScript cookie that Safari caps at 7 days, or 1 day after a tagged landing. The pixel rewrites that cookie on every page view.

trk.identify(email) attaches an email to a known visitor.

The Stripe sync resolves a visitor from a vid in charge metadata, from the Checkout Session or from the customer's email, then credits clicks inside your attribution window (1 to 365 days, set per workspace).

Renewals copy the first order's credit.

A Safari visitor who goes quiet for more than 7 days and returns through a plain URL gets a new pixel visitor with no click behind it, so the email binds to nothing.

A signup within the same session, or a return through any tracked link, keeps the chain.

The Free plan covers 50 links and 1,000 tracked events monthly, with revenue figures hidden. Revenue by channel needs Indie at $29 a month (pricing, revenue attribution).

Skip a tool if you already write UTM tags and a click ID to Stripe metadata at checkout, as in step 3, and look at a standalone attribution product if you have no partner program to run.

Google Analytics 4 showing no revenue by channel is a separate fix, covered in GA4 not showing revenue by channel.

Found this useful? Share it.

PostLinkedIn

Frequently asked questions

Muzahid Maruf — Founder of TrackRev.io

Written by

Muzahid Maruf

Founder, TrackRev.io & Contant.io

Muzahid Maruf founded TrackRev.io, SaaS affiliate software with no limit on tracked revenue, and Contant.io. He writes about affiliate programs.

Writes about Marketing attribution · Link tracking · Revenue analytics · SaaS growth

Stop guessing where your revenue comes from.

Set up TrackRev in about five minutes. The free plan covers 1,000 events a month, no card needed.

Start free