diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c
index f8b8b590216..ac094ac5901 100644
--- a/src/backend/utils/adt/uuid.c
+++ b/src/backend/utils/adt/uuid.c
@@ -13,17 +13,30 @@
 
 #include "postgres.h"
 
+#include <time.h> /* for clock_gettime() */
+
 #include "common/hashfn.h"
 #include "lib/hyperloglog.h"
 #include "libpq/pqformat.h"
 #include "port/pg_bswap.h"
-#include "portability/instr_time.h"
 #include "utils/fmgrprotos.h"
 #include "utils/guc.h"
 #include "utils/sortsupport.h"
 #include "utils/timestamp.h"
 #include "utils/uuid.h"
 
+/* helper macros */
+#define NS_PER_S	INT64CONST(1000000000)
+#define NS_PER_MS	INT64CONST(1000000)
+#define NS_PER_US	INT64CONST(1000)
+
+/*
+ * In UUID version 7, we use 12 bits in "rand_a" to store 1/4096 fractions of
+ * sub-millisecond. This is the minimum amount of nanoseconds that guarantees
+ * step of UUID increased clock precision.
+ */
+#define SUBMS_MINIMAL_STEP ((NS_PER_MS / (1 << 12)) + 1)
+
 /* sortsupport for uuid */
 typedef struct
 {
@@ -39,7 +52,7 @@ static int	uuid_fast_cmp(Datum x, Datum y, SortSupport ssup);
 static bool uuid_abbrev_abort(int memtupcount, SortSupport ssup);
 static Datum uuid_abbrev_convert(Datum original, SortSupport ssup);
 static inline void uuid_set_version(pg_uuid_t *uuid, unsigned char version);
-static inline uint64 get_real_time_ns_ascending();
+static inline int64 get_real_time_ns_ascending();
 
 Datum
 uuid_in(PG_FUNCTION_ARGS)
@@ -404,14 +417,13 @@ uuid_hash_extended(PG_FUNCTION_ARGS)
 	return hash_any_extended(key->data, UUID_LEN, PG_GETARG_INT64(1));
 }
 
-/*
- * Set magic numbers for a UUID variant 3
- * https://www.rfc-editor.org/rfc/rfc9562
- */
-static inline void uuid_set_version(pg_uuid_t *uuid, unsigned char version)
+/* Set the given UUID version and the variant bits */
+static inline void
+uuid_set_version(pg_uuid_t *uuid, unsigned char version)
 {
 	/* set version field, top four bits */
 	uuid->data[6] = (uuid->data[6] & 0x0f) | (version << 4);
+
 	/* set variant field, top two bits are 1, 0 */
 	uuid->data[8] = (uuid->data[8] & 0x3f) | 0x80;
 }
@@ -433,8 +445,8 @@ gen_random_uuid(PG_FUNCTION_ARGS)
 				 errmsg("could not generate random values")));
 
 	/*
-	 * Set magic numbers for a "version 4" (pseudorandom) UUID, see
-	 * https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-4
+	 * Set magic numbers for a "version 4" (pseudorandom) UUID and
+	 * variant, see https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-4
 	 */
 	uuid_set_version(uuid, 4);
 
@@ -442,44 +454,63 @@ gen_random_uuid(PG_FUNCTION_ARGS)
 }
 
 /*
- * Aquire nanosecond reading and ensure it is ascending (on this backend)
+ * Get the current timestamp with nanosecond precision for UUID generation.
+ * The returned timestamp is ensured to be at least SUBMS_MINIMAL_STEP greater
+ * than the previous returned timestamp (on this backend).
  */
