diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc
index c9620e2bf..a3cd4ff0d 100644
--- a/src/libutil/serialise.cc
+++ b/src/libutil/serialise.cc
@@ -64,9 +64,9 @@ static void warnLargeDump()
 
 void FdSink::write(const unsigned char * data, size_t len)
 {
+    written += len;
     static bool warned = false;
     if (warn && !warned) {
-        written += len;
         if (written > threshold) {
             warnLargeDump();
             warned = true;
@@ -131,6 +131,7 @@ size_t FdSource::readUnbuffered(unsigned char * data, size_t len)
     } while (n == -1 && errno == EINTR);
     if (n == -1) { _good = false; throw SysError("reading from file"); }
     if (n == 0) { _good = false; throw EndOfFile("unexpected end-of-file"); }
+    read += n;
     return n;
 }
 
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index 9e269f392..0fdc4037b 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -76,11 +76,11 @@ struct BufferedSource : Source
 struct FdSink : BufferedSink
 {
     int fd;
-    bool warn;
-    size_t written;
+    bool warn = false;
+    size_t written = 0;
 
-    FdSink() : fd(-1), warn(false), written(0) { }
-    FdSink(int fd) : fd(fd), warn(false), written(0) { }
+    FdSink() : fd(-1) { }
+    FdSink(int fd) : fd(fd) { }
     ~FdSink();
 
     void write(const unsigned char * data, size_t len) override;
@@ -96,6 +96,8 @@ private:
 struct FdSource : BufferedSource
 {
     int fd;
+    size_t read = 0;
+
     FdSource() : fd(-1) { }
     FdSource(int fd) : fd(fd) { }
     size_t readUnbuffered(unsigned char * data, size_t len) override;