diff --git a/configure.ac b/configure.ac
index fcc7cdd095f183ed8be21e2af66e58693f5671a0..f23813766336c3b8c0740f4331abfc7afb02b9ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ AC_CHECK_HEADERS(
   [limits.h sys/time.h sys/types.h sys/stat.h dirent.h unistd.h fnmatch.h ncurses.h],[],
   AC_MSG_ERROR([required header file not found]))
 
-AC_CHECK_HEADERS(locale.h)
+AC_CHECK_HEADERS([locale.h sys/statfs.h linux/magic.h])
 
 # Check for typedefs, structures, and compiler characteristics.
 AC_TYPE_INT64_T
@@ -28,6 +28,7 @@ AC_CHECK_FUNCS(
   [getcwd gettimeofday fnmatch chdir rmdir unlink lstat system getenv],[],
   AC_MSG_ERROR([required function missing]))
 
+AC_CHECK_FUNCS(statfs)
 
 
 # Look for ncurses library to link to
diff --git a/doc/ncdu.pod b/doc/ncdu.pod
index 784500f3a20d5dd39a950e96ce3e76b537b1ace4..ad6783b1e4e3ed7bd1bc8f259721b811a31df0d0 100644
--- a/doc/ncdu.pod
+++ b/doc/ncdu.pod
@@ -179,6 +179,15 @@ this option will not follow symlinks to directories and will count each
 symlinked file as a unique file (i.e. unlike how hard links are handled). This
 is subject to change in later versions.
 
+=item --exclude-kernfs
+
+Exclude Linux pseudo filesystems, e.g. /proc (procfs), /sys (sysfs).
+This option is only available on Linux, but exported statistics can be loaded on
+all platforms.
+
+The complete list of currently known pseudo filesystems is: binfmt, bpf, cgroup,
+cgroup2, debug, devpts, proc, pstore, security, selinux, sys, trace.
+
 =back
 
 
@@ -307,6 +316,10 @@ File or directory is excluded from the statistics by using exlude patterns.
 
 Directory is on another filesystem.
 
+=item ^
+
+Directory is excluded from the statistics due to being a Linux pseudo filesystem.
+
 =item @
 
 This is neither a file nor a folder (symlink, socket, ...).