-static inline uint64 get_real_time_ns_ascending()
+static inline int64
+get_real_time_ns_ascending()
 {
-	static uint64 previous_ns = 0;
+	static int64 previous_ns = 0;
+	int64 ns;
+
+	/* Get the current real timestamp */
+
+#ifdef	WIN32
+	struct timeval tmp;
+
+	gettimeofday(&tp, NULL);
+	ns = tmp.tv_sec * NS_PER_S + tmp.tv_usec * NS_PER_US;
+#else
 	struct timespec tmp;
-	uint64 ns;
 
-	/* We use some bits of nanosecond precision, so we cannot resort to gettimeofday() */
+	/*
+	 * We don't use gettimeofday() where available, instead use clock_gettime()
+	 * with CLOCK_REALTIME in order to get a high-precision (nanoseconds) real
+	 * timestamp.
+	 *
+	 * Note that a timestamp returned by clock_gettime() with CLOCK_REALTIME
+	 * is nanosecond-precision on most Unix-like platforms. On some platforms
+	 * such as macOS, it's restricted to microsecond-precision.
+	 */
 	clock_gettime(CLOCK_REALTIME, &tmp);
-	ns = tmp.tv_sec * 1000000000L + tmp.tv_nsec;
+	ns = tmp.tv_sec * NS_PER_S + tmp.tv_nsec;
+#endif
 
-	/* minimum amount of ns that guarantees step of UUID increased clock precision */
-#define SUB_MILLISECOND_STEP ((NS_PER_MS / (1 << 12)) + 1)
-	if (previous_ns + SUB_MILLISECOND_STEP >= ns)
-		ns = previous_ns + SUB_MILLISECOND_STEP;
+	/* Guarantee the minimal step advancement of the timestamp */
+	if (previous_ns + SUBMS_MINIMAL_STEP >= ns)
+		ns = previous_ns + SUBMS_MINIMAL_STEP;
 	previous_ns = ns;
 
 	return ns;
 }
 
 /*
- * Generate UUID version 7 per RFC 9562.
+ * Generate UUID version 7 per RFC 9562, with the given timestamp.
  *
- * Monotonicity (regarding generation on given backend) is ensured with method
- * "Replace Leftmost Random Bits with Increased Clock Precision (Method 3)".
- * We use 12 bits in "rand_a" bits to store 1/4096 fractions of millisecond.
- * Usage of pg_testtime indicates that such precision is available on most
- * systems. If timestamp is not advancing between two consecutive UUID
- * generations, previous timestamp is incremented and used instead of current
- * timestamp.
+ * UUID version 7 consists of a Unix timestamp in milliseconds (48 bits) and
+ * 74 random bits, excluding the required version and variant bits. To ensure
+ * monotonicity in scenarios of high-frequency UUID generation, we employ the
+ * method "Replace Leftmost Random Bits with Increased Clock Precision (Method 3)".
+ * This method utilizes 12 bits from the "rand_a" bits to store a 1/4096
+ * (or 2^12) fraction of sub-millisecond precision.
  */
-static Datum
-generate_uuidv7(uint64 ns)
+static pg_attribute_always_inline pg_uuid_t *
+generate_uuidv7(int64 ns)
 {
 	pg_uuid_t	*uuid = palloc(UUID_LEN);
-	uint64		 unix_ts_ms;
-	uint16 		 increased_clock_precision;
+	int64		 unix_ts_ms;
+	int32 		 increased_clock_precision;
 
 	unix_ts_ms = ns / NS_PER_MS;
 
@@ -494,6 +525,7 @@ generate_uuidv7(uint64 ns)
 	/* sub-millisecond timestamp fraction (12 bits) */
 	increased_clock_precision = ((ns % NS_PER_MS) * (1 << 12)) / NS_PER_MS;
 
+	/* Fill the increased clock precision to "rand_a" bits */
 	uuid->data[6] = (unsigned char) (increased_clock_precision >> 8);
 	uuid->data[7] = (unsigned char) (increased_clock_precision);
 
@@ -504,51 +536,62 @@ generate_uuidv7(uint64 ns)
 				 errmsg("could not generate random values")));
 
 	/*
-	 * Set magic numbers for a "version 7" (pseudorandom) UUID, see
-	 * https://www.rfc-editor.org/rfc/rfc9562#name-version-field
+	 * Set magic numbers for a "version 7" (pseudorandom) UUID and
+	 * variant, see https://www.rfc-editor.org/rfc/rfc9562#name-version-field
 	 */
 	uuid_set_version(uuid, 7);
 
