I got into a little debate with someone yesterday regarding the logic and/or veracity of my answer here, vis., that logging and maintaining fs meta-data on a decent (GB+) sized SD card could never be significant enough to wear the card out in a reasonable amount of time (years and years).  The jist of the counter-argument seemed to be that I must be wrong since there are so many stories online of people wearing out SD cards.Since I do have devices with SD cards in them containing rw root filesystems that are left on 24/7,  I had tested the premise before to my own satisfaction.  I've tweaked this test a bit, repeated it (using the same card, in fact) and am presenting it here.  The two central questions I have are:Is the method I used to attempt to wreck the card viable, keeping in mind it's intended to reproduce the effects of continuously re-writing small amounts of data?Is the method I used to verify the card was still okay viable? I'm putting the question here rather than S.O. or SuperUser because an objection to the first part would probably have to assert that my test didn't really write to the card the way I'm sure it does, and asserting that would require some special knowledge of linux.  [It could also be that SD cards use some kind of smart buffering or cache, such that repeated writes to the same place would be buffered/cached somewhere less prone to wear. I haven't found any indication of this anywhere, but I am asking about that on S.U.]The idea behind the test is to write to the same small block on the card millions of times.  This is well beyond any claim of how many write cycles such devices can sustain, but presuming wear leveling is effective, if the card is of a decent size, millions of such writes still shouldn't matter much, as the same block would not literally be the same physical block.  To do this, I needed to make sure every write was truly flushed to the hardware, and to the same apparent place.For flushing to hardware, I relied on the POSIX library call fdatasync():#include <stdio.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>// Compile std=gnu99#define BLOCK 1 << 16int main (void) {    int in = open (/dev/urandom, O_RDONLY);    if (in < 0) {        fprintf(stderr,open in %s, strerror(errno));        exit(0);    }    int out = open(/dev/sdb1, O_WRONLY);    if (out < 0) {        fprintf(stderr,open out %s, strerror(errno));        exit(0);    }    fprintf(stderr,BEGIN\n);    char buffer[BLOCK];    unsigned int count = 0;    int thousands = 0;    for (unsigned int i = 1; i !=0; i++) {        ssize_t r = read(in, buffer, BLOCK);        ssize_t w = write(out, buffer, BLOCK);        if (r != w) {            fprintf(stderr, r %d w %d\n, r, w);            if (errno) {                fprintf(stderr,%s\n, strerror(errno));                break;            }        }        if (fdatasync(out) != 0) {            fprintf(stderr,Sync failed: %s\n, strerror(errno));            break;        }        count++;        if (!(count % 1000)) {            thousands++;            fprintf(stderr,%d000...\n, thousands);        }        lseek(out, 0, SEEK_SET);    }    fprintf(stderr,TOTAL %lu\n, count);    close(in);    close(out);    return 0;}                                 I ran this for ~8 hours, until I had accumulated 2 million+ writes to the beginning of the /dev/sdb1 partition.1  I could just have easily used /dev/sdb (the raw device and not the partition) but I cannot see what difference this would make.I then checked the card by trying to create and mount a filesystem on /dev/sdb1.  This worked, indicating the specific block I had been writing to all night was feasible.  However, it does not mean that some regions of the card had not been worn out and displaced by wear levelling, but left accessible.To test that, I used badblocks -v -w on the partition.  This is a destructive read-write test, but wear levelling or not, it should be a strong indication of the feasibility of the card since it must still provide space for each rolling write.  In other words, it is the literal equivalent of filling the card completely, then checking that all of that was okay.  Several times, since I let badblocks work through a few patterns.[Contra Jason C's comments below, there is nothing wrong or false about using badblocks this way.  While it would not be useful for actually identifying bad blocks due to the nature of SD cards, it is fine for doing destructive read-write tests of an arbitrary size using the -b and -c switches, which is where the revised test went (see my own answer).  No amount of magic or caching by the card's controller can fool a test whereby several megabytes of data can be written to hardware and read back again correctly. Jason's other comments seem based on a misreading -- IMO an intentional one, which is why I have not bothered to argue. With that head's up, I leave it to the reader to decide what makes sense and what does not.] 1 The card was an old 4 GB Sandisk card (it has no class number on it) which I've barely used.  Once again, keep in mind that this is not 2 million writes to literally the same physical place; due to wear leveling the first block will have been moved constantly by the controller during the test to, as the term states, level out the wear.
Stress testing SD cards using linux
linux;hardware;sd card
Peterph's answer did make me consider the issue of possible caching further.  After digging around, I still can't say for sure whether any, some, or all SD cards do this, but I do think it is possible.However, I don't believe that the caching would involve data larger than the erase block.  To be really sure, I repeated the test using a 16 MB chunk instead of 64 kB.  This is 1/250th the total volume of the 4 GB card.  It took ~8 hours to do this 10,000 times.  If wear leveling does its best to spread the load around, this means every physical block would have been used 40 times.That's not much, but the original point of the test was to demonstrate the efficacy of wear leveling by showing that I could not easily damage the card through repeated writes of modest amounts of data to the same (apparent) location.  IMO the previous 64 kB test was probably real -- but the 16 MB one must be.  The system has flushed the data to the hardware and the hardware has reported the write without an error. If this were a deception, the card would not be good for anything, and it can't be caching 16 MB anywhere but in primary storage, which is what the test is intended to stress.Hopefully, 10,000 writes of 16 MB each is enough to demonstrate that even on a bottom end name brand card (value: $5 CDN), running a rw root filesystem 24/7 that writes modest amounts of data daily will not wear the card out in a reasonable period of time.   10,000 days is 27 years...and the card is still fine...If I were getting paid to develop systems that did heavier work than that, I would want to do at least a few tests to determine how long a card can last.  My hunch is that with one like this, which has a low write speed, it could take  weeks, months, or years of continuous writing at the max speed (the fact there aren't oodles of comparative tests of this sort online speaks to the fact that it would be a very prolonged affair).With regard to confirming the card is still okay, I no longer think using badblocks in it's default configuration is appropriate.  Instead, I did it this way:badblocks -v -w -b 524288 -c 8Which means to test using a 512 kB block repeated 8 times (= 4 MB).  Since this is a destructive rw test, it would probably be good as my homespun one with regard to stressing the device if used in a continuous loop.I've also created a filesystem on it, copied in a 2 GB file, diff'd the file against the original and then -- since the file was an .iso -- mounted it as an image and browsed the filesystem inside that.The card is still fine.  Which is probably to be expected, after all... ;) ;)