If you run your own IMAP server or if you use Thunderbird, you may have run into the problem where there are just too many emails in your folder and you need to delete them.

It seems that at a certain threshold of emails, trying to delete your email through any normal IMAP client is just impossible. I first had this happen when I was mail bombed with about 3000 emails. For some reason, Thunderbird just couldn’t handle deleting them. I would select all the messages in my inbox and hit delete. Then it would sit there for hours just spinning.

My first thought was that this was a server problem. To troubleshoot it, I created a groovy script to run through my inbox and delete the messages. It worked and actually finished it in 5 minutes! So it appears there is definitely a problem with Thunderbird and other clients.

Just a few days ago I had the same problem again. Only this was on a much larger scale. Due to a configuration problem in my postfix mail server, I had over 190,000 emails sent to my inbox in a matter of 36 hours. Yikes!

I ran the script and it took about 12 hours in total to finish it. Without it, I would just have had to delete the entire account and loose all of my email. And manually going through and deleting all that email would be impossible for all practical purposes.

The script was more than just a straight forward connect and delete. Committing the changes on 10,000 emails usually kills your IMAP server. To get around this, it processes a few then disconnects and reconnects. This is slower, but works.

import javax.mail.*;
import javax.mail.internet.*;

// Configuration below...

type = "imap" // (or pop3)
host = "domain.com"
user = "username"
pass = "password"
deleteOn = "Undelivered Mail Returned to Sender" // This is the subject line to search for.  Any messages matching will be deleted.
testRun = true;  // if this is true, it will only make 5 passes and then exit.
passes = 5;	// Number of passes to make before closing the connection and committing changes

// End configuration...

moreAvailable = true;
progStart = System.currentTimeMillis();

while(moreAvailable) {

// -- Get hold of the default session --
Properties props = System.getProperties();
Session session = Session.getDefaultInstance(props, null);

// -- Get hold of a POP3 message store, and connect to it --
Store store = session.getStore(type);
store.connect(host, user, pass);

// -- Try to get hold of the default folder --
Folder folder = store.getDefaultFolder();
if(folder == null)
	throw new Exception("No default folder");

// -- ...and its INBOX --
folder = folder.getFolder("INBOX");
if(folder == null)
	throw new Exception("No " + type + " INBOX");

// -- Open the folder for read only --
folder.open(Folder.READ_WRITE);

// -- Get the message wrappers and process them --
int total = folder.getMessageCount();

if(total < 700) {
	moreAvailable = false;
}

println "Total messages: " + total;
long start = System.currentTimeMillis();
long lastTime = System.currentTimeMillis();
int testCount = 0;
int page = 100;
for(i in 0..(total/page)) {
	println(" Elapsed Time: " + (System.currentTimeMillis() - start) + " MS");
	println("Deleting messages[" + (total - (page * (i + 1))) + ", " + (total - (page * i)) + "]");
	messages = folder.getMessages(total - (page * (i + 1)), total - (page * i));
	for(m in messages) {
		if(m.getSubject().equals(deleteOn)) {
			print "."
			m.setFlag(Flags.Flag.DELETED, true);
		}
	}
	println ""

	testCount++;
	if(testRun && testCount > 5) {
		break;
	}
	print "Deletion took: " + (System.currentTimeMillis() - lastTime) + " MS";
	lastTime = System.currentTimeMillis();

}
println "Committing changes...";

folder.expunge();
folder.close(true);
store.close();

println("Pass took: " + (System.currentTimeMillis() - start) + " MS");

}

println("Total time to cleanup: " + (System.currentTimeMillis() - progStart) + " MS");

About the Author:

Learned something? Great! Need help on your development project? I'm available for hire:

  • Ruby on Rails
  • iOS Development
  • System Architecture & Performance

Get in touch:

Discussion

No comments yet, be the first.

Leave a Comment