SimPy PriorityResource Explained: When Some Requests Matter More

Not all customers are equal. Not all jobs are equally urgent. PriorityResource lets important requests jump the queue.

Basic Resource vs PriorityResource

Regular Resource: First come, first served. Fair. Simple.

PriorityResource: Lower priority number goes first. VIPs jump the queue.

import simpy

env = simpy.Environment()
resource = simpy.PriorityResource(env, capacity=1)

How Priority Works

Lower numbers = higher priority.

def requester(env, name, resource, priority):
    with resource.request(priority=priority) as req:
        yield req
        print(f"{name} (priority {priority}) gets resource at {env.now}")
        yield env.timeout(5)

env = simpy.Environment()
resource = simpy.PriorityResource(env, capacity=1)

# First request (lowest priority)
env.process(requester(env, "Low", resource, priority=10))
# Second request (highest priority)
env.process(requester(env, "High", resource, priority=1))
# Third request (medium priority)
env.process(requester(env, "Medium", resource, priority=5))

env.run()

Output:

Low (priority 10) gets resource at 0
High (priority 1) gets resource at 5
Medium (priority 5) gets resource at 10

"Low" was first, so it got the resource. But when it released, "High" jumped ahead of "Medium" in the queue.

Real-World Examples

Emergency Department Triage

PRIORITY = {
    'critical': 1,
    'urgent': 2,
    'standard': 3,
    'minor': 4
}

def patient(env, name, doctor, severity):
    print(f"{name} ({severity}) arrives at {env.now}")
    with doctor.request(priority=PRIORITY[severity]) as req:
        yield req
        print(f"{name} sees doctor at {env.now}")
        yield env.timeout(10)

env = simpy.Environment()
doctor = simpy.PriorityResource(env, capacity=1)

env.process(patient(env, "Alice", doctor, "minor"))
env.process(patient(env, "Bob", doctor, "critical"))
env.process(patient(env, "Charlie", doctor, "urgent"))

env.run()

Bob (critical) jumps ahead of Charlie (urgent), who jumps ahead of Alice (minor).

Job Scheduling

def job(env, name, machine, priority, duration):
    with machine.request(priority=priority) as req:
        yield req
        print(f"{name} starts at {env.now}")
        yield env.timeout(duration)

machine = simpy.PriorityResource(env, capacity=1)

# Customer jobs (low priority)
env.process(job(env, "Routine", machine, priority=10, duration=5))

# Expedited order (high priority)
env.process(job(env, "Rush", machine, priority=1, duration=5))

Ties: Same Priority

When priorities are equal, FIFO applies:

env.process(requester(env, "A", resource, priority=5))
env.process(requester(env, "B", resource, priority=5))
env.process(requester(env, "C", resource, priority=5))

A, B, C get served in order—no favouritism among equals.

Dynamic Priority

Priority is set at request time, not at process creation:

def smart_customer(env, resource):
    wait_start = env.now

    # Start with normal priority
    priority = 5

    # But if I've been waiting too long, escalate
    if env.now - wait_start > 10:
        priority = 1

    with resource.request(priority=priority) as req:
        yield req
        # ...

You could also implement aging—increasing priority the longer someone waits.

Priority vs Regular Resource

Feature Resource PriorityResource
Queue order FIFO Priority, then FIFO
Request syntax request() request(priority=n)
Fair Yes No (by design)

When to Use PriorityResource

Use when: - Some entities genuinely deserve faster service - SLAs require tiered response times - Business value varies by customer/job type - You're modelling emergency services or triage

Don't use when: - Fairness matters - Priority abuse is a concern (low priority starves) - The real system doesn't prioritise

Starvation Warning

Priority queues can starve low-priority requests:

def high_priority_flood(env, resource):
    """Continuous stream of high-priority requests"""
    while True:
        yield env.timeout(1)
        env.process(quick_job(env, resource, priority=1))

If high-priority requests keep arriving, low-priority requests wait forever.

Solutions: - Age-based priority boosting - Reserved capacity for low priority - Maximum wait time enforcement

Collecting Statistics by Priority

wait_times = {1: [], 2: [], 3: []}

def job(env, resource, priority):
    arrival = env.now
    with resource.request(priority=priority) as req:
        yield req
        wait_times[priority].append(env.now - arrival)
        yield env.timeout(5)

# After simulation
for p, times in wait_times.items():
    avg = sum(times) / len(times) if times else 0
    print(f"Priority {p} average wait: {avg:.2f}")

PriorityResource vs PreemptiveResource

PriorityResource: High priority jumps the queue but waits for current user to finish.

PreemptiveResource: High priority can interrupt and take over immediately.

The difference is not insignificant. PriorityResource respects current users. PreemptiveResource doesn't.

Example: Call Centre with VIP Line

import random

def caller(env, name, agents, is_vip):
    priority = 1 if is_vip else 5
    arrival = env.now

    print(f"{name} ({'VIP' if is_vip else 'Regular'}) calls at {env.now}")

    with agents.request(priority=priority) as req:
        yield req
        wait = env.now - arrival
        print(f"{name} answered after {wait:.1f} (priority {priority})")
        yield env.timeout(random.uniform(3, 8))

env = simpy.Environment()
agents = simpy.PriorityResource(env, capacity=2)

for i in range(10):
    is_vip = random.random() < 0.2  # 20% VIP
    env.process(caller(env, f"Caller{i}", agents, is_vip))
    yield env.timeout(random.expovariate(1))

env.run()

Summary

PriorityResource: - Serves lower priority numbers first - FIFO among equal priorities - Doesn't interrupt current service - Use for triage, tiered SLAs, job scheduling

When priority matters, use PriorityResource.

Next Steps


Discover the Power of Simulation

Want to become a go-to expert in simulation with Python? The Complete Simulation Bootcamp will show you how simulation can transform your career and your projects.

Explore the Bootcamp