diff --git a/configure.ac b/configure.ac
index f1c5b0419..96b805aa4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1735,6 +1735,22 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
 	AC_MSG_RESULT(no)
     ])
 
+    AC_CHECK_DECL([CLOCK_MONOTONIC]
+        , []
+        , [AC_MSG_ERROR([ngtcp2 for QUIC needs at least CLOCK_MONOTONIC on the system])]
+        , [AC_INCLUDES_DEFAULT
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+        ])
+
 fi
 
 # set static linking for uninstalled libraries if requested
diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c
index 5db2b940b..a08a5352e 100644
--- a/services/listen_dnsport.c
+++ b/services/listen_dnsport.c
@@ -42,7 +42,6 @@
 #ifdef HAVE_SYS_TYPES_H
 #  include <sys/types.h>
 #endif
-#include <sys/time.h>
 #include <limits.h>
 #ifdef USE_TCP_FASTOPEN
 #include <netinet/tcp.h>
@@ -3399,14 +3398,13 @@ doq_table_delete(struct doq_table* table)
 }
 
 struct doq_timer*
-doq_timer_find_time(struct doq_table* table, struct timeval* tv)
+doq_timer_find_time(struct doq_table* table, ngtcp2_tstamp ts)
 {
 	struct doq_timer key;
 	struct rbnode_type* node;
 	log_assert(table != NULL);
 	memset(&key, 0, sizeof(key));
-	key.time.tv_sec = tv->tv_sec;
-	key.time.tv_usec = tv->tv_usec;
+	key.time_mono = ts;
 	node = rbtree_search(table->timer_tree, &key);
 	if(node)
 		return (struct doq_timer*)node->key;
@@ -3454,7 +3452,7 @@ doq_timer_list_remove(struct doq_table* table, struct doq_timer* timer)
 	if(!timer->timer_in_list)
 		return;
 	/* The item in the rbtree has the list start and end. */
-	rb_timer = doq_timer_find_time(table, &timer->time);
+	rb_timer = doq_timer_find_time(table, timer->time_mono);
 	if(rb_timer) {
 		if(timer->setlist_prev)
 			timer->setlist_prev->setlist_next = timer->setlist_next;
@@ -3500,7 +3498,8 @@ doq_timer_unset(struct doq_table* table, struct doq_timer* timer)
 }
 
 void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
-	struct doq_server_socket* worker_doq_socket, struct timeval* tv)
+	struct doq_server_socket* worker_doq_socket, struct timeval* tv,
+	ngtcp2_tstamp ts)
 {
 	struct doq_timer* rb_timer;
 	if(verbosity >= VERB_ALGO && timer->conn) {
@@ -3514,14 +3513,14 @@ void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
 			(int)rel.tv_sec, (int)rel.tv_usec);
 	}
 	if(timer->timer_in_tree || timer->timer_in_list) {
-		if(timer->time.tv_sec == tv->tv_sec &&
-			timer->time.tv_usec == tv->tv_usec)
+		if(timer->time_mono == ts)
 			return; /* already set on that time */
 		doq_timer_unset(table, timer);
 	}
