Limiting account misuse

Account sharing for B2B publishers – part 2

So, you’ve identified that account sharing is a problem for your business. What do you do about it?

There are two distinct strategies here:

  1. You can actively make it harder to share accounts; or
  2. You can passively track the users who share their accounts, then use that data to sell more seats to the customer.

Active prevention

Prevention of account sharing also splits into two:

  1. Using authentication techniques that only the real account holder can log in with; or
  2. Limiting devices or sessions.

Authentication techniques

A quick crash course in authentication… When someone authenticates (logs in) they are presenting you with:

  • Something only they know (like a password, PIN, etc.);
  • Something they are (i.e. biometric data like a fingerprint); or
  • Something they possess (such as a phone, which can receive a token by SMS).
    • I would also include something they have access to (like an email inbox) in the last category.

The de facto (although it’s slowly changing) method for logging in to a Web site is a password. If you don’t want someone to access your online banking you set a strong password and keep it secret. But here’s the problem: if you do want to let someone else access your account (i.e. account sharing) then you can just set a weak password and tell them what it is. The responsibility for keeping others out is with the user not the vendor.

That problem is pretty hard to get around in the “something they know” family, because knowledge can be shared. If you want to actively prevent account sharing you need to leverage one of the other two systems.

Side note: this post is not particularly discussing 2-factor authentication (2FA) or multi-factor authentication (MFA) but, in a nutshell, those systems are asking for multiple authentication techniques. They do not necessarily state which techniques but it’s often a password + a token by SMS.

Authenticating someone using “something they are” is definitely an area to watch keenly. If you primarily deliver content through native apps it’s pretty easy to leverage in-device biometrics today. On the Web it’s harder as you are targeting a multitude of devices with different biometric capabilities. That said, standards are being created to work with password-less authentication, in particular the Credential Management API which allows you to use fingerprint sensors on Mac OS and Android (if the device supports them). If you want to invest early, then definitely look into these techniques and offer them for users who have a supported device. The big challenge is that you’ll probably need to support passwords too, for the foreseeable future, so a user who wants to share their account can just elect to use a password instead of their fingerprint.

So what about “something they possess”? There are a bunch of low-hanging fruit here. It’s often impractical to send a user a physical device (like an RSA key), so I’ll focus on things they already own like SIM cards (that receive SMS message), email inboxes and social media accounts. To leverage any of these authentication schemes you need to send a token using that channel that only the true owner can pick up; for social media this is codified as OAuth2.0 (it’s a similar effect, at least) but for the other two you’ll need an Identity Management tool that supports them.

The flow goes like this:

  • To log in, the user enters their email address or phone number
  • A single-use token is sent to them by email or SMS
  • They enter the token on-site or in-app to authenticate

Only the owner of the inbox or device has access to that token, so only they can log in. The user can still abuse this system by forwarding on the token but, crucially, they need to be an active participant in every single log in. Unlike password-based account sharing, where the user told their peer the password once and they then have access forever-forward, they will now need to forward on the token every time the piggyback user logs in.

If you use a “something you own” scheme, you can push account sharing further down the long tail by imposing a limit on concurrent sessions. Given that a user is only allowed to be logged in from one device at a time, and two users are trying to use your service, they will each need to log in every session – always by passing on a token from one to the other. That is such a jarring experience (and clearly tied to their illicit behaviour) that there’s a real drive to either not share or, if the value is high enough, to buy another licence.

Of course you can use this system with any means of delivery that the user would feel uncomfortable sharing. They would share a password – they wouldn’t give someone access to their inbox, their SMSs or their Facebook account.

Limiting devices

You can limit the number of devices that a customer can use to access your service by either setting a maximum number of concurrent session or by restricting the user to named devices.

Named devices are perfect for high value content. Typically, device management is used only with native apps not on the Web. Limitations of the Web mean that device’s “name” can only be pinned to a session, local storage or a device fingerprint. Sessions and local storage (unlike on a native app) are highly transient and becoming more so: cookie can be deleted, “incognito” session are used, corporations routinely clear data from their employee’s browsers.

