diff --git a/src/dir_scan.c b/src/dir_scan.c
index f3688c64d90b9c25ad371506361a9ecf26840113..57f96b3d46a3757b663b3f9ffa61b0d8a028c1e2 100644
--- a/src/dir_scan.c
+++ b/src/dir_scan.c
@@ -196,6 +196,10 @@ static int dir_scan_item(struct dir *d) {
   if(!(d->flags & (FF_ERR|FF_EXL)))
     stat_to_dir(d, &st);
 
+  if(cachedir_tags && (d->flags & FF_DIR) && !(d->flags & (FF_ERR|FF_EXL|FF_OTHFS)))
+    if(has_cachedir_tag(d->name))
+      d->flags |= FF_EXL;
+
   /* Recurse into the dir or output the item */
   if(d->flags & FF_DIR && !(d->flags & (FF_ERR|FF_EXL|FF_OTHFS)))
     fail = dir_scan_recurse(d);
diff --git a/src/exclude.c b/src/exclude.c
index ecf40a82567521a34804ee2a1b0ca41f410879ce..d7b679d81040af335cdfe6163b043866d15f822e 100644
--- a/src/exclude.c
+++ b/src/exclude.c
@@ -99,3 +99,26 @@ void exclude_clear() {
   excludes = NULL;
 }
 
+
+/* 
+ * Exclusion of directories that contain only cached information.
+ * See http://www.brynosaurus.com/cachedir/
+ */
+static const char cachedir_tag_signature[] =
+    "Signature: 8a477f597d28d172789f06886806bc55";
+
+int has_cachedir_tag(const char *name) {
+    char buf[1024];
+    FILE *f;
+    int match = 0;
+    const int signature_l = strlen(cachedir_tag_signature);
+
+    snprintf(buf, sizeof(buf), "%s/CACHEDIR.TAG", name);
+    f = fopen(buf, "rb");
+    if (f != NULL) {
+        match = ((fread(buf, 1, signature_l, f) == signature_l) &&
+                    !strncmp(buf, cachedir_tag_signature, signature_l));
+        fclose(f);
+    }
+    return match;
+}
diff --git a/src/global.h b/src/global.h
index d6eb2cb4a41ab45ca07cee5939973c63cc98de98..4bf0d55adda9ca8f6a8714231dd09abb9465b4d7 100644
--- a/src/global.h
+++ b/src/global.h
@@ -86,6 +86,8 @@ extern int pstate;
 extern int read_only;
 /* minimum screen update interval when calculating, in ms */
 extern long update_delay;
+/* filter directories with CACHEDIR.TAG */
+extern int cachedir_tags;
 
 /* handle input from keyboard and update display */
 int input_handle(int);
diff --git a/src/main.c b/src/main.c
index 109f2a119b23585da1cff9997cff0c18a24581a8..54771b223fd212af9732b5b4a0dbb30be0cf8fb5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -40,6 +40,7 @@
 int pstate;
 int read_only = 0;
 long update_delay = 100;
+int cachedir_tags = 0;
 
 static int min_rows = 17, min_cols = 60;
 static int ncurses_init = 0;
@@ -125,6 +126,7 @@ static void argv_parse(int argc, char **argv) {
     { '2', 0, "-2" },
     {  1,  1, "--exclude" },
     { 'X', 1, "-X,--exclude-from" },
+    { 'C', 0, "-C,--cachedir-tag" },
     {0,0,NULL}
   };
 
@@ -146,6 +148,7 @@ static void argv_parse(int argc, char **argv) {
       printf("  -0,-1,-2                   UI to use when scanning (0=none,2=full ncurses)\n");
       printf("  --exclude PATTERN          Exclude files that match PATTERN\n");
       printf("  -X, --exclude-from FILE    Exclude files that match any pattern in FILE\n");
+      printf("  -C, --cachedir-tag         Exclude directories containing CACHEDIR.TAG\n");
       exit(0);
     case 'q': update_delay = 2000; break;
     case 'v':
@@ -165,6 +168,9 @@ static void argv_parse(int argc, char **argv) {
         exit(1);
       }
       break;
+    case 'C':
+      cachedir_tags = 1;
+      break;
     case -2:
       printf("ncdu: %s.\n", val);
       exit(1);