-	timer->time.tv_sec = tv->tv_sec;
-	timer->time.tv_usec = tv->tv_usec;
-	rb_timer = doq_timer_find_time(table, tv);
+	timer->time_real.tv_sec = tv->tv_sec;
+	timer->time_real.tv_usec = tv->tv_usec;
+	timer->time_mono = ts;
+	rb_timer = doq_timer_find_time(table, ts);
 	if(rb_timer) {
 		/* There is a timeout already with this value. Timer is
 		 * added to the setlist. */
@@ -3700,13 +3699,9 @@ int doq_timer_cmp(const void* key1, const void* key2)
 {
 	struct doq_timer* e = (struct doq_timer*)key1;
 	struct doq_timer* f = (struct doq_timer*)key2;
-	if(e->time.tv_sec < f->time.tv_sec)
-		return -1;
-	if(e->time.tv_sec > f->time.tv_sec)
-		return 1;
-	if(e->time.tv_usec < f->time.tv_usec)
+	if(e->time_mono < f->time_mono)
 		return -1;
-	if(e->time.tv_usec > f->time.tv_usec)
+	if(e->time_mono > f->time_mono)
 		return 1;
 	return 0;
 }
@@ -4254,12 +4249,11 @@ doq_submit_new_token(struct doq_conn* conn)
 	ngtcp2_ssize tokenlen;
 	int ret;
 	const ngtcp2_path* path = ngtcp2_conn_get_path(conn->conn);
-	ngtcp2_tstamp ts = doq_get_timestamp_nanosec();
 
 	tokenlen = ngtcp2_crypto_generate_regular_token(token,
 		conn->doq_socket->static_secret,
 		conn->doq_socket->static_secret_len, path->remote.addr,
-		path->remote.addrlen, ts);
+		path->remote.addrlen, doq_get_timestamp_nanosec());
 	if(tokenlen < 0) {
 		log_err("doq ngtcp2_crypto_generate_regular_token failed");
 		return 1;
@@ -5101,23 +5095,30 @@ doq_conn_clear_conids(struct doq_conn* conn)
 
 ngtcp2_tstamp doq_get_timestamp_nanosec(void)
 {
-#ifdef CLOCK_REALTIME
 	struct timespec tp;
 	memset(&tp, 0, sizeof(tp));
-	/* Get a nanosecond time, that can be compared with the event base. */
-	if(clock_gettime(CLOCK_REALTIME, &tp) == -1) {
-		log_err("clock_gettime failed: %s", strerror(errno));
+#ifdef CLOCK_BOOTTIME
+	if(clock_gettime(CLOCK_BOOTTIME, &tp) == -1) {
+#endif
+		if(clock_gettime(CLOCK_MONOTONIC, &tp) == -1) {
+			log_err("clock_gettime failed: %s", strerror(errno));
+		}
+#ifdef CLOCK_BOOTTIME
 	}
+#endif
 	return ((uint64_t)tp.tv_sec)*((uint64_t)1000000000) +
 		((uint64_t)tp.tv_nsec);
-#else
+}
+
+static struct timeval doq_get_timevalue(void)
+{
 	struct timeval tv;
+	memset(&tv, 0, sizeof(tv));
 	if(gettimeofday(&tv, NULL) < 0) {
 		log_err("gettimeofday failed: %s", strerror(errno));
+		memset(&tv, 0, sizeof(tv));
 	}
-	return ((uint64_t)tv.tv_sec)*((uint64_t)1000000000) +
-		((uint64_t)tv.tv_usec)*((uint64_t)1000);
-#endif /* CLOCK_REALTIME */
+	return tv;
 }
 
 /** doq start the closing period for the connection. */
@@ -5240,18 +5241,17 @@ doq_conn_recv(struct comm_point* c, struct doq_pkt_addr* paddr,
 	int* err_drop)
 {
 	int ret;
-	ngtcp2_tstamp ts;
 	struct ngtcp2_path path;
 	memset(&path, 0, sizeof(path));
 	path.remote.addr = (struct sockaddr*)&paddr->addr;
 	path.remote.addrlen = paddr->addrlen;
 	path.local.addr = (struct sockaddr*)&paddr->localaddr;
 	path.local.addrlen = paddr->localaddrlen;
-	ts = doq_get_timestamp_nanosec();
 
 	ret = ngtcp2_conn_read_pkt(conn->conn, &path, pi,
 		sldns_buffer_begin(c->doq_socket->pkt_buf),
-		sldns_buffer_limit(c->doq_socket->pkt_buf), ts);
+		sldns_buffer_limit(c->doq_socket->pkt_buf),
+		doq_get_timestamp_nanosec());
 	if(ret != 0) {
 		if(err_retry)
 			*err_retry = 0;
@@ -5339,7 +5339,6 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
 {
 	struct doq_stream* stream = conn->stream_write_first;
 	ngtcp2_path_storage ps;
-	ngtcp2_tstamp ts = doq_get_timestamp_nanosec();
 	size_t num_packets = 0, max_packets = 65535;
 	ngtcp2_path_storage_zero(&ps);
 
@@ -5392,7 +5391,8 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
 		ret = ngtcp2_conn_writev_stream(conn->conn, &ps.path, &pi,
 			sldns_buffer_begin(c->doq_socket->pkt_buf),
 			sldns_buffer_remaining(c->doq_socket->pkt_buf),
-			&ndatalen, flags, stream_id, datav, datav_count, ts);
+			&ndatalen, flags, stream_id, datav, datav_count,
+			doq_get_timestamp_nanosec());
 		if(ret < 0) {
 			if(ret == NGTCP2_ERR_WRITE_MORE) {
 				verbose(VERB_ALGO, "doq: write more, ndatalen %d", (int)ndatalen);
@@ -5464,7 +5464,8 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
 		if(ret == 0) {
 			/* congestion limited */
 			doq_conn_write_disable(conn);
-			ngtcp2_conn_update_pkt_tx_time(conn->conn, ts);
+			ngtcp2_conn_update_pkt_tx_time(conn->conn,
+				doq_get_timestamp_nanosec());
 			return 1;
 		}
 		sldns_buffer_set_position(c->doq_socket->pkt_buf, ret);
@@ -5478,7 +5479,7 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
 		if(stream)
 			stream = stream->write_next;
 	}
-	ngtcp2_conn_update_pkt_tx_time(conn->conn, ts);
+	ngtcp2_conn_update_pkt_tx_time(conn->conn, doq_get_timestamp_nanosec());
 	return 1;
 }
 
@@ -5555,32 +5556,35 @@ doq_table_pop_first(struct doq_table* table)
 }
 
 int
-doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv)
+doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv, ngtcp2_tstamp* ts)
 {
-	ngtcp2_tstamp expiry = ngtcp2_conn_get_expiry(conn->conn);
-	ngtcp2_tstamp now = doq_get_timestamp_nanosec();
+	ngtcp2_tstamp doq_expiry = ngtcp2_conn_get_expiry(conn->conn);
+	ngtcp2_tstamp doq_now = doq_get_timestamp_nanosec();
 	ngtcp2_tstamp t;
+	struct timeval now = doq_get_timevalue();
 
-	if(expiry <= now) {
+	if(doq_expiry <= doq_now || doq_expiry == UINT64_MAX) {
+		/* UINT64_MAX means there is no next expiry. */
 		/* The timer has already expired, add with zero timeout.
 		 * This should call the callback straight away. Calling it
 		 * from the event callbacks is cleaner than calling it here,
 		 * because then it is always called with the same locks and
 		 * so on. This routine only has the conn.lock. */
-		t = now;
+		t = doq_now;
+		memcpy(tv, &now, sizeof(*tv));
 	} else {
-		t = expiry;
+		t = doq_expiry;
+		memset(tv, 0, sizeof(*tv));
+		tv->tv_sec = (doq_expiry - doq_now) / NGTCP2_SECONDS;
+		tv->tv_usec = ((doq_expiry - doq_now) / NGTCP2_MICROSECONDS)%1000000;
+		timeval_add(tv, &now);
 	}
 
-	/* convert to timeval */
-	memset(tv, 0, sizeof(*tv));
-	tv->tv_sec = t / NGTCP2_SECONDS;
-	tv->tv_usec = (t / NGTCP2_MICROSECONDS)%1000000;
+	*ts = t;
 
 	/* If we already have a timer, is it the right value? */
 	if(conn->timer.timer_in_tree || conn->timer.timer_in_list) {
-		if(conn->timer.time.tv_sec == tv->tv_sec &&
-			conn->timer.time.tv_usec == tv->tv_usec)
+		if(conn->timer.time_mono == *ts)
 			return 0;
 	}
 	return 1;
@@ -5601,13 +5605,12 @@ doq_conn_log_line(struct doq_conn* conn, char* s)
 int
 doq_conn_handle_timeout(struct doq_conn* conn)
 {
-	ngtcp2_tstamp now = doq_get_timestamp_nanosec();
 	int rv;
 
 	if(verbosity >= VERB_ALGO)
 		doq_conn_log_line(conn, "timeout");
 
-	rv = ngtcp2_conn_handle_expiry(conn->conn, now);
+	rv = ngtcp2_conn_handle_expiry(conn->conn, doq_get_timestamp_nanosec());
 	if(rv != 0) {
 		verbose(VERB_ALGO, "ngtcp2_conn_handle_expiry failed: %s",
 			ngtcp2_strerror(rv));
diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h
index 963595a1c..95aa3e11e 100644
--- a/services/listen_dnsport.h
+++ b/services/listen_dnsport.h
@@ -538,8 +538,11 @@ void doq_table_delete(struct doq_table* table);
 struct doq_timer {
 	/** The rbnode in the tree sorted by timeout value. Key this struct. */
 	struct rbnode_type node;
+	/** The timeout value. Monotonic value used with ngtcp2.
+	 *  This time value is used for the tree operations. */
+	ngtcp2_tstamp time_mono;
 	/** The timeout value. Absolute time value. */
-	struct timeval time;
+	struct timeval time_real;
 	/** If the timer is in the time tree, with the node. */
 	int timer_in_tree;
 	/** If there are more timers with the exact same timeout value,
@@ -813,10 +816,12 @@ struct doq_conn* doq_table_pop_first(struct doq_table* table);
  * doq check if the timer for the conn needs to be changed.
  * @param conn: connection, caller must hold lock on it.
  * @param tv: time value, absolute time, returned.
+ * @param ts: time stamp, absolute time, returned.
  * @return true if timer needs to be set to tv, false if no change is needed
  * 	to the timer. The timer is already set to the right time in that case.
  */
-int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv);
+int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv,
+	ngtcp2_tstamp* ts);
 
 /** doq remove timer from tree */
 void doq_timer_tree_remove(struct doq_table* table, struct doq_timer* timer);
@@ -829,11 +834,12 @@ void doq_timer_unset(struct doq_table* table, struct doq_timer* timer);
 
 /** doq set the timer and add it. */
 void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
-	struct doq_server_socket* worker_doq_socket, struct timeval* tv);
+	struct doq_server_socket* worker_doq_socket, struct timeval* tv,
+	ngtcp2_tstamp ts);
 
 /** doq find a timeout in the timer tree */
 struct doq_timer* doq_timer_find_time(struct doq_table* table,
-	struct timeval* tv);
+	ngtcp2_tstamp ts);
 
 /** doq handle timeout for a connection. Pass conn locked. Returns false for
  * deletion. */