-	PG_RETURN_UUID_P(uuid);
+	return uuid;
 }
 
 /*
- * Entry point for uuidv7()
+ * Generate UUID version 7 with the current timestamp.
  */
 Datum
 uuidv7(PG_FUNCTION_ARGS)
 {
-   return generate_uuidv7(get_real_time_ns_ascending());
+	pg_uuid_t *uuid = generate_uuidv7(get_real_time_ns_ascending());
+
+	PG_RETURN_UUID_P(uuid);
 }
 
 /*
- * Entry point for uuidv7(interval)
+ * Similar to uuidv7() but with the timestamp adjusted by the given interval.
  */
 Datum
 uuidv7_interval(PG_FUNCTION_ARGS)
 {
-	uint64 ns = get_real_time_ns_ascending();
+	Interval *span = PG_GETARG_INTERVAL_P(0);
+	TimestampTz ts;
+	pg_uuid_t *uuid;
+	int64 ns = get_real_time_ns_ascending();
+
 	/*
-	 * We are given a time shift interval as an argument.
-	 * The interval represent days, monthes and years, that are not fixed
-	 * number of nanoseconds. To make correct computations we call
-	 * timestamptz_pl_interval() with corresponding logic. This logic is
-	 * implemented with microsecond precision. So we carry nanoseconds
-	 * between computations.
+	 * Shift the current timestamp by the given interval. To make correct
+	 * calculating the time shift, we convert the UNIX epoch to TimestampTz
+	 * and use timestamptz_pl_interval(). Since this calculation is done with
+	 * microsecond precision, we carry back the nanoseconds.
 	 */
-	Interval *span = PG_GETARG_INTERVAL_P(0);
-	/* Convert time part of UUID to Timestamptz (ms since Postgres epoch) */
-	TimestampTz ts = (TimestampTz) (ns / 1000) -
+
+	ts = (TimestampTz) (ns / NS_PER_US) -
 		(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY * USECS_PER_SEC;
 
 	/* Copmute time shift */
 	ts = DatumGetTimestampTz(DirectFunctionCall2(timestamptz_pl_interval,
-													TimestampTzGetDatum(ts),
-													IntervalPGetDatum(span)));
-	/* Convert TimestampTz back and carry nanoseconds. */
+												 TimestampTzGetDatum(ts),
+												 IntervalPGetDatum(span)));
+
+	/*
+	 * Convert a TimestampTz value back to an UNIX epoch and carry back
+	 * nanoseconds.
+	 */
 	ns = (ts + (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY * USECS_PER_SEC)
-		* 1000 + ns % 1000;
-   return generate_uuidv7(ns);
+		* NS_PER_US + ns % NS_PER_US;
+
+	/* Generate an UUID */
+	uuid = generate_uuidv7(ns);
+
+	PG_RETURN_UUID_P(uuid);
 }
 
 /*
@@ -603,7 +646,7 @@ uuid_extract_timestamp(PG_FUNCTION_ARGS)
 			+ (((uint64) uuid->data[0]) << 40);
 
 		/* convert ms to us, then adjust */
