Skip to content

Scheduler prioritization

This page explains how the scheduler chooses which observation to run next on a given telescope. The mechanics here cut across every layer of the access model — telescope access grants, queues, queue access grants, and observing accounts — so it's worth reading Telescope access, Observing queues, and Access grants first if any of that vocabulary is new.

The short version: prioritization is a ladder. When two eligible observations compete for the same time, the scheduler compares them level by level and the first level that differs decides:

  1. Queue order — which queue each observation is in. You, the telescope owner, order your queues; higher queues win.
  2. Queue access grant order — within one queue, the grants are ordered by the queue's prioritization mode (fixed, fair-share, or calendar — your choice per queue).
  3. Account order — within one grant, the observing accounts that reference it are ordered by their owner, and inside each account its subaccounts are ordered by the account's managers, level by level down the delegation chain.
  4. Observation order — within one account, the submitter's own observation priority, then how long each observation has been waiting, then the scheduler's efficiency model.

Every level is controlled by the party that owns that level: you control levels 1–2 (how your telescope's time is divided among grantees), and each grantee controls levels 3–4 (how their own slice is divided among their accounts, teams, and observations). Nothing a grantee configures can change how much time they get relative to another grantee — that is always your queue configuration's decision.


The records that drive prioritization

TelescopeAccessGrant       ←─ entity ↔ telescope; shares + usage across ALL queues
        │ has many
ObservingQueueAccessGrant  ←─ entity ↔ one queue; order within the queue,
        │                     usage within the queue
        │ referenced by
ObservingAccount           ←─ bundles queue access grants for submitters;
        │                     ordered among its siblings
        │ may delegate to
ObservingAccount (sub)     ←─ subaccounts, ordered by the parent's managers

TelescopeAccessGrant

Each telescope maintains a set of telescope access grants — one per entity that's been admitted to observe with the telescope.

The grant carries a shares value — the entity's ownership fraction, the input to fair-share prioritization — and the entity's usage bookkeeping across all queues (time_used, plus time_contested and time_waiting; see how usage is counted).

Telescope access grants are not the same thing as the TelescopeAccessGrants that delegate read/update/delete on the telescope record — they share a name (and a model) but represent different intent. The one described here is the observing-time grant; an owner uses it to say "this entity is admitted to the telescope, with this many shares of its time."

ObservingQueueAccessGrant

Once an entity holds a telescope access grant, queue access grants hang off it — one per queue the entity is allowed to access.

A queue access grant carries:

  • The queue it applies to.
  • A back-reference to the parent telescope access grant (so the entity and the telescope are both implied).
  • order — the configured priority of this grant within the queue. Lower values are higher priority.
  • effective_order — the priority the scheduler actually uses. For fixed queues this equals order; for the dynamic modes it is recomputed continuously by the queue's prioritization mode (see below).
  • time_used, time_contested, time_waiting — the entity's usage within this queue specifically, distinct from the parent telescope access grant's cross-queue totals.
  • An optional observing-policy override.

The split between "total usage on the telescope" (on the telescope access grant) and "usage in this queue" (on the queue access grant) is what lets you choose fair-share at either scope: telescope-wide or queue-local.

ObservingAccount

Once an entity holds a queue access grant, they include it in one or more observing accounts. An observing account is a bundle of:

  • One or more queue access grants (possibly across telescopes),
  • A list of observing grants identifying which entities are allowed to add observations to those queues through this account (OwnerObservingGrant, MemberObservingGrant, GroupObservingGrant, DelegatedObservingGrant, etc. — see Observing accounts), and
  • An order — where this account ranks among its siblings when the scheduler breaks ties inside the entity's slice (see account ordering).

The account is what submitters interact with. They never pick a queue access grant directly; they pick an account, and the account exposes whichever queues its grants reach.


How usage is counted: contested time

The fair-share modes below all rest on one accounting rule:

Usage counts against a grantee's share only when the time was contested — that is, only when another grantee's eligible observation was waiting for the telescope at the same time. Time used while the telescope would otherwise have sat idle is free.

This is deliberate, and it is the property to keep in mind when reasoning about "who is ahead":

  • Idle time is use-it-or-lose-it. If one grantee is the only one with work queued tonight, they can run all night without consuming any of their share. Nobody was harmed; nothing is owed.
  • Hoarding doesn't work. A grantee cannot sit out for months, "bank" their unused fraction, and then monopolize the telescope while their average catches up. Only contested time moves the ledger, so there is nothing to bank.
  • Shares mean priority under contention, not a guaranteed number of hours. Weather, targets, and demand decide how much absolute time exists; shares decide how the contested part of it divides.

The bookkeeping behind this is the time_used / time_contested / time_waiting triple, maintained at both the telescope level (on the telescope access grant) and per queue (on each queue access grant): used is everything the grantee ran, contested is the subset that ran while a sibling was waiting, and waiting is the time siblings used while this grantee had eligible work queued.


Queue prioritization modes

Each queue chooses exactly one prioritization mode, recorded as ObservingQueue.access_prioritization. The mode determines how the scheduler turns the queue's set of queue access grants into an ordered list — that is, how effective_order is produced:

Mode Behavior
Fixed (default) effective_order = the configured order on each queue access grant. You set it; it doesn't change as time is used.
Telescope fair-share (total_usage) effective_order is recomputed continuously so that grantees running behind their shares — measured on contested time across the whole telescope — float to the top. A grantee who has been crowded out anywhere on the telescope catches up here.
Queue fair-share (queue_usage) Same mechanism, but measured on the queue-local contested-usage bookkeeping. Fair-share within this queue only; usage on other queues doesn't affect standing here.
Calendar (schedule) A calendar maps grantee → time window. During a grantee's window, their grant is at the top of the queue; outside their window, the grant is not considered.

The two fair-share modes produce a dynamic ordering — effective_order is an output of the mode, not a field you edit. The configured order still matters in every mode: it is the tiebreaker between grants the mode considers equal.

Choosing between the fair-share scopes: use telescope fair-share when the queue should compensate for imbalance elsewhere ("everyone gets their fair share of the telescope, and this queue is where it evens out"); use queue fair-share when the queue is its own self-contained allocation ("this queue is split fairly among its grantees, regardless of what anyone uses elsewhere").


The ladder, end to end

For a given telescope, when the scheduler builds the schedule:

  1. Queues, in queue order. ObservingQueue.order defines the priority order of queues on the telescope — lower values are higher priority. Disabled queues are skipped. A queue with can_interrupt may preempt an in-progress observation from a lower-priority queue; otherwise higher queues wait for the current task to finish and then take precedence.
  2. Within a queue: grants, by effective_order. Lower is higher priority. This is the output of the queue's prioritization mode — fixed, fair-share (telescope-wide or queue-local), or calendar.
  3. Within a grant: accounts, by account order. Multiple observing accounts can reference the same queue access grant. The grantee entity orders those accounts (ObservingAccount.order, lower first). If the winning account has delegated subaccounts, the same rule applies again inside it — the parent's managers order the subaccounts — and so on down the delegation chain. See the next section.
  4. Within an account: observations. The submitter's own observation priority ranks their observations against each other; among equals, observations that have been waiting longer come first; and among those, the scheduler's efficiency model (target observability, slews, filter changes, readout overheads) picks the cheapest to start next.

Eligibility filtering applies throughout: observations whose targets aren't observable now, whose policy constraints fail, or whose funding account / grant has hit a quota are excluded before any of the ordering above happens.

Each pass emits an ObservingScheduleEvent per queue, and the overall run is summarized by a SchedulerRun. Those are the records to read first when diagnosing "why didn't my observation run." See Observing queues → Schedule events and scheduler runs.


Prioritization within a grantee's slice: account ordering

Levels 3–4 of the ladder happen entirely inside one grantee's slice of one queue. As the telescope owner you never see or configure them, and they can never change how much time that grantee gets relative to anyone else — but it's worth understanding what your grantees can do with them:

  • Ordering sibling accounts. An entity whose accounts share a queue access grant can rank those accounts. A university that runs a "faculty research" account and a "outreach" account against the same grant can declare that, under contention, research observations go first.
  • Ordering subaccounts. The managers of any account with delegated subaccounts can rank the subaccounts the same way — a department can put its thesis students ahead of its intro-lab sections. The rule applies recursively at every level of the delegation tree.
  • Defaults are neutral. Accounts and subaccounts start with equal order. Equal-order siblings are treated fairly: among them, the observation that has been waiting longest goes first. Ordering only changes anything when an account's owner deliberately sets it.
  • Quotas never reorder — they only pause. Quotas on accounts and grants are eligibility limits: when one fills, dispatch for that account stalls in place until the window rolls over. A stalled high-priority observation is not "overtaken" in any ordering sense; it is simply not eligible until its quota recovers. See Observing accounts → Quotas.

One practical consequence for observers: an observation's position in the ladder is determined by the account it was submitted through. An observer with access to several accounts can change an observation's standing by choosing a different account — which may reach a different grant, a different queue, or a differently-ordered branch of an account tree.


Reference

ObservingQueue Schema

Properties

Name Type Description
id Integer No description
queue_type Enum(maintenance, too, general, calibration, custom) No description
telescope_id Integer No description
name String(256) No description
slug String(256) No description
description String(Unbounded) No description
can_interrupt Boolean Whether or not the queue can interrupt lower priority queues
access_prioritization Enum(default, total_usage, queue_usage, schedule) No description
order Integer The order used to prioritize queues for a given telescope. Lower values are higher priority.
enabled Boolean Whether or not the queue is enabled. Disabled queues will not be scheduled.

Relationships

Relationship Name Type
telescope Telescope
access_grants ObservingQueueAccessGrant

ObservingQueueAccessGrant Schema

Properties

Name Type Description
id Integer The unique identifier for the queue access grant.
queue_id Integer The ID of the queue to which the allocation belongs.
telescope_access_grant_id Integer The ID of the telescope access grant providing access to this queue.
order Integer The order used to prioritize this allocation within the queue. Lower values are higher priority.
revoked Boolean Whether this allocation has been revoked. If true, the allocation is no longer valid.
effective_order Integer The effective order used to prioritize thisa llocation within the queue, taking into account the queue's prioritization policy and the allocation's own priority.
time_used Float The total time used by the account regardless of whether it was contested or not.
time_contested Float The total time used by the account when sibling accounts also had observations which could have been scheduled.
time_waiting Float The total time that the other accounts used while this account was waiting for its observations to be scheduled.
observing_policy_id Integer (Optional) No description

Relationships

Relationship Name Type
queue ObservingQueue
telescope_access_grant TelescopeAccessGrant
observing_accounts ObservingAccount
observing_policy ObservingPolicy

TelescopeAccessGrant Schema

Properties

Name Type Description
id Integer No description
telescope_id Integer No description
entity_id Integer (Optional) The entity (user or organization) granted access to the telescope. Null while an email invitation is outstanding — set to the accepting entity when the invitation is accepted. (C10)
shares Float The number of shares this access grant has. This is used to determine how much time the entity can use the telescope.
time_used Float No description
time_contested Float No description
time_waiting Float No description
revoked Boolean Whether this access grant has been revoked. If true, the access grant is no longer valid.

Relationships

Relationship Name Type
telescope Telescope
entity Entity
invitation TelescopeAccessGrantInvitation
queue_access_grants ObservingQueueAccessGrant

ObservingScheduleEvent Schema

Properties

Name Type Description
id Integer No description
owner_id Integer (Optional) No description
telescope_id Integer (Optional) No description
priority Integer No description
created_on DateTime No description
updated_on DateTime (Optional) No description
start_on DateTime (Optional) No description
end_on DateTime (Optional) No description
end_time_unspecified Boolean No description
all_day Boolean No description
recurrence String(100) (Optional) No description
recurring_event_id Integer (Optional) No description
is_too Boolean No description
is_exclusive Boolean No description
description String(100) No description

Relationships

Relationship Name Type
owner Organization
telescope Telescope
users User
groups Group
organizations Organization
observations Observation

SchedulerRun Schema

Properties

Name Type Description
id Integer No description
started_at DateTime No description
finished_at DateTime (Optional) No description

Relationships

Relationship Name Type
tasks ObservationTask