How about pinning the “name” to a device fingerprint? That is an interesting approach but not perfect. The system works as follows:

  • A user authenticates using any scheme (let’s say a password)
  • In the background, a hash is created of static information we know about the device, like the operating system (OS), the browser, the screen size and maybe fonts and browser extensions
  • They are asked to name their device (“Work laptop”)
  • An identity management system stores the hash and name against the user
  • Subsequently, if the user logs in from a device with the same hash, they are considered to be using the “Work laptop”
  • If the user (or a piggyback user) logs in from a device with a different hash then they are asked to manage their devices.

There is a real problem with this approach, however… static data is so generic it’s not useful. Consider the OS. If a visitor users a Mac then that part of the hash is the same for every other mac user. You can’t really use data such as browser version because the “device” will change every time someone’s browser is updated: it’s not static data.

Building an effective fingerprint is hard, to the point that it cannot really work standalone. But this might be a useful technique to deploy in conjunction with other tactics, such as “something you have” authentication.

For the Web, the simplest way to limit devices is a concurrent session limit. This is similar to the flow for named devices but it’s completely opaque to the user. If you allow 2 concurrent sessions, and the user logs in from a third browser, then the oldest session in deleted. The user cannot choose which session is deleted, because they are unnamed. Again, this is not going to stop account misuse but it will require bad actors to log in more frequently, so could be coupled with a password-less authentication scheme.

Passive Tracking

It’s definitely useful leverage, when trying to negotiate an increase at renewal time, if you can categorically prove that the customer has bought 10 seats but 30 of their employees use the service. Be aware that you need users to abuse their accounts to get that benefit, so don’t rush block account sharing.

There are a number of metrics you can track to get an indicator of account sharing. All publishers of high-value B2B content absolutely need to report on concurrent sessions – that’s the low hanging fruit – but you can also look at unique IP addresses per user and other dimensions that are likely to be small for a real user. Building these kinds of report is usually pretty straight forward (and was covered in the previous post) but know that it will need to be based upon server log data or your IAM’s reporting if you want to see IP addresses.

The pay off

At Zephr, we have seen B2B publishers tackle the issue of account sharing head on. It’s really not that hard to go from it being trivially easy for a user to abuse their licence to it being quite difficult and explicitly fraudulent. We have seen huge revenue uplifts attributed to these drives and prove a bunch of tools for the publisher to leverage.

This is never going to be one-size-fits-all but being conscious of the cost of the problem is essential. And know that there are things you can do to deter this behaviour.

The cost of account sharing

Account sharing for B2B publishers – part 1

Account sharing is incredibly prevalent across the whole digital subscriptions space. Maybe you let a mate of yours use one of your Netflix family profiles. Perhaps there’s a SaaS tool you find really useful and you shared your login to it with a colleague because it was easier than getting a corporate licence. “Password123” anyone? Whatever the transgression, few of us can honestly deny we misuse our subscription accounts from time-to-time.

There are three parties in this situation. For this post I’ll refer to them as:

  • “the service” – which is the vendor offering the subscription;
  • “the subscriber” – who is the user that actually pays the subscription; and,
  • “the piggyback user” – who is using the subscriber’s account to access the service but never actually paid for the right to do so.

To begin to quantify the problem, somewhere between 30% and 40% of all subscribers to music streaming services share their login with at least one person, according to a survey of over 12,000 people carried out in 2017. That’s huge.

So, what’s the impact of account misuse? For B2Cs account sharing can be seen (if you squint) as a good thing. It’s word-of-mouth sales. The piggyback user is building the service into their habits and routines and, at some point, will probably need to actually sign up; if they don’t they weren’t getting value out of the service anyway.

That advantage doesn’t necessarily carry over to B2B, however. In general, a B2B subscription is for a substantially higher fee and the customer base is much smaller. A smaller market means that the word-of-mouth growth from piggyback users won’t have the scale to become viral (there are some obvious exceptions which are widely horizontal, like Slack). This is compounded as the cost of the piggyback user, the loss of potential revenue, is much greater.

I asked Tony Skeggs, CTIO of Private Equity International, for his view:

“[The cost of account misuse] is not an insignificant amount. Enough to justify setting up a claims team to track client behaviour and … claim back revenue.”

I’m sure that’s a position many B2B publishers share.

Now, every business is different and it’s dangerous to generalize (particularly with domain-focused B2B publishers) so there are two questions you should be asking yourself: “how big is the problem for me?” and “what can be done about it?”. The first question is the focus of this post, the second will be covered in part 2.

How big is the problem?