-		ts = (TimestampTz) (tms * 1000) -
+		ts = (TimestampTz) (tms * NS_PER_US) -
 			(POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY * USECS_PER_SEC;
 
 		PG_RETURN_TIMESTAMPTZ(ts);
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index d343e6c1875..7789e0431aa 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -184,20 +184,6 @@
 #ifdef _MSC_VER
 /* Last parameter not used */
 extern int	gettimeofday(struct timeval *tp, void *tzp);
-
-/*
- * Windows implementation is limited to CLOCK_REALTIME
- */
-typedef enum {
-	CLOCK_REALTIME
-} clockid_t;
-
-#include <time.h> /* for timespec */
-
-extern int clock_gettime(clockid_t clock_id, struct timespec *tp);
-#else
-/* MinGW */
-#include "pthread_time.h"
 #endif
 
 /* for setitimer in backend/port/win32/timer.c */
diff --git a/src/port/win32gettimeofday.c b/src/port/win32gettimeofday.c
index 93ec3bf731c..1e00f7ee149 100644
--- a/src/port/win32gettimeofday.c
+++ b/src/port/win32gettimeofday.c
@@ -41,7 +41,6 @@ static const unsigned __int64 epoch = UINT64CONST(116444736000000000);
  */
 #define FILETIME_UNITS_PER_SEC	10000000L
 #define FILETIME_UNITS_PER_USEC 10
-#define FILETIME_UNITS_TO_NS	100L
 
 
 /*
@@ -74,24 +73,3 @@ gettimeofday(struct timeval *tp, void *tzp)
 
 	return 0;
 }
-
-/*
- * This function is ported for UUID purposes.
- */
-int
-clock_gettime(clockid_t clock_id, struct timespec *tp)
-{
-	Assert(clock_id == CLOCK_REALTIME);
-
-	FILETIME	file_time;
-	ULARGE_INTEGER ularge;
-	GetSystemTimePreciseAsFileTime(&file_time);
-	ularge.LowPart = file_time.dwLowDateTime;
-	ularge.HighPart = file_time.dwHighDateTime;
-
-	tp->tv_sec = (long) ((ularge.QuadPart - epoch) / FILETIME_UNITS_PER_SEC);
-	tp->tv_nsec = (long) (((ularge.QuadPart - epoch) % FILETIME_UNITS_PER_SEC)
-						  * FILETIME_UNITS_TO_NS);
-
-	return 0;
-}
\ No newline at end of file
diff --git a/src/test/regress/expected/uuid.out b/src/test/regress/expected/uuid.out
index aa6224e81bb..bd83f6b0763 100644
--- a/src/test/regress/expected/uuid.out
+++ b/src/test/regress/expected/uuid.out
@@ -10,6 +10,11 @@ CREATE TABLE guid2
 	guid_field UUID,
 	text_field TEXT DEFAULT(now())
 );
+CREATE TABLE guid3
+(
+	id SERIAL,
+	guid_field UUID
+);
 -- inserting invalid data tests
 -- too long
 INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111F');
@@ -189,6 +194,14 @@ SELECT count(DISTINCT guid_field) FROM guid1;
      3
 (1 row)
 
+-- test sortability of v7
+INSERT INTO guid3 (guid_field) SELECT uuidv7() FROM generate_series(1, 10);
+SELECT array_agg(id ORDER BY guid_field) FROM guid3;
+       array_agg        
+------------------------
+ {1,2,3,4,5,6,7,8,9,10}
+(1 row)
+
 -- extract functions
 -- version
 SELECT uuid_extract_version('11111111-1111-5111-8111-111111111111');  -- 5
@@ -247,4 +260,4 @@ SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111');  -- null
 (1 row)
 
 -- clean up
-DROP TABLE guid1, guid2 CASCADE;
+DROP TABLE guid1, guid2, guid3 CASCADE;
diff --git a/src/test/regress/sql/uuid.sql b/src/test/regress/sql/uuid.sql
index eec7f160f81..8e54217a75c 100644
--- a/src/test/regress/sql/uuid.sql
+++ b/src/test/regress/sql/uuid.sql
@@ -10,6 +10,11 @@ CREATE TABLE guid2
 	guid_field UUID,
 	text_field TEXT DEFAULT(now())
 );
+CREATE TABLE guid3
+(
+	id SERIAL,
+	guid_field UUID
+);
 
 -- inserting invalid data tests
 -- too long
@@ -98,6 +103,9 @@ INSERT INTO guid1 (guid_field) VALUES (uuidv7());
 INSERT INTO guid1 (guid_field) VALUES (uuidv7(INTERVAL '1 day'));
 SELECT count(DISTINCT guid_field) FROM guid1;
 
+-- test sortability of v7
+INSERT INTO guid3 (guid_field) SELECT uuidv7() FROM generate_series(1, 10);
+SELECT array_agg(id ORDER BY guid_field) FROM guid3;
 
 -- extract functions
 
@@ -116,4 +124,4 @@ SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111');  -- null
 
 
 -- clean up
-DROP TABLE guid1, guid2 CASCADE;
+DROP TABLE guid1, guid2, guid3 CASCADE;
