---
title: Review Queue
slug: review-queue
kind: pattern
summary: A single ordered worklist that hands one person the next item to judge, with the decision available in the same view — built so the queue empties rather than so it can be browsed.
problem: >-
  Work that needs a human decision is spread across a list everyone can see and
  nobody owns. Two people open the same item, older items sink, and "how much is
  waiting" is a question nobody can answer without counting.
family: [act, workflow]
data_shape: [collection]
principles: [surface-dont-bury, friction, orientation]
interaction: [selection, decision]
density: medium
complexity: medium
status: stable
visibility: public
use_when:
  - Items need a human judgment before work continues, and the judgment is repeatable.
  - The order matters — oldest first, or by risk — and should not be left to whoever looks.
  - Several people work the same pool and must not collide.
avoid_when:
  - Each item needs a different investigation with no common decision. That is casework, not a queue.
  - Only one person ever does it and volume is low. A filtered list is enough.
  - The decision cannot be made from the information shown, so every item becomes a research project.
alternatives:
  - slug: dense-operational-table
    when: People need to compare items across the set rather than judge them one at a time.
  - slug: linear-workflow
    when: The interesting question is the sequence of stages, not the throughput of one of them.
ask_leo: |
  Build this as a review queue, not as a list.

  - Order the queue explicitly — oldest first by default — and say what the
    order is. Never leave it to insertion order.
  - Show the count of items waiting, and the age of the oldest one, at the top.
    Those two numbers are what tell someone whether the queue is healthy.
  - Show one item at a time with everything needed to decide it in the same
    view. If someone must open another screen to judge an item, bring that
    information into the queue instead.
  - Put the decision actions directly in the item view, with the primary
    decision emphasised and a distinct action for "reject", which must capture
    a reason.
  - Support keyboard operation for the whole loop: move to next, approve,
    reject. People work queues for an hour at a time.
  - Advance automatically to the next item after a decision, and say what just
    happened with an undo for the last action.
  - Prevent collisions: mark an item as being worked when someone opens it, and
    release it if they leave. Two people must not decide the same item.
  - Give the queue a real empty state that reads as success, not as an error.
related:
  - title: Linear Workflow
    url: /patterns/linear-workflow
    summary: The topology a queue usually sits inside — a queue is one stage of it.
  - title: Confirmation vs Undo
    url: /patterns/confirmation-vs-undo
    summary: Why a queue should use undo rather than confirm on every decision.
---

## Anatomy

```
┌────────────────────────────────────────────────────┐
│ 14 waiting · oldest 6 days          ⌨ j/k a r      │
├────────────────────────────────────────────────────┤
│ Expense #4471 — Priya Nandi            waiting 6d  │
│ $184.00 · Client dinner · 3 attendees              │
│ [receipt thumbnail]  policy limit $150             │
│                                                    │
│         [ Approve ]   [ Reject with reason ]       │
└────────────────────────────────────────────────────┘
      ↑ everything needed to decide, in one view
```

The properties that make it a queue rather than a list:

- **An explicit order**, stated on screen.
- **A depth and an age**, so the health of the queue is visible without counting.
- **The decision in the same view as the evidence.** This is the one that
  decides whether the pattern works at all.
- **Auto-advance**, so the loop is decide-decide-decide rather than
  decide-navigate-decide.
- **A claim**, so two people cannot judge the same item.

## Why it works

A queue optimises for **throughput of decisions**, which is a different goal from
a list optimising for *finding a record*. Nearly every design choice follows
from that: one item at a time because attention is the bottleneck, auto-advance
because navigation between items is pure overhead, keyboard control because the
loop repeats for an hour.

The depth and age numbers are what make it manageable rather than merely usable.
A list can hide a backlog indefinitely; a queue that says "oldest is 6 days"
turns a quiet accumulation into a visible fact, which is usually the first time
anyone notices the process is under-staffed.

## The information test

Before building the queue, check that **the decision can actually be made from
what the queue can show**. If a reviewer has to open the customer, then the
contract, then last month's report, it is not a queue — it is casework wearing a
queue's interface, and the auto-advance will make it worse by removing the
context between items.

The fix is usually to bring the missing evidence into the item, not to abandon
the pattern. That is often the most valuable thing the exercise produces:
discovering exactly which three facts a decision really depends on.

## Getting it wrong

- **Confirm dialogs on every decision.** In a queue this is catastrophic — it
  doubles the clicks on the one action people repeat hundreds of times. Use
  [undo](/patterns/confirmation-vs-undo) instead.
- **Reject with no reason.** The reason is the entire feedback loop; without it,
  the same bad submissions arrive forever.
- **No claim.** Two reviewers, one item, two different decisions.
- **An empty state that looks broken.** Finishing a queue is the goal; the
  screen should say so.
- **Mouse-only.** Fine for ten items a week, unusable for two hundred a day.

## Exemplars

**Gmail's archive loop** is the pattern at its most refined: one item, keyboard
control, auto-advance, and undo instead of confirmation on the destructive
action. It is worth studying precisely because the decision is trivial and the
volume is huge, which is the regime queues exist for.

**Stripe Radar's review queue** shows the information test passed properly —
each flagged payment arrives with the specific signals that flagged it, so the
reviewer is judging rather than investigating.

**Content moderation tools** across the industry converge on the same shape,
which is a strong signal: one item, fixed order, decision in view, reason on
reject.

The extractable rule: **a queue is designed to be emptied, and a list is
designed to be browsed.** If your queue has filters, sorting and pagination, ask
whether you built a list and called it a queue.