As with most difficult questions, this is multi-facetted. You need to know, at least:

  • How many users are regularly sharing their account?
  • What proportion of the piggyback users would otherwise convert into customers?
  • What would it have cost to identify the piggyback users as net-new leads?

The last point, in particular, draws attention to the balance here: account sharing is not bad in an absolute sense, it’s just probably responsible for an overall loss, in the case of most B2B publishers.

How many users are regularly sharing their account?

To the first question, it is tricky to accurately estimate the number of users who share accounts. However you can see tell-tale signs of account sharing if you have a decent BI tool in place or some access to server logs. This really needs a statistician to analyse – and is beyond the scope of this post- but if you want to properly understand how to identify account misuse you should read up on the Gaussian Mixture Model and similar clustering techniques.

In a nutshell, you will look for patterns in accounts that have an unusually high number of concurrent sessions or access the service from more IP addresses or geographies than normal users.

What proportion of piggyback users could be converted to customers?

This question is also non-trivial. You do know these people actually consume your product, though, so it’s a fairly safe bet that they would convert at least as well as an MQL – and you probably have that ratio already.

If you want to get  a better feel for this you are going to have to run some experiments. You’ll need to be creative and this will take investment. One tactic, for example, is to identify the 1000 accounts which use the most IP addresses then target them with a promotion to “invite a colleague and they get 1 month free”. If you can track the signups from that campaign you have a list of leads that are likely to have previously been piggyback users – then you just need to sell to them and track your success!

What would it have cost to identify the piggyback users as net-new leads?

This should be a fairly easy calculation, as if they weren’t piggyback users they would be marketing targets. What’s your marketing spend per MQL? This should be a known stat.

Overall cost of account sharing

Once you have answered the questions above you can have a good stab at calculating the cost of account sharing.

The lost potential revenue is the approximate number of piggyback users x the conversion rate x your ARPU.

The cost of realizing that revenue is your cost per MQL x the approximate number of piggyback users.

The difference is your potential return.

However, depending upon the capabilities of your tech stack, there might be more investment needed to get there. You would need to bake that into your model. The capabilities needed are explored in the next part but some solutions (like Zephr) provide many of these out-of-the-box, so you may not need additional investment.


Working out the business case for tackling account sharing might be difficult for you to take on or it might be so obvious you don’t even need to back it with data. The chances are that all B2B publishers (and all subscription businesses) suffer due to misuse of accounts to some degree of another.

There are a few steps you can take to limit account sharing and I’ll explore those in the next post in this series.

Separation of concerns

Best-of-breed – part 3

In this series (part 1 / part 2), I have been writing about the merits of best-of-breed, as the middle ground between monoliths and microservices. So far, the subject has been limited to just the scale of the software – how many functions should one unit handle. There is another facet to this, however: which functions should be collected together into one solution.

This problem is referred to as the separation of concerns. Or, more accurately, you should consider the separation of concerns when you face the problem of dividing up all of your requirements into units of software.

If you are not familiar with the term, separation of concerns is the process of extracting functionality relating to different domains into isolated units – as a programmer that could be different modules, functions or classes; as an architect that would be different components of the whole system.

To illustrate this concept and explore why you might want to separate concerns, let’s go through an example. Consider a website that requires you to log in to access its content. This system has at least two concerns: managing content and managing users. Now, if this website has a single database to store all data then it has potentially mixed concerns. How could this manifest as a problem? Well, what if the Asian and European markets are both very important for this site and performance is critical? In that case, the GDPR mandates that the users are stored within the EU but the latency of database calls from Asia to the EU could be a problem. The crux of the issue is that there are conflicting requirements upon the database. One concern (user management) requires that the data is never stored outside of the EU and another concern (content management) requires that the data is replicated between Europe and Asia. Obviously this is an over-simplification but hopefully it illustrates the point.

In that example, the resolution to the conflict is straightforward: use two databases – one for users and one for content. That change exemplifies a separation of concerns in a very literal way. Of course, that could cascade into the application tier or the architecture. For the latter, that would mean having one standalone solution for content management and a separate piece of software for user management.

So, given you have taken the decision to use best-of-breed solutions – not monoliths – the question of where to draw the boundaries between these solutions is forthcoming. To answer that question you need to contrast two factors:

  • the benefits of proximity, control and intimate knowledge; vs
  • the risk of conflicts arising between two functions in the same black-box

