The clock
This design has exactly one dependency it does not control, and it is the machine clock. Clocks misbehave.
Time corrections step backward by milliseconds or more. A virtual machine migration jumps it. A rare leap-second bug shoves it a full second.
Follow what happens when your clock moves backward. Your generator revisits timestamps it already used, and with the same machine identifier and a reset sequence it mints duplicates of identifiers it issued moments ago.
Sit with that outcome. Duplicate primary keys, produced by the one component whose entire job was uniqueness.
Defend simply, and treat these as mandatory. Have your generator remember the last timestamp it used, and if the clock reads earlier, refuse to generate, either erroring or sleeping until the wall clock catches up. Alarm at the same time, because something is wrong with time on that machine.
Run your time synchronisation in the mode that adjusts gradually instead of stepping, on every generator host.
Look at how one variant spends the bit budget differently, using 10 millisecond units instead of one. That buys 174 years of range and eases the pressure on the sequence, at the cost of fewer identifiers per unit.
Two alternatives
Consider two alternatives that trade the clock dependency for other costs. Range allocation hands each server a block of, say, a thousand identifiers from a coordinator, and servers issue locally from their block, returning when it runs out.
Weigh it honestly. No clock at all, and near-zero coordination once you amortise it over the block. Your identifiers are only coarsely ordered, and a crashed server's unused block leaves permanent holes, fine until somebody treats identifiers as a count.
Push the problem into your database instead, the other direction. One well-known photo product built generation inside Postgres itself, packing time, shard and sequence bits in a stored function, with no separate service to operate.
Close an interview with the decision rule. Wanting them sortable, at a high rate, points to the Snowflake layout with clock guards. Not trusting clocks points to range allocation. And a small system should keep the database sequence it already has.
Worked example
A payments company runs Snowflake-style generators on 40 hosts. During a maintenance window, an engineer fixes a 3-second clock drift on one host by forcing an NTP step correction, and the clock jumps backward 3 seconds while the generator is serving traffic. The naive implementation has no last-timestamp guard, so for the next 3 seconds it re-mints timestamp values from the recent past, and 7 transaction IDs collide with IDs issued minutes earlier. The duplicates surface as unique-constraint violations in the ledger, the one place the company is lucky, because a constraint catches what the generator did not. The remediation ticket reads like the textbook: track last-issued timestamp and refuse to go backward, alert on refusal, switch NTP to slew-only on generator hosts, and add a canary that compares each host's clock against three peers every minute.