Page MenuHomePhabricator

TDMP Proposal: Preference Persistence For Anonymous Users
Closed, ResolvedPublic



Problem Statement

Write your problem statement using layperson's terminology. In one sentence, what is the problem or opportunity?

  • To support WE2.1 and other similar use cases, we need a clearly-defined (but limited), performant, mechanism to provide configurable user experiences for anonymous users that require changes to the way the page is rendered.
    • WE2.1: FY23-24 Annual Planning (draft) objective 2, Key Result 1: “X% of unique devices read Wikipedia through a customized experience, in order to fit their own needs.”
    • Other similar use cases: We would like to identify a class of related problems, and solve for these together, going beyond simply the preferences explicitly called out in the KR.
    • Clearly-defined (but limited): As part of our discussion, we should spell out the scope of this mechanism: what it is and is not intended to cover.
    • Performant: Falling within explicitly-defined acceptable performance budgets
    • Configurable user experiences - allow for different user experience presentations depending on the user
    • Anonymous: this does not affect logged-in users, who have the user_properties table
    • Affect the way the page is rendered: These should be changes that need to happen before the page is loaded
  • Scope:
    • No caching changes: Currently we serve the same (usually cached) HTML to all anonymous users - any proposed solution should avoid impacting existing Varnish caching
    • No A/B tests: We should consider A/B tests to be out of scope for this solution. There may be other out of scope options/changes as well which we should discuss
    • No cross-device storage: These preferences should be specific to the device they’re stored on – cross-device preference storage is out of scope for this solution.
    • On-Wiki Storage: Though they may interact with device system settings (e.g. prefers-color-scheme), these settings will be explicitly stored on the site itself
  • To be determined:
    • What class of changes?: What is the class of change this should and shouldn’t cover?
      • E.g. binary changes only, Scalar values etc.

What does the future look like if this is achieved?

  • Impact to Movement: We have a mechanism that will enable us to deliver successfully on the FY23-24 Annual Planning OKR WE2.1 to enable customization of user experiences for anonymous users.
  • Extensibility: We have a clear, documented, constrained go-to solution for storing future client-side preferences that teams doing development on the frontend can use for a defined subset of use cases
  • Scope: We have documented and made clearly understood the circumstances under which a team would and would not use this mechanism
  • Performance Parameters: We have documented and made clearly understood the performance impact of this mechanism and how a given team would evaluate the performance risk of a given proposal