To illustrate the benefits of proximity, consider Identity and Access Management (IAM). These two families of functions are very commonly bundled together because the decision about access is intrinsically based upon the subject’s identity (“you can access this but they can not”). An access management tool can exist independently with an integration to an external identity store but then the management may be more convoluted, latency will slow the system down and, if the integration fails, the whole system will cease to function.

From an architect’s standpoint, the task is not just to cluster functionality into concerns but also focused on identifying functions that should not live together, because of the risks that coupling them expose your organization to. Unfortunately, analysing the risk of a conflict arising is akin to predicting the future. There are a few indicators you can consider, however… Is the function (not system) mission critical? Is the function heavily regulated, therefor subject to unpredicted change? Is the function intrinsically linked to external systems? Is the function intrinsically linked to client-side technologies, browsers, devices? Essentially, will one function need to moved and/or be changed (with some degree of urgency) independently to the rest of the system?

Finally, the vendors you are assessing will clearly have opinions about the correct separations of concerns and should be able to articulate them clearly.

For a true best-of-breed system the same vendors will regularly work with each other in a mutually beneficial and dependent ecosystem. The hallmark of best-of-breed is that the solution sells by word of mouth. That network effect will naturally cause the best software and, crucially, the most sensible integrations to bubble to the top: “We really liked X and it worked great with Y but, to be honest, the integration with Z was a mistake”.

Really, that final point – the Darwinian emergence of a best-of-breed ecosystem – is the crux of this series. It may be a challenging and multifaceted problem to architect a complex solution but a combination of foresight and market-wisdom can be used to mitigate the risks you take on.

In conclusion, the size and situation of your business affect whether you should be using smaller or larger solutions; monoliths are almost never beneficial; and, finally, careful planning – not just for the architectural patterns but also of where the split lies between various concerns in the system – will help you identify best-of-breed solutions that are a good match to your needs.

How big should your software be?

Best-of-breed – part 2

In the previous post, I talked about the extremes of a spectrum of enterprise software architectures: from large monoliths down to microservices. tl;dr Monoliths are potentially simple solutions but inflexible; micro-services are very agile but come with architectural complexity. At the end of the post, I touched upon the question of whether simplicity and flexibility were of equal value and, hence, if the trade-off was linear.

It seems fairly likely that this model is not correct – there will be some Goldilocks zone in the spectrum, where the flexibility is enough and the complexity manageable. Of course, that sweet-spot will not be universal: the size of the internal technology team, how specialized the outcome is, the market and a host of other factors will come into play.

In this post I am going to explore a framework for modelling the payoff and take some best guesses at how that applies to some example scenarios.

A generalized framework for modelling payoffs

The examples that I will explore in this post are imaginary; they are designed to illustrate that there is not a one-size-fits all solution, nor a paint-by-numbers exercise to find the solution for you. That said, there are aspects that I think are generally applicable and that should be considered:

  1. What is your objective and how are you measuring it? OKRs can work well for this.
  2. What are the attributes of a project that will influence the objective(s)?
  3. For the decision you are trying to make, how do those attributes play our between the extreme cases?

While you should know point one and be able to intuit point two, the final one is tricky and requires work. To effectively describe the landscape, you are likely to need to produce a model in a spreadsheet and put some numbers in. You can guess the numbers to start but it’s worth finding contacts in similar organizations who are friendly enough to share their experiences and help you refine your model.

In the following examples, keep the 3 points above in mind and consider them in the context of each case.

Greenfield startup – limited resources, both in time and budget

In this case, the biggest constraint may be budget. Where you do have budget to spend, you need to avoid one choice closing off other low cost options elsewhere in the stack. The trick will be to find an inter-operable set of software where no single pieces blows the budget. You probably won’t want to pay for engineers where you don’t get differentiating value, either, so the integrations need to be simple or out-of-the-box.

ObjectiveBuild a functional system within budget
Key resultProject total cost of ownership less than X
Influential attributesLicence cost and team size

Here you can see the need to avoid expensive solutions – which will often rule out large enterprise suites – and, equally, you will not want the overhead of a committed team. If you can, buy best-of-breed where it differentiates you and open source or consumer-grade where it doesn’t. You will also want to plan your team size very carefully; while the steps in the illustration above are purely figurative, as a small company the impact of each FTE will significant.

