Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/renja-g/RiftRelay/llms.txt

Use this file to discover all available pages before exploring further.

What are Priority Requests?

By default, RiftRelay spreads requests evenly across the rate limit window to avoid bursts. Priority requests allow you to bypass this pacing delay for time-sensitive operations while still respecting rate limits.
Priority requests skip the pacing delay but still consume rate limit capacity. They do not bypass Riot’s rate limits.

When to Use Priority Requests

Use priority requests for:

Real-time Data

Live game data or match updates that need immediate processing

User-facing Requests

API calls triggered directly by user actions where latency matters

Critical Operations

Time-sensitive operations that cannot wait in the queue

Low-volume Priority

Occasional high-priority requests mixed with bulk processing
Don’t use priority requests for all traffic. Overusing priority bypasses the benefits of request pacing and may lead to more rejected requests.

How to Send Priority Requests

Add the X-Priority: high header to your request:
curl -H "X-Priority: high" \
  "http://localhost:8985/europe/riot/account/v1/accounts/by-riot-id/Someone/EUW1"

How Priority Works

From the source code in internal/limiter/limiter.go:
limiter.go
func (l *Limiter) pickKey(now time.Time, keys []keyState, region, bucket string, priority Priority) (int, time.Time) {
	bestIndex := -1
	bestAt := time.Time{}
	bypassPacing := priority == PriorityHigh

	for i := range keys {
		key := &keys[i]
		appAt := key.app(region, now, l.cfg.AdditionalWindow).nextAllowed(now, bypassPacing)
		methodAt := key.method(bucket, now, l.cfg.AdditionalWindow).nextAllowed(now, bypassPacing)
		readyAt := appAt
		if methodAt.After(readyAt) {
			readyAt = methodAt
		}

		if bestIndex < 0 || readyAt.Before(bestAt) {
			bestIndex = i
			bestAt = readyAt
		}
	}

	return bestIndex, bestAt
}
1

Priority Detection

RiftRelay detects the X-Priority: high header and marks the request as high priority.
2

Bypass Pacing

The bypassPacing flag skips the even distribution delay that normal requests experience.
3

Rate Limit Check

The request still checks against application and method rate limits.
4

Immediate or Queue

If rate limit capacity exists, the request is sent immediately. Otherwise, it waits at the front of the priority queue.

Priority Levels

RiftRelay supports two priority levels defined in internal/limiter/types.go:
types.go
type Priority uint8

const (
	PriorityNormal Priority = iota
	PriorityHigh
)
  • PriorityNormal - Default priority with pacing delay
  • PriorityHigh - Bypasses pacing delay

Comparison: Normal vs Priority

Normal Request

curl "http://localhost:8985/europe/riot/account/v1/accounts/by-riot-id/Someone/EUW1"
Behavior:
  • Enters the normal priority queue
  • Waits for pacing delay to spread requests evenly
  • Sent when the next scheduled slot is available
  • Lower latency impact on other requests

Priority Request

curl -H "X-Priority: high" \
  "http://localhost:8985/europe/riot/account/v1/accounts/by-riot-id/Someone/EUW1"
Behavior:
  • Enters the high priority queue
  • Bypasses pacing delay
  • Sent as soon as rate limit capacity allows
  • Minimal latency for this specific request
Both types still respect the same rate limits from Riot’s API. Priority affects queue position and pacing, not rate limit consumption.

Queue Behavior

From internal/limiter/limiter.go, RiftRelay maintains separate queues:
limiter.go
type bucketQueue struct {
	region    string
	bucket    string
	high      []*admitRequest  // High priority queue
	normal    []*admitRequest  // Normal priority queue
	heapIndex int
}
High priority requests are always processed before normal priority requests from the same bucket.

Best Practices

Reserve priority requests for truly time-sensitive operations. If 90%+ of your requests are priority, you’re bypassing the benefits of request pacing.
Enable metrics to monitor queue depth by priority:
.env
ENABLE_METRICS=true
If priority queues are consistently full, you may need to increase capacity or reduce priority usage.
Using multiple tokens increases total throughput, giving priority requests more capacity to work with.
Priority requests can still be rejected if rate limits are exhausted. Always handle 429 responses and respect Retry-After headers:
const response = await fetch(url, {
  headers: { 'X-Priority': 'high' }
});

if (response.status === 429) {
  const retryAfter = response.headers.get('Retry-After');
  // Wait and retry after the specified duration
}

Rate Limiting Behavior

From the README, here’s how RiftRelay handles rate limits:
When requests come in, RiftRelay figures out which rate limit bucket they belong to and adds them to a queue. A scheduler picks requests from the queue and sends them when there’s room in the rate limit window. Instead of sending all requests at once when the limit resets, RiftRelay spreads them out evenly over time to avoid sudden bursts.
Priority requests modify this behavior:
  • Normal requests: Spread evenly across the rate limit window
  • Priority requests: Sent as soon as capacity allows, no artificial pacing delay
  • Both types: Respect the same rate limit capacity from Riot’s API

Example Scenario

Imagine you’re building an app that:
  1. Processes bulk match history analysis (background job)
  2. Displays live game data when users click a button (user-facing)
Example Implementation
// Background job - normal priority
async function analyzeBulkMatches(matchIds) {
  for (const matchId of matchIds) {
    const response = await fetch(
      `http://localhost:8985/europe/lol/match/v5/matches/${matchId}`
      // No X-Priority header - uses normal queue
    );
    await processMatchData(await response.json());
  }
}

// User-facing request - high priority
async function fetchLiveGame(summonerId) {
  const response = await fetch(
    `http://localhost:8985/na1/lol/spectator/v4/active-games/by-summoner/${summonerId}`,
    {
      headers: { 'X-Priority': 'high' }
    }
  );
  
  if (response.status === 429) {
    const retryAfter = parseInt(response.headers.get('Retry-After'));
    await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
    return fetchLiveGame(summonerId); // Retry
  }
  
  return response.json();
}

Limitations

Priority requests do NOT:
  • Increase your rate limit quota
  • Guarantee instant delivery (still subject to rate limits)
  • Prevent 429 errors if limits are exhausted
  • Override Riot’s rate limiting
Priority requests DO:
  • Skip artificial pacing delays
  • Get processed before normal requests in the same bucket
  • Reduce latency for time-sensitive operations
  • Respect the same rate limit capacity

Next Steps

Multiple Tokens

Increase throughput with multiple API tokens

Configuration

Tune queue capacity and timeouts

Build docs developers (and LLMs) love