diff --git a/src/browser.c b/src/browser.c
index 61c38a454071a6dfe578660d69fd17b0c3403251..3a9971f1b1ac71098a7820862c733636decb941a 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -118,6 +118,7 @@ static void browse_draw_flag(struct dir *n, int *x) {
         n->flags & FF_ERR ? '!' :
        n->flags & FF_SERR ? '.' :
       n->flags & FF_OTHFS ? '>' :
+     n->flags & FF_KERNFS ? '^' :
       n->flags & FF_HLNKC ? 'H' :
      !(n->flags & FF_FILE
     || n->flags & FF_DIR) ? '@' :
diff --git a/src/dir.h b/src/dir.h
index 8c145f1265654e4de00ebcc1c9feb66d3e5063f6..ec927337c8c8bf38e5b277ca948e00e7434c1f3a 100644
--- a/src/dir.h
+++ b/src/dir.h
@@ -113,6 +113,10 @@ void dir_scan_init(const char *path);
 extern int dir_import_active;
 int dir_import_init(const char *fn);
 
+#if HAVE_LINUX_MAGIC_H && HAVE_SYS_STATFS_H && HAVE_STATFS
+extern int exclude_kernfs;
+#endif
+
 
 /* The currently configured output functions. */
 extern struct dir_output dir_output;
diff --git a/src/dir_export.c b/src/dir_export.c
index 6a7fe8dde8a4d531b9624dd0c59a7d043db0415d..f60242121a30c7ff9be98ef321a55f695e114928 100644
--- a/src/dir_export.c
+++ b/src/dir_export.c
@@ -116,12 +116,14 @@ static void output_info(struct dir *d, const char *name, struct dir_ext *e) {
   if(d->flags & FF_ERR)
     fputs(",\"read_error\":true", stream);
   /* excluded/error'd files are "unknown" with respect to the "notreg" field. */
-  if(!(d->flags & (FF_DIR|FF_FILE|FF_ERR|FF_EXL|FF_OTHFS)))
+  if(!(d->flags & (FF_DIR|FF_FILE|FF_ERR|FF_EXL|FF_OTHFS|FF_KERNFS)))
     fputs(",\"notreg\":true", stream);
   if(d->flags & FF_EXL)
     fputs(",\"excluded\":\"pattern\"", stream);
   else if(d->flags & FF_OTHFS)
     fputs(",\"excluded\":\"othfs\"", stream);
+  else if(d->flags & FF_KERNFS)
+    fputs(",\"excluded\":\"kernfs\"", stream);
 
   fputc('}', stream);
 }
diff --git a/src/dir_import.c b/src/dir_import.c
index 3a5c2a35bcb1dbdbb2975692f3ef6652edee6457..b3aeb7bcf1d08606bfe9ed3ee00382f1b639555e 100644
--- a/src/dir_import.c
+++ b/src/dir_import.c
@@ -480,6 +480,8 @@ static int iteminfo(void) {
       C(rstring(ctx->val, 8));
       if(strcmp(ctx->val, "otherfs") == 0)
         ctx->buf_dir->flags |= FF_OTHFS;
+      else if(strcmp(ctx->val, "kernfs") == 0)
+        ctx->buf_dir->flags |= FF_KERNFS;
       else
         ctx->buf_dir->flags |= FF_EXL;
     } else if(strcmp(ctx->val, "notreg") == 0) {     /* notreg */
diff --git a/src/dir_scan.c b/src/dir_scan.c
index 8706e9c1aab394ac981d3ec8d6f5641172741aa1..879e13de2833769db9a6777ddb05a0e1ff24abb3 100644
--- a/src/dir_scan.c
+++ b/src/dir_scan.c
@@ -34,6 +34,11 @@
 #include <sys/stat.h>
 #include <dirent.h>
 
+#if HAVE_LINUX_MAGIC_H && HAVE_SYS_STATFS_H && HAVE_STATFS
+#include <sys/statfs.h>
+#include <linux/magic.h>
+#endif
+
 
 /* set S_BLKSIZE if not defined already in sys/stat.h */
 #ifndef S_BLKSIZE
@@ -50,6 +55,27 @@ static struct dir    *buf_dir;
 static struct dir_ext buf_ext[1];
 
 
+#if HAVE_LINUX_MAGIC_H && HAVE_SYS_STATFS_H && HAVE_STATFS
+int exclude_kernfs; /* Exlude Linux pseudo filesystems */
+
+static int is_kernfs(unsigned long type) {
+  if(type == BINFMTFS_MAGIC ||
+     type == BPF_FS_MAGIC ||
+     type == CGROUP_SUPER_MAGIC ||
+     type == CGROUP2_SUPER_MAGIC||
+     type == DEBUGFS_MAGIC ||
+     type == DEVPTS_SUPER_MAGIC ||
+     type == PROC_SUPER_MAGIC ||
+     type == PSTOREFS_MAGIC ||
+     type == SECURITYFS_MAGIC ||
+     type == SELINUX_MAGIC ||
+     type == SYSFS_MAGIC ||
+     type == TRACEFS_MAGIC)
+    return 1;
+
+  return 0;
+}
+#endif
 
 /* Populates the buf_dir and buf_ext with information from the stat struct.
  * Sets everything necessary for output_dir.item() except FF_ERR and FF_EXL. */
@@ -69,7 +95,7 @@ static void stat_to_dir(struct stat *fs) {
   if(dir_scan_smfs && curdev != buf_dir->dev)
     buf_dir->flags |= FF_OTHFS;
 
-  if(!(buf_dir->flags & (FF_OTHFS|FF_EXL))) {
+  if(!(buf_dir->flags & (FF_OTHFS|FF_EXL|FF_KERNFS))) {
     buf_dir->size = fs->st_blocks * S_BLKSIZE;
     buf_dir->asize = fs->st_size;
   }
@@ -204,6 +230,17 @@ static int dir_scan_item(const char *name) {
     dir_setlasterr(dir_curpath);
   }
 
+#if HAVE_LINUX_MAGIC_H && HAVE_SYS_STATFS_H && HAVE_STATFS
+  if(exclude_kernfs && !(buf_dir->flags & (FF_ERR|FF_EXL)) && S_ISDIR(st.st_mode)) {
+    struct statfs fst;
+    if(statfs(dir_curpath, &fst)) {
+      buf_dir->flags |= FF_ERR;
+      dir_setlasterr(dir_curpath);
+    } else if(is_kernfs(fst.f_type))
+      buf_dir->flags |= FF_KERNFS;
+  }
+#endif
+
   if(!(buf_dir->flags & (FF_ERR|FF_EXL))) {
     if(follow_symlinks && S_ISLNK(st.st_mode) && !stat(name, &stl) && !S_ISDIR(stl.st_mode))
       stat_to_dir(&stl);
@@ -211,14 +248,14 @@ static int dir_scan_item(const char *name) {
       stat_to_dir(&st);
   }
 
-  if(cachedir_tags && (buf_dir->flags & FF_DIR) && !(buf_dir->flags & (FF_ERR|FF_EXL|FF_OTHFS)))
+  if(cachedir_tags && (buf_dir->flags & FF_DIR) && !(buf_dir->flags & (FF_ERR|FF_EXL|FF_OTHFS|FF_KERNFS)))
     if(has_cachedir_tag(name)) {
       buf_dir->flags |= FF_EXL;
       buf_dir->size = buf_dir->asize = 0;
     }
 
   /* Recurse into the dir or output the item */
-  if(buf_dir->flags & FF_DIR && !(buf_dir->flags & (FF_ERR|FF_EXL|FF_OTHFS)))
+  if(buf_dir->flags & FF_DIR && !(buf_dir->flags & (FF_ERR|FF_EXL|FF_OTHFS|FF_KERNFS)))
     fail = dir_scan_recurse(name);
   else if(buf_dir->flags & FF_DIR) {
     if(dir_output.item(buf_dir, name, buf_ext) || dir_output.item(NULL, 0, NULL)) {
diff --git a/src/global.h b/src/global.h
index f9b59cb716b63da58f60db666359646f25ae60d6..fb0405a6d44ff62bc835fc9a3ca8bcb5ddbb9fd6 100644
--- a/src/global.h
+++ b/src/global.h
@@ -42,15 +42,16 @@
 #endif
 
 /* File Flags (struct dir -> flags) */
-#define FF_DIR    0x01
-#define FF_FILE   0x02
-#define FF_ERR    0x04 /* error while reading this item */
-#define FF_OTHFS  0x08 /* excluded because it was another filesystem */
-#define FF_EXL    0x10 /* excluded using exlude patterns */
-#define FF_SERR   0x20 /* error in subdirectory */
-#define FF_HLNKC  0x40 /* hard link candidate (file with st_nlink > 1) */
-#define FF_BSEL   0x80 /* selected */
-#define FF_EXT   0x100 /* extended struct available */
+#define FF_DIR     0x01
+#define FF_FILE    0x02
+#define FF_ERR     0x04 /* error while reading this item */
+#define FF_OTHFS   0x08 /* excluded because it was another filesystem */
+#define FF_EXL     0x10 /* excluded using exlude patterns */
+#define FF_SERR    0x20 /* error in subdirectory */
+#define FF_HLNKC   0x40 /* hard link candidate (file with st_nlink > 1) */
+#define FF_BSEL    0x80 /* selected */
+#define FF_EXT    0x100 /* extended struct available */
+#define FF_KERNFS 0x200 /* excluded because it was a Linux pseudo filesystem */
 
 /* Program states */
 #define ST_CALC   0
diff --git a/src/main.c b/src/main.c
index 0651a6ec08fb6d3e13142bc81b5bc534c63a328b..cc7d43b46e935170f964a37e012dd04e94f3fda0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -137,6 +137,7 @@ static void argv_parse(int argc, char **argv) {
     { 'X', 1, "-X,--exclude-from" },
     { 'L', 0, "-L,--follow-symlinks" },
     { 'C', 0, "--exclude-caches" },
+    {  2,  0, "--exclude-kernfs" },
     { 's', 0, "--si" },
     { 'Q', 0, "--confirm-quit" },
     { 'c', 1, "--color" },
@@ -166,6 +167,9 @@ static void argv_parse(int argc, char **argv) {
       printf("  -X, --exclude-from FILE    Exclude files that match any pattern in FILE\n");
       printf("  -L, --follow-symlinks      Follow symbolic links (excluding directories)\n");
       printf("  --exclude-caches           Exclude directories containing CACHEDIR.TAG\n");
+#if HAVE_LINUX_MAGIC_H && HAVE_SYS_STATFS_H && HAVE_STATFS
+      printf("  --exclude-kernfs           Exclude Linux pseudo filesystems (procfs,sysfs,cgroup,...)\n");
+#endif
       printf("  --confirm-quit             Confirm quitting ncdu\n");
       printf("  --color SCHEME             Set color scheme (off/dark)\n");
       exit(0);
@@ -194,6 +198,14 @@ static void argv_parse(int argc, char **argv) {
     case 'C':
       cachedir_tags = 1;
       break;
+
+    case  2 :
+#if HAVE_LINUX_MAGIC_H && HAVE_SYS_STATFS_H && HAVE_STATFS
+      exclude_kernfs = 1; break;
+#else
+      fprintf(stderr, "This feature is not supported on your platform\n");
+      exit(1);
+#endif
     case 'c':
       if(strcmp(val, "off") == 0)  { uic_theme = 0; }
       else if(strcmp(val, "dark") == 0) { uic_theme = 1; }