---
title: UUIDv7における連続発行時の単調性の保証方法
tags: 
author: [jyuch](https://convert.docswell.com/user/jyuch)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/LELM4DXM7R.jpg?width=480
description: UUIDv7における連続発行時の単調性の保証方法 by jyuch
published: February 15, 26
canonical: https://convert.docswell.com/s/jyuch/K37PEJ-2026-02-15-180000
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/LELM4DXM7R.jpg)

UUIDv7における連続発行時の単調性の保証方法
@jyuch


# Page. 2

![Page Image](https://bcdn.docswell.com/page/4JMYKPL6JW.jpg)

自己紹介
• @jyuch
• 都内でデータエンジニアをしています
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/PJR9X1KN79.jpg)

アジェンダ
• UUIDの基本
• 単調性を保証するためにRFCで提案されている方法
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/PEXQ6YL8JX.jpg)

UUIDの基本
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/3EK913LLED.jpg)

UUID
A UUID is 128 bits long and is intended to guarantee uniqueness across space and time.
• 128bitからなる識別子
• 空間と時間にわたって一意性を保証する
• 00000000-0000-0000-0000-000000000000 みたいな見た目
• 最新の仕様はRFC9562で規定されている
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/L73WQG3675.jpg)

UUIDの各バージョン
UUIDv1
100ナノ秒単位のタイムスタンプ＋重複回避用のクロックシーケンス＋ノードID
タイムスタンプを下位ビットから並べているせいで生成順にソート出来ない
UUIDv2
（RFC9562で規定されていないので割愛）
UUIDv3
名前空間内で名前から一意な値を生成する（MD5）
UUIDv4
（バージョンとバリアントフィールド以外）完全にランダム
UUIDv5
名前空間内で名前から一意な値を生成する（SHA-1）
UUIDv6
UUIDv1のタイムスタンプを上位ビットから並べて生成順にソート可能にしたもの
UUIDv7
ミリ秒単位のUNIXタイムスタンプ＋ランダム値で生成順にソート可能にしたもの
UUIDv8
ベンダー固有
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/87DK914MJG.jpg)

（UUIDv6ではなく）UUIDv7を採用するモチベーション
• UUIDv1は解析しないとソート出来ない
• 一般的なガイダンスとして、UUIDの解析は避ける（Section 6.12.）
• UUIDv1 / UUIDv6のタイムスタンプは実装が大変
• グレゴリオエポックをIEEE754で実装することはまれ（Section 2.1.）
• UUIDv1 / UUIDv6は実装によってはMACアドレスが露出する
• MACアドレスをUUID内で使用すべきではない（Section 8.）
• UUIDv1 / UUIDv6はUUIDv7と比べてエントロピーが小さい
• UUIDv7でエントロピー特性を改善している（Section 5.7.）
タイムベースなUUIDを使用するならUUIDv7を採用するべき（Section 5.6.）
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/VJPKZQMQE8.jpg)

UUIDv7のフィールド及びビットレイアウト
0
1
2
3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
unix_ts_ms
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
unix_ts_ms
| ver |
rand_a
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var|
rand_b
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
rand_b
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 11: UUIDv7 Field and Bit Layout
unix_ts_ms
rand_a
rand_b
00000000-0000-7000-8000-000000000000
ver
var
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/2EVVW59PEQ.jpg)

UUIDv7のフィールド及びビットレイアウト
フィールド
説明
unix_ts_ms
48ビットで表現されたミリ秒単位のUnixエポックタイムスタンプ
rand_a
12ビットのランダムフィールド
rand_b
62ビットのランダムフィールド
UUIDv7のタイムスタンプはミリ秒精度
ナイーブに実装すると同一ミリ秒内で生成順にソート出来なくなる
（単調性が保証できなくなる）
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/57GLD6ZQEL.jpg)

追加の単調性を保証するためにRFCで提案されている方法
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/4EQY14LWJP.jpg)

追加の単調性を保証するためにRFCで提案されている方法
RFCでは以下の3つが提案されている
（Section 6.2. Monotonicity and Counters）
• 固定ビット長カウンター（Method 1）
• 単調増加するランダム値（Method 2）
• 追加のクロック精度の導入（Method 3）
いずれもrand_a（とrand_bの左側ビット）を使用してソート可能にしている
また、いずれもシングルノードでの生成を想定している
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/KJ4WRQD171.jpg)

固定ビット長カウンター
• rand_aの全体もしくは一部をカウンターとして使用
• さらにカウンター長が必要ならrand_bの一部も使用する
• タイムスタンプティック内で生成するたびにカウンターをインクリメントする
00000000-0000-7000-8???-????????????
00000000-0000-7001-8???-????????????
00000000-0000-7002-8???-????????????
00000000-0000-7003-8???-????????????
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/LE1YQPZ57G.jpg)

単調増加するランダム値
• タイムスタンプティック内で生成するたびにランダム値を加算
• 初回はふつうにUUIDv7を生成
• 同一タイムスタンプティック内であれば、前回の値にランダム値を加算
00000000-0000-7000-8000-000000000000
+5
00000000-0000-7000-8000-000000000005
+2
00000000-0000-7000-8000-000000000007
+3
00000000-0000-7000-8000-00000000000A
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/GEWGM29WJ2.jpg)

追加のクロック精度の導入
• rand_aを追加のタイムスタンプフィールドとして使用
• rand_aにはサブミリ秒をエンコードして格納する
• PostgreSQLのuuidv7()ではプラットフォームで精度が変わる
• OSから供給されるクロックの精度が変わるから
• Linuxではナノ秒を12ビットにエンコード
• Windows / Mac OSではマイクロ秒を10ビットにエンコード
• サブミリ秒が衝突した場合はティックを進めて衝突を回避する
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/47ZLQD92J3.jpg)

まとめ
• タイムベースのUUIDを使うならUUIDv7を使う
• UUIDv1 / UUIDv6は互換性が必要な用途以外では非推奨
• タイムスタンプはミリ秒精度
• サブミリ秒を取り出せる場合もあるが、生成側の実装依存
• 実装によっては同一ミリ秒内でも単調性を保証する
• RFCで提案しているのは以下の方法
• 固定ビット長カウンター
• 単調増加するランダム値
• 追加のクロックの導入
15