What happens if we do nothing?

  • Anonymous User Customizability: Anonymous users, who make up the bulk of users of our sites, would miss out on certain customizable user experience benefits such as page density, dark mode, and font size
    • System-level Overrides: Note that the key detail here is customizability. For dark mode specifically, and likely several other of these preferences, there are device & system-specific defaults which one can query by means of media queries such as [prefers-color-scheme]( If we do nothing, we defer automatically to these system-wide settings. That said, as currently defined, WE2.1 is about the ability to customize and override such systems-specific settings on a per-site basis - if, for example, a user wished to have system-wide dark mode but to opt out of this on-wiki, there would be no means of doing so without this kind of anonymous preference storage.
  • Reinventing the Wheel: The Web Team, or other teams looking to persist similar features, would not benefit from a unified solution in this space, and may need to individually work through any number of the following issues:
    • Flash of Unstyled Content - content appearing before styled according to the settings specified
    • Other layout shifts - applying settings after page-render may result in user-visible shifts in page layout
    • Performance impact - it is possible that teams would store preferences in a non-performant way at the wrong juncture of the critical rendering path, potentially resulting in rendering slowdowns or hits to SEO
    • Lack of unified solution - teams would otherwise need to solve the question of how to store certain preferences for anonymous users on a case-by-case basis, potentially re-inventing the wheel for every preference that needs to be stored
    • Missing go-to solution - Other teams looking to persist similar features might hesitate to implement features with this need at all, fearing that they might encounter the above consequences
    • Missing guidance - Existing, temporary measures for storing various user settings may be expanded to use cases that they are not suited for, e.g. making DOM changes in a critical render path


User Value/Organization Value AND Objective it supports and How

  • FY23-24 APP - Web Team
    • The FY23-24 OKR WE2.1 (draft) currently states: “X% of unique devices read Wikipedia through a customized experience, in order to fit their own needs.” The ability to store at very least the following preferences for anonymous users to be critical to making these possible:
    • Page density (page width)
    • Accessibility settings:
      • Dark Mode
      • Font size
  • Community Responsiveness/Wishlist
    • Dark mode was the top-voted item in the community wishlist survey, and implementing a dark-mode preference for anonymous users in a persistent way will be an important part of this
  • APP - Other Feature Teams
    • Other teams are working now through the APP process, and it would be helpful to them to know when and how they could store certain settings for affected anonymous users.
    • The Web team has been approached by several teams that would be interested in potentially storing preferences in some way

Why are you bringing this decision to the Technical Forum?

What about the scope of this problem led you and your team to seek input across departments/organizations?

  • Impact - This is intended to be a general-purpose mechanism that could be used by any team at the Foundation (provided their use case fits within our defined criteria) - thus the scope goes beyond the Web Team
  • Clarity - An initial mechanism that the Web team implemented for storing page width (see here) was made in render-blocking code, and concerns were raised about when and how this was accomplished. Providing clarity about when/how we should and should not use this mechanism – wherever possible tied to specific metrics of concern and interest – for Web and for other teams, is critical.
  • Expertise and Alternatives - It is important to solicit input from those who either need to store similar preferences or who have relevant subject-matter/domain expertise to understand what options and alternatives exist for this kind of storage


  • Web Team - will likely (pending APP approval) need to use this or similar mechanisms for work beginning FY 2023-24
  • Performance Team - will need to weigh in as to the performance implications
  • Other teams doing FE feature work - will need to weigh in as to whether and how this mechanism could be used for other frontend use cases.


  • SRE - it is our assumption that this solution, being client-side only, will not necessitate involvement of the SRE team
  • Related Designs *

Related Objects

Resolved Mabualruz
ResolvedBUG REPORTJdlrobson
ResolvedBUG REPORTSeddon

Event Timeline

I've simplified the sub-tasks so only this root epic is in the TDF tag, rather than each of the stages.

To be honest I don't understand why we can't use localStorage? Serious question. I tried to read the proposal a few times. It appears like it mixes two things:

  1. Changing the width of the page or expanding elements is something anonymous users can already do. It doesn't require a reload. All that appears to be necessary is to store these boolean flags and apply them the moment the page loads, early enough to not cause any FOUC, but late enough to not block anything. This is a solved problem.
  2. I understand that something like a proper dark mode might need preparation server-side, e.g. actually different HTML being delivered.

However, it appears like the majority of the (few) examples in the proposal fall in category 1. I think it would help to discuss the two separately.

To be honest I don't understand why we can't use localStorage? Serious question. I tried to read the proposal a few times. It appears like it mixes two things:

Details in T321498#8550182. Cookies are already primed in memory. LocalStorage isn't and this code is run in a performance-sensitive place.

I understand that something like a proper dark mode might need preparation server-side, e.g. actually different HTML being delivered.

No. Dark mode would be a CSS only change. It would require a separate stylesheet which would be controlled by a class on the HTML element that needs to be changed in a similar way before the page renders. Essentially we want to generalize the solution for the limited width feature so it can be applied to other use cases.

I would love to see some discussion of the privacy implications. Anonymous users already have a random session ID mw.user.sessionId() which is logged along with various metrics and is sticky across page views. Will we be careful to only leverage that existing session ID, or will we increase the stickiness beyond session length, or across wikis? There are considerations about data retention--will the server-side data be regularly purged and how will that affect the experience? Is the persistence lifetime extended after each reading session? Would it be possible to correlate unique combinations of preferences to probabilistically track users across a longer lifetime? Will this user preference data be protected so that only some parts of the code can access it, or will it be published to the client?

We had a great Meeting on the 27th of July 2023 Titled:

TDF Decision Records

Summary of Meeting Notes:

Topics Discussed:

  1. Preference Persistence for Anonymous Users: The meeting revolved around the implementation of preference persistence for anonymous users and the decision-making process.
  2. TDMP (Technical Decision Making Process): The discussion also touched upon issues related to the TDMP, its communication, and the need for iterative solutioning.
  3. Unblocking technical parts, how to move forward with the patches and testing.

Ideas Shared:

  1. Urgency and Communication: Attendees expressed concerns about the urgency of the decision and the need for more transparent and frequent updates.
  2. A follow-up meeting between PMs/product owners was proposed to discuss the feature and future steps.


  1. @Krinkle should leave specific comments on the proposal document.
  2. @Catrope will review the current patch.
  3. @Mabualruz and @Krinkle should agree on the problem and its assessment, then run the specific referenced test together, interpret results together, and agree on the next steps together.
  4. The Web team ( @Mabualruz ) will summarise the decision and results in the document and update the public Phabricator ticket with the chosen decision.
  5. Attendees ( @Mabualruz, @Krinkle, @KSarabia-WMF, @NHillard-WMF, @Mooeypoo) will regroup in one week's time to evaluate progress.

Action Items Tracking:


Please note that I (@Mabualruz) will be out on vacation after next week for 3 weeks ( 7th of August - 25th of August 2023 ), if any of my responsibilities are not done by then @KSarabia-WMF, @NHillard-WMF, and other members of the Web team will handle it in my absence.

@Jdlrobson Yes. If this can be signed off by @NHillard-WMF when he gets back that would be great.

Resolving - great job everyone who worked on this!
The decision has been made and posted to the decision record page here