Skip to content
Development
Skill

/sequencer

This skill should be used when the user needs a "unique ID generator", "distributed IDs", a "Snowflake ID", asks "UUID vs auto-increment", wants a "time-sortable ID", a "monotonic sequence", a "ticket server", or "ID generation at scale". It gives a menu of ID schemes

From plugin
system-design-skills
7422 skills1 agent1 command
Install
$ npx -y skills add proyecto26/system-design-skills --skill sequencer --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/sequencer

Context preview

The summary Claude sees to decide when to auto-load this skill.

This skill should be used when the user needs a "unique ID generator", "distributed IDs", a "Snowflake ID", asks "UUID vs auto-increment", wants a "time-sortable ID", a "monotonic sequence", a "ticket server", or "ID generation at scale". It gives a menu of ID schemes

SKILL.md

sequencer.SKILL.md
name: sequencer
description: This skill should be used when the user needs a "unique ID generator", "distributed IDs", a "Snowflake ID", asks "UUID vs auto-increment", wants a "time-sortable ID", a "monotonic sequence", a "ticket server", or "ID generation at scale". It gives a menu of ID schemes (UUID/ULID, Snowflake-style, DB ticket/range) with their causality, ordering, and clock-skew trade-offs. Use it whenever a design needs collision-free identifiers across many nodes, even if the user doesn't say "sequencer".

Sequencer

Hand out identifiers that are unique across every node without a central bottleneck — and decide whether those IDs must also be *sortable* or *monotonic*. Getting this wrong shows up late and hard: collisions corrupt data, a single allocator caps write throughput, and IDs that leak a creation time or a sequential count expose business secrets and enable enumeration attacks.

When to reach for this

A system writes new records across multiple nodes and each needs a primary key (orders, messages, uploads, events). Reach for this when a single auto-increment column would serialize all writes, when IDs must be generated before a DB round trip (client-side, offline), or when records must be roughly time-ordered without a separate sort field.

When NOT to

A single relational node still comfortably serves the write load (→ `back-of-the-envelope`) — then a plain `BIGINT AUTO_INCREMENT`/`SERIAL` is the cheapest correct answer; do not build a distributed ID service for it (YAGNI). If a natural unique key already exists (email, ISBN, content hash), use it. Don't demand global monotonicity unless an invariant truly needs it — it is the most expensive property here and usually only *per-entity* ordering is required.

Clarify first

  • **Generation point** — client/edge, app server, or database? (Decides whether a

DB round trip per ID is acceptable.)

  • **Ordering need** — none, *time-sortable* (k-sorted is fine), or *strictly

monotonic*? Per-entity or global? This is the single biggest fork.

  • **Write rate & node count** — IDs/sec at peak and how many generators (→

`back-of-the-envelope`). Sets the bits needed for a sequence counter.

  • **Size & encoding budget** — 64-bit int (fits an indexed key cheaply) vs 128-bit

(no coordination ever) vs short URL-safe string?

  • **Leakage tolerance** — may the ID reveal creation time or a guessable count

(enumeration / competitor signal)?

The options

  • **Auto-increment / SQL sequence** — one DB column hands out IDs. Use when a

single node owns the writes and you want zero new infrastructure.

  • **UUIDv4 (random 128-bit)** — generate anywhere, no coordination, effectively

zero collision risk. Use when you only need uniqueness and never sort by ID.

  • **ULID / UUIDv7 (time-prefixed 128-bit)** — random but with a millisecond

timestamp prefix, so IDs sort by creation time. Use when you want UUIDv4's zero-coordination *and* time-ordering (the modern default for new keys).

  • **Snowflake-style (timestamp + node + sequence, 64-bit)** — pack a timestamp,

a node ID, and a per-ms counter into a sortable 64-bit int. Use at high write rates where a compact, k-sorted integer key matters.

  • **DB ticket / range allocation (Flickr-style)** — a central table hands out

*blocks* of IDs (e.g. 1000 at a time); each node serves from its block in memory. Use when you want simple monotonic-ish integers without per-ID coordination.

Trade-offs

| Option | What it solves | What it worsens | Change it when | |---|---|---|---| | Auto-increment / sequence | Trivial, monotonic, compact int | Serializes writes; single node caps throughput; leaks count | Writes outgrow one node, or you need client-side IDs → ticket/Snowflake | | UUIDv4 (random) | Generate anywhere, no coordination, no leakage | 128-bit; random order kills index locality (page splits); not sortable | You need time-ordering → ULID/UUIDv7 | | ULID / UUIDv7 | Zero coordination + time-sortable + index-friendly | Still 128-bit; only ms-sortable (not strict); leaks creation time | You need a 64-bit key or strict order → Snowflake / sequence | | Snowflake-style (64-bit) | Compact, k-sorted, ~4M IDs/node/sec | Needs node-ID assignment + clock-skew handling; epoch/bit budget caps lifespan | Clock sync is unreliable, or you can't assign node IDs → ULID | | DB ticket / range | Monotonic-ish ints, low coordination, simple | Allocator table is a SPOF; gaps on restart; only loosely ordered across nodes | Allocator becomes a bottleneck or SPOF → Snowflake/ULID |

Behavior under stress

The whole point of distributed ID schemes is to avoid a single allocator, so the failure modes cluster around *coordination shortcuts*.

  • **Allocator as SPOF/bottleneck (ticket, single sequence):** every write blocks on

one row/node. A spike or its failure stalls all inserts. *Mitigate:* hand out larger ranges, replicate the allocator, or move to Snowflake/ULID (no central hop). Larger ranges trade away monotonicity and waste IDs on restart.

  • **Clock skew & rewind (Snowflake/time-prefixed):** if a node's clock jumps

backward (NTP correction, VM pause), it can re-emit a timestamp it already used and collide within its node+sequence space. *Mitigate:* refuse to emit while `now < last_timestamp` (block or error), use a monotonic clock source, and alarm on skew. Never silently trust wall-clock time.

  • **Sequence-bits exhaustion:** more than `2^seq_bits` IDs in one millisecond on

one node overflows the counter. *Mitigate:* spin-wait to the next ms, or size the bit budget to peak rate up front.

  • **Node-ID collision:** two generators boot with the same node ID (bad config,

autoscaling reuse) and silently mint duplicates. *Mitigate:* lease node IDs from a coordinator (→ `consistency-coordination`) instead of static config.

  • **Hot shard from sequential keys:** monotonic IDs as a shard/partition key send

all new writes to one shard. *Mitigate:* hash the key or prefix-shard

Read more
Ships withsystem-design-skills

Design scalable systems the way strong engineers actually do — by reasoning, not by memorizing diagrams.

Get the whole plugin
Stats
75
Stars
8
Forks
Maintained
Maintenance
JavaScript
Language
MIT
License
3mo ago
Last commit
3mo ago
Created

Repo: proyecto26/system-design-skills

Other skills on system-design-skills.