@@ -851,6 +857,9 @@ int doq_table_quic_size_available(struct doq_table* table,
 
 /** doq get the quic size value */
 size_t doq_table_quic_size_get(struct doq_table* table);
+
+/** get a timestamp in nanoseconds */
+ngtcp2_tstamp doq_get_timestamp_nanosec(void);
 #endif /* HAVE_NGTCP2 */
 
 char* set_ip_dscp(int socket, int addrfamily, int ds);
@@ -866,8 +875,4 @@ void doq_client_event_cb(int fd, short event, void* arg);
 /** timer event callback for testcode/doqclient */
 void doq_client_timer_cb(int fd, short event, void* arg);
 
-#ifdef HAVE_NGTCP2
-/** get a timestamp in nanoseconds */
-ngtcp2_tstamp doq_get_timestamp_nanosec(void);
-#endif
 #endif /* LISTEN_DNSPORT_H */
diff --git a/util/netevent.c b/util/netevent.c
index a86e22518..e1480dc22 100644
--- a/util/netevent.c
+++ b/util/netevent.c
@@ -1827,7 +1827,6 @@ doq_send_retry(struct comm_point* c, struct doq_pkt_addr* paddr,
 	char host[256], port[32];
 	struct ngtcp2_cid scid;
 	uint8_t token[NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN];
-	ngtcp2_tstamp ts;
 	ngtcp2_ssize tokenlen, ret;
 
 	if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host,
@@ -1841,12 +1840,10 @@ doq_send_retry(struct comm_point* c, struct doq_pkt_addr* paddr,
 	scid.datalen = c->doq_socket->sv_scidlen;
 	doq_cid_randfill(&scid, scid.datalen, c->doq_socket->rnd);
 
-	ts = doq_get_timestamp_nanosec();
-
 	tokenlen = ngtcp2_crypto_generate_retry_token(token,
 		c->doq_socket->static_secret, c->doq_socket->static_secret_len,
 		hd->version, (void*)&paddr->addr, paddr->addrlen, &scid,
-		&hd->dcid, ts);
+		&hd->dcid, doq_get_timestamp_nanosec());
 	if(tokenlen < 0) {
 		log_err("ngtcp2_crypto_generate_retry_token failed: %s",
 			ngtcp2_strerror(tokenlen));
@@ -1895,13 +1892,11 @@ doq_verify_retry_token(struct comm_point* c, struct doq_pkt_addr* paddr,
 	struct ngtcp2_cid* ocid, struct ngtcp2_pkt_hd* hd)
 {
 	char host[256], port[32];
-	ngtcp2_tstamp ts;
 	if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host,
 		sizeof(host), port, sizeof(port))) {
 		log_err("doq_verify_retry_token failed");
 		return 0;
 	}
-	ts = doq_get_timestamp_nanosec();
 	verbose(VERB_ALGO, "doq: verifying retry token from %s %s", host,
 		port);
 	if(ngtcp2_crypto_verify_retry_token(ocid,
@@ -1913,7 +1908,7 @@ doq_verify_retry_token(struct comm_point* c, struct doq_pkt_addr* paddr,
 		c->doq_socket->static_secret,
 		c->doq_socket->static_secret_len, hd->version,
 		(void*)&paddr->addr, paddr->addrlen, &hd->dcid,
-		10*NGTCP2_SECONDS, ts) != 0) {
+		10*NGTCP2_SECONDS, doq_get_timestamp_nanosec()) != 0) {
 		verbose(VERB_ALGO, "doq: could not verify retry token "
 			"from %s %s", host, port);
 		return 0;
@@ -1928,13 +1923,11 @@ doq_verify_token(struct comm_point* c, struct doq_pkt_addr* paddr,
 	struct ngtcp2_pkt_hd* hd)
 {
 	char host[256], port[32];
-	ngtcp2_tstamp ts;
 	if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host,
 		sizeof(host), port, sizeof(port))) {
 		log_err("doq_verify_token failed");
 		return 0;
 	}
-	ts = doq_get_timestamp_nanosec();
 	verbose(VERB_ALGO, "doq: verifying token from %s %s", host, port);
 	if(ngtcp2_crypto_verify_regular_token(
 #ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN
@@ -1944,7 +1937,7 @@ doq_verify_token(struct comm_point* c, struct doq_pkt_addr* paddr,
 #endif
 		c->doq_socket->static_secret, c->doq_socket->static_secret_len,
 		(void*)&paddr->addr, paddr->addrlen, 3600*NGTCP2_SECONDS,
-		ts) != 0) {
+		doq_get_timestamp_nanosec()) != 0) {
 		verbose(VERB_ALGO, "doq: could not verify token from %s %s",
 			host, port);
 		return 0;
@@ -2171,6 +2164,7 @@ doq_pickup_timer(struct comm_point* c)
 {
 	struct doq_timer* t;
 	struct timeval tv;
+	ngtcp2_tstamp ts = 0;
 	int have_time = 0;
 	memset(&tv, 0, sizeof(tv));
 
@@ -2180,27 +2174,24 @@ doq_pickup_timer(struct comm_point* c)
 			t->worker_doq_socket == c->doq_socket) {
 			/* pick up this element */
 			t->worker_doq_socket = c->doq_socket;
+			memcpy(&tv, &t->time_real, sizeof(tv));
+			ts = t->time_mono;
 			have_time = 1;
-			memcpy(&tv, &t->time, sizeof(tv));
 			break;
 		}
 	}
 	lock_rw_unlock(&c->doq_socket->table->lock);
-
+	c->doq_socket->marked_time = ts;
 	if(have_time) {
 		struct timeval rel;
 		timeval_subtract(&rel, &tv, c->doq_socket->now_tv);
 		comm_timer_set(c->doq_socket->timer, &rel);
-		memcpy(&c->doq_socket->marked_time, &tv,
-			sizeof(c->doq_socket->marked_time));
 		verbose(VERB_ALGO, "doq pickup timer at %d.%6.6d in %d.%6.6d",
 			(int)tv.tv_sec, (int)tv.tv_usec, (int)rel.tv_sec,
 			(int)rel.tv_usec);
 	} else {
 		if(comm_timer_is_set(c->doq_socket->timer))
 			comm_timer_disable(c->doq_socket->timer);
-		memset(&c->doq_socket->marked_time, 0,
-			sizeof(c->doq_socket->marked_time));
 		verbose(VERB_ALGO, "doq timer disabled");
 	}
 }
@@ -2213,13 +2204,14 @@ doq_done_setup_timer_and_write(struct comm_point* c, struct doq_conn* conn)
 	uint8_t cid[NGTCP2_MAX_CIDLEN];
 	rbnode_type* node;
 	struct timeval new_tv;
+	ngtcp2_tstamp new_ts;
 	int write_change = 0, timer_change = 0;
 
 	/* No longer in callbacks, so the pointer to doq_socket is back
 	 * to NULL. */
 	conn->doq_socket = NULL;
 
-	if(doq_conn_check_timer(conn, &new_tv))
+	if(doq_conn_check_timer(conn, &new_tv, &new_ts))
 		timer_change = 1;
 	if( (conn->write_interest && !conn->on_write_list) ||
 		(!conn->write_interest && conn->on_write_list))
@@ -2265,7 +2257,7 @@ doq_done_setup_timer_and_write(struct comm_point* c, struct doq_conn* conn)
 	}
 	if(timer_change) {
 		doq_timer_set(c->doq_socket->table, &conn->timer,
-			c->doq_socket, &new_tv);
+			c->doq_socket, &new_tv, new_ts);
 	}
 	lock_rw_unlock(&c->doq_socket->table->lock);
 	lock_basic_unlock(&conn->lock);