Well funded new venture – trying to scale rapidly

If you have taken investment to scale faster than the competition, the cost of delay far outweighs financial outlay (at least within reason). You’ll need to get the commodity stuff out the way quickly then focus on your differentiator. Bear in mind – you might need to adjust course or even pivot, so don’t get locked in!

Objective 1Get out an MVP and gather usage data
Key result 1Project delivered in less than X days
Objective 2Test-learn-iterate to achieve product-market fit
Key result 2Deliver second iteration in less than Y days
Influential attributesInitial delivery time and time to change some functionality

Some kind of SOA will allow you to adapt to changes as you try and achieve PMF: the big hump in the left of the “Time to pivot” wave indicates the risk of getting a single, inflexible solution for everything. The finance, in this case, is opening up the width of the Goldilocks zone: with enough budget and motivation, you could go all the way to true microservices.

Established company – fighting to get off a crippling legacy stack

The organizational overhead of a move away from a legacy stack can be paralysing. It’s a tough pill but you’re going to have to swallow it.

The OKR is much harder to define in this situation. It could be any one of many, For the purpose of illustration I will chose one possible OKR:

ObjectiveAccurately track customer data throughout the enterprise
Key resultReconcile Web Analytics with Single Customer View with an error rate of less than 0.01%
Influential attributesSCV de-duping accuracy, data integration reliability

A solid architectural strategy will be integral to success and without it the project risks spiralling into chaos. Plan your architecture wisely – hire an FTE to own it, if you don’t have someone already. Something well structured like an event-bus pattern is a good place to start, followed by a multi-stage migration plan that minimizes risk.

There are going to be a lot of requirements in a project like this as, if nothing else, it’s difficult to get agreement to drop BAU functionality in a large organization. That means a single monolith doesn’t exist. You might consider a suite, for some areas of the business, but make sure the vendor is a safe pair of hands.

Failure here is needing to do a large re-arch again. What you build now should last for at least 3 years and the architecture should be designed to live a lot longer than that.

As called out in part 1, the monoliths are spread too thinly to realistically achieve a best-of-breed status for any of the functions you need but, at the other end of the spectrum, if you self-build everything you will never catch up with the attention-to-detail and resilience that a vendor will have finessed over years and multiple clients.

The bump on the right hand side of the “Integration reliability” curve is for true microservices, and is debateable. I believe that there are enough engineers out there who are enthusiastic about micro-services that the right team will be likely to produce a more reliable network of services because they will spend a lot of time thinking about them. Microservices inherently make you consider integrations, whereas that is less of an emphasis if you have non-mission-critical integrations between a small number of self-contained solutions.


To conclude the second post in this series, I want to reiterate the sentiment that there is no right size of software. Small services work well for some companies, large monoliths have their place too. The prevailing truths are:

  • With a little analysis you can identify which style of software will minimize the risk for you, as a buyer
  • The specialists near the middle of the spectrum will have the best quality solutions, as long as their market is large enough and healthy enough to support their growth – these are the best-of-breed solutions

If you have taken the decision to look to the middle of the spectrum – avoiding both atomic microservices and all-encompassing monoliths – the next question is how do you decide which functions live together. In the final post in this series I will focus on that question and explore how a separation of concerns can help keep systems operating effectively over time.

The monolith to microservice spectrum

Best-of-breed software part 1

This is the first in a three part series, covering:

Enterprise software buyers have a really hard job. Aside from the specifics of meeting requirements, there’s no escaping the difficulty of the underlying architectural decisions an organization needs to make in order to buy well.

If the technology systems of your company are simple – with few users and minimal integration – you may be able to buy something that just does the job. But, most often, that’s not a strategy that can scale with your business or the changing technology landscape. Usually, there needs to be some consideration of architecture even before shortlisting a vendor.

The decision regularly comes down to buying a monolithic-solution or a point-solution. That is, you can buy a monolith (or suite) that handles the majority of the functional requirements of your business in one solution; or you can buy many solutions that each fulfil one function. Of course there are some solutions that fall between the two, which will be the subject of the next post in this series.

Now, on the face of it, a solution that meets all of your needs in one tool is the obvious winner, versus one that only meets a single need, but – as we all know – it’s not that simple.

