Is there a way to prioritize some users over others when there is a spike in traffic?

For ex: in wealth management, is there a way to allow an API call from a high networth individual as opposed to say someone like me when the traffic reaches a certain threshold.

~~S:G:TC~~

1 3 459
3 REPLIES 3

Not applicable

"Identifier" element can be used to uniquely identify a request and apply spike arrest accordingly. However, identifying request owner would require access token verification and that in turn will delay enforcing the SpikeArrest policy.

I would suggest to apply SpikeArrest as generically for a proxy as a protection against DDoS

Use quota policy with Identifier to provie more quota for such customer type and use custom attribute having quota value for different customer type.

I think what Anil is describing is a rate limit that applies "only when the traffic exceeds a certain threshold." Which I am translating to "only when there is contention."

Let's say there are A-class and C-class clients/users.

My understanding of the problem:

  1. if there are no requests from A-Class clients, then the requests C-Class of users can use as much service as they like. (Maybe subject to a quota, but put that aside for a moment).
  2. If there are A-class requests and C-class requests, then we want to give "more priority" to the A-class requests.

Depending on the exact requirement, I think you could do it. Maybe with a 2-stage quota enforcement, with some conditionals. Here's what I imagine:

  1. request arrives in Edge
  2. VerifyApiKey or VerifyAccessToken
    1. in the above, you implicitly determine the "class" of the user or client. Either A or C .
  3. If A-class, then PopulateCache with key "contention", value: true (doesn't matter). TTL = 30s (your choice)
  4. if not A-class, then LookupCache on key "contention". If the cache value exists, then enforce a quota.

In the DSL for Apigee Edge it might look like this:

<PreFlow name='PreFlow'>
  <Request>
    <Step>
      <Name>VerifyAccessToken-1</Name>
    </Step>
    <Step>
      <Condition>accesstoken.A-class = "true"</Condition>
      <Name>PopulateCache-SetContentionFlag</Name>
    </Step>
    <Step>
      <Condition>not (accesstoken.A-class = "true")</Condition>
      <Name>LookupCache-GetContentionFlag</Name>
    </Step>
    <Step>
      <Condition>not (accesstoken.A-class = "true") AND (contention = "true")</Condition>
      <Name>Quota-C-class</Name>
    </Step>
    <Step>
      <Name>Quota-1</Name> <!-- optional -->
    </Step>
  </Request>
</PreFlow>

Depending on the exact requirements, that might satisfy. It's not "priority queueing". Instead it is "secondary quota enforcement only when contention occurs".

This is very naive, but it illustrates the idea. Probably, the "contention" state should be set not based on whether a single request has arrived, but based on whether the load or concurrency is "high". How would you determine that? For that you could use a non-enforced quota, a counter that is incremented for every request, but which does not ever return 429. You could simulate this by using a quota with a limit of 10e6 requests per minute.

When that quota policy executes, it will compute the counters, and set context variables like this:

ratelimit.{policy_name}.used.count  

So the contention state might be based on that number, being above "a fixed threshold". Let's say, 1000 requests per minute.

The updated XML might be:

<PreFlow name='PreFlow'>
  <Request>
    <Step>
      <Name>VerifyAccessToken-1</Name>
    </Step>
    <Step>
      <Name>Quota-Unenforced-1</Name> <!-- eg, 10e6 / min -->
    </Step>
    <Step>
      <Condition>accesstoken.A-class = "true" AND (ratelimit.Quota-Unenforced-1.used.count > 1000) </Condition>
      <Name>PopulateCache-SetContentionFlag</Name>
    </Step>
    <Step>
      <Condition>not (accesstoken.A-class = "true")</Condition>
      <Name>LookupCache-GetContentionFlag</Name>
    </Step>
    <Step>
      <Condition>not (accesstoken.A-class = "true") AND (contention = "true")</Condition>
      <Name>Quota-C-class-DuringContention</Name>
    </Step>
    <Step>
      <Name>Quota-1</Name> <!-- optional -->
    </Step>
  </Request>
</PreFlow>

Class-based Quota configuration may provide easy solution as this being based on customer types.