@@ -2429,7 +2421,7 @@ doq_write_blocked_pkt(struct comm_point* c)
 	return 1;
 }
 
-/** doq find a timer that timeouted and return the conn, locked. */
+/** doq find a timer that timed out and return the conn, locked. */
 static struct doq_conn*
 doq_timer_timeout_conn(struct doq_server_socket* doq_socket)
 {
@@ -2442,7 +2434,7 @@ doq_timer_timeout_conn(struct doq_server_socket* doq_socket)
 		conn = t->conn;
 
 		/* If now < timer then no further timeouts in tree. */
-		if(timeval_smaller(doq_socket->now_tv, &t->time)) {
+		if(timeval_smaller(doq_socket->now_tv, &t->time_real)) {
 			lock_rw_unlock(&doq_socket->table->lock);
 			return NULL;
 		}
@@ -2465,11 +2457,11 @@ doq_timer_erase_marker(struct doq_server_socket* doq_socket)
 {
 	struct doq_timer* t;
 	lock_rw_wrlock(&doq_socket->table->lock);
-	t = doq_timer_find_time(doq_socket->table, &doq_socket->marked_time);
+	t = doq_timer_find_time(doq_socket->table, doq_socket->marked_time);
 	if(t && t->worker_doq_socket == doq_socket)
 		t->worker_doq_socket = NULL;
 	lock_rw_unlock(&doq_socket->table->lock);
-	memset(&doq_socket->marked_time, 0, sizeof(doq_socket->marked_time));
+	doq_socket->marked_time = 0;
 }
 
 void
@@ -2776,7 +2768,7 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd,
 		free(doq_socket);
 		return NULL;
 	}
-	memset(&doq_socket->marked_time, 0, sizeof(doq_socket->marked_time));
+	doq_socket->marked_time = 0;
 	comm_base_timept(base, &doq_socket->now_tt, &doq_socket->now_tv);
 	doq_socket->cfg = cfg;
 	return doq_socket;
diff --git a/util/netevent.h b/util/netevent.h
index c5114bbbe..7235843ee 100644
--- a/util/netevent.h
+++ b/util/netevent.h
@@ -1093,8 +1093,10 @@ struct doq_server_socket {
 	struct doq_pkt_addr* blocked_paddr;
 	/** timer for this worker on this comm_point to wait on. */
 	struct comm_timer* timer;
+#ifdef HAVE_NGTCP2
 	/** the timer that is marked by the doq_socket as waited on. */
-	struct timeval marked_time;
+	ngtcp2_tstamp marked_time;
+#endif
 	/** the current time for use by time functions, time_t. */
 	time_t* now_tt;
 	/** the current time for use by time functions, timeval. */
