Inspiration

74.5% of Reddit moderators report queue collisions — two mods independently banning the same user, removing the same post, or replying to the same modmail (Park et al., "Think about it like you're a firefighter," CHI 2026, arxiv 2509.07314).

Reddit's own "real-time indicator" is reactive (the Approve/Remove button just disappears once another mod clicks), Card-View-only, and desktop-only. Mods describe it as "so subtle and unreliable that I don't pay attention to them." We built the version mods actually want.

What it does

  • A mod clicks "ModQueueCue: Claim for review" on any post in the mod queue.
  • Every other mod sees a colored "Under review" flair pill on the post within ~1 second.
  • If another mod tries to claim, they get an instant warning: "⚠ Already claimed by u/sarah (14s ago)."
  • The claim auto-releases after 5 minutes (configurable) OR instantly when the claiming mod approves/removes the post.
  • Works on the Reddit iOS app, Android app, Old Reddit, and New Reddit — Reddit's own indicator works on zero of these surfaces. Since the majority of Reddit moderation happens on mobile, this is the biggest single coverage gap ModQueueCue closes.

How we built it

  • Devvit Web 0.13 (TypeScript, server-side only)
  • Atomic claim acquisition via Redis SETNX + EX in one round-trip — race-free even with simultaneous clicks. Two mods clicking "Claim" at the exact same millisecond → only one wins, always.
  • Privacy-by-design dual-channel architecture: realtime broadcasts contain only {postId, claimedAt, expiresAt} — no mod identity ever crosses the wire. Mod identity is revealed only through an authenticated /api/claim endpoint that verifies mod status server-side.
  • Mod-only flair template (modOnly: true) auto-created on install — locks the OP out of editing the badge.
  • Time-budgeted orphan-sweep cron (every minute) restores stale flair if a claim expires without explicit release.
  • Crash-safe ordering: restore flair before deleting claim → orphan-sweep can always recover.
  • Strict TypeScript (isolatedDeclarations, noUncheckedIndexedAccess, verbatimModuleSyntax).
  • Vitest unit tests + settings-parity test + SETNX-semantics regression test (18 tests passing).

Challenges we ran into

  • The flair-restore race. When a claim expires and a fresh mod claims the same post in the same Redis tick, naive snapshot → apply could save our own "Under review" badge as the "original" — making the badge permanent. Fix: SETNX on snapshot writes (only preserve if none exists), and restore-before-cleanup ordering so orphan-sweep is idempotent.
  • Devvit Redis SET NX returns "" on rejection, not null. Standard Redis returns nil; Devvit's SDK normalizes that to an empty string. Initial implementation checked === null — silently broken. Verified against node_modules/@devvit/redis/test/mocks/RedisMock.js and added a regression test that pins the production semantics.
  • No documented inline-render hook for the native mod queue page. We use a modOnly flair template — the only Reddit primitive that renders inline on every queue card on every client (iOS app, Android app, Old Reddit, New Reddit).

Accomplishments that we're proud of

  • Atomic claim semantics. Two mods clicking at the exact same millisecond → only one wins.
  • Beats Reddit's native indicator on coverage by a mile — ModQueueCue works on the iOS app, the Android app, Old Reddit, and every view mode of New Reddit. Reddit's native indicator works on exactly one surface (New Reddit Card View desktop). Mobile is where mods actually live.
  • Privacy boundary holds: a non-mod cannot learn which mod is reviewing what, even by subscribing to the realtime channel.
  • 18 unit tests, GitHub Actions CI, README + CHANGELOG + LICENSE + privacy docs — production-grade housekeeping from v0.1.

What we learned

  • Devvit Web 0.13 is significantly different from Blocks-era examples — entire declarative config in devvit.json instead of Devvit.addMenuItem(...) style.
  • Reddit's docs lag the source; reading node_modules/@devvit/... type defs and mocks was the only reliable source of truth.
  • The flair API is wildly more useful than it looks — modOnly: true templates are a hidden mod-only rendering surface on every queue card.

What's next for ModQueueCue

  • Mod-only Devvit Web dashboard with always-on per-item presence avatars beside the native queue.
  • Slack/Discord webhooks when a long-running claim is about to expire.
  • Cross-sub spam-signal opt-in network (URL/image-hash sharing, no user data).
  • Claim semantics on queue comments, not just posts.

Built With

Share this project:

Updates