Personally, in order to bring clarity to a difficult decision, I like to consider the polar extremes: a solution that literally does everything ones business needs verses a microservice that only handles the slimmest, most atomic function.

Take the example of an online newspaper (as an industry I know well). They need solutions to, at least:

  • Author content
  • Publish content to the web
  • Manage registered user data
  • Authenticate users
  • Hide content behind a paywall
  • Manage recurring subscriptions
  • Curate newsletters
  • Manage email lists
  • Send emails

(In fact, the list is much, much longer than that but they would definitely need to do those things.)

First, let’s consider the monolith. For a green-field publisher this might be an attractive option. One vendor (throat), one set of training for their users, one bill. And, hopefully, the whole business is supported by one integrated solution.

There are three particular drawbacks to the monolithic approach.

One is that the implementation project is likely to be huge, which constitutes a substantial gamble: if the project goes wrong the cost could be existentially damaging, particularly for a new business.

The second problem is vendor lock-in. Assuming the project is a success, what happens a year or two down the line if the publisher wants to change the way they send emails? Maybe they were getting a lot of bounces; maybe the reporting is inaccurate; whatever the reason, the solution is not cutting it and a better one is now desirable. The issue at this point is that the publisher is paying for the email sending functionality of the monolith, whether they are using it or not.

Finally, there is a more insipid problem of the development and maintenance. You should be cognisant to the fact that the vendor of a monolith is competing with several best-of-breed and point solutions, across different functions. If they offer a CMS (authoring & publishing content), an IDM (user data and auth’) and a paywall (access control & subscriptions) then there would be an alternative architecture with 3 separate best-of-breed vendors or 6 point solutions; so the monolith’s development team (and other teams) would need to be in the same order as 3 best-of-breed vendors combined. If they’re not, how can they be investing in their product competitively?

So, what about microservices?

The benefits of microservices are well documented elsewhere but, to summarize, because each service is modular and focused they can be built and maintained more easily and quickly. The service only has to worry about one thing and has a strict interface between it and other services so:

  • you can rebuild or refactor them often, without worrying about the rest of your stack;
  • you can use different technologies and programming languages for each service, picking the most appropriate for each, and;
  • when you release, you are testing an isolated scope.

All of that is predicated upon the architecture being responsible for the interactions between the services. A development team can safely work on just, say, Content Authoring because there is a strict interface (what comes in and out of the service must not change) and there is some kind of transport between them, such as an event bus or HTTP calls.

The real challenge with microservices is that architecture – the glue between the services. Each service is less complicated but the entire system is a whole lot more complex. Some services might be built in house, some bought; in that case you need to abstract the APIs of the bought systems to fit in with your interfaces, which means an API gateway, of some kind. The services you build yourself need to be containerized, load-balanced and auto-scaled. You need to monitor performance at either the interface or the network level to identify bottlenecks… It gets complicated.

In some cases, another down-side to a microservices architecture is performance. This one is arguable and depends a lot on specifics but more network request between the interconnected web of services means more latency. That should be considered too.

So, from this point of view we can see there is a trade-off between simplicity and flexibility. Monoliths are simple solutions, in many senses, but really undermine organizational flexibility; Microservices are flexible but come with an architectural complexity that should not be underestimated.

If these two traits – simplicity and flexibility – are equally valued and dissipate linearly from one extreme to the other then there is no outright advantage for any particular point on the spectrum. You would just chose the solution you liked. That, however, is probably not the case.

The value of each trait is absolutely dependent upon your team and existing systems. If you don’t employ any solutions architects then the value of simplicity is massively inflated. If you have very unique requirements that can only be built bespoke, then flexibility may be more important for you. In part two of this series I will have a look at some example cases and explore a framework for answering the question “how big should your software be”.

In practice, most enterprises will have some blend of solutions from across this spectrum. Extremes are generally risky and solutions that fall somewhere between microservices and monoliths may be the pragmatic choice. In part three of this series I am going to explore which functions should be collected into best-of-breed solutions and why.

About me

I’m an entrepreneur and technologist. I’m passionate about building SaaS products that provide real value, solving hard problems, but are easy to pick up and scale massively.

I’m the technical co-founder of a venture-backed start-up, Zephr. We have built the worlds most exciting CDN which delivers dynamic content to billions of our customer’s visitors, executing live, real-time decisions for every page.