Visualizing my journey to Inbox Zero

2020-03-31 2 min read
    Number of emails in my inbox by account

    I subscribe to the “Inbox Zero” philosophy and treat my email inbox as a todo list that I slowly work through. As part of the desire to get more and more quantitative I wrote a quick script to pull the number of emails from my Inbox and then insert the data as a row into a new table in my personal stats database. As usual, most of the work was in deciding to do it and once I got to coding the hacky solution was done within 20 minutes. The script uses Python’s built-in imaplib library to log in to an email provider and then a simple MySQL query to insert the resulting data. I hooked this up to run every 15 minutes via cron and put together a Grafana dashboard to plot the count over time. I’m currently not actually going through the content of the email messages themselves but there are tons of directions I can take this - for example slicing the data by sender or examining the age of the messages. For now I’m just hopeful this motivates me to keep going through that email.

    #! /usr/bin/python3
    import imaplib
    import mysql.connector
    # TODO: Handle credentials better (environment, config, etc)
    IMAP_INFO = {
        'work': {
            'imap_host': '',
            'imap_port': 993,
            'imap_user': '',
            'imap_pass': '',
        'personal': {
            'imap_host': '',
            'imap_port': 993,
            'imap_user': '',
            'imap_pass': '',
    db_host = ''
    db_user = ''
    db_pass = ''
    db_database = ''
    def get_num_emails(creds):
        imap = imaplib.IMAP4_SSL(creds['imap_host'], creds['imap_port'])
        imap.login(creds['imap_user'], creds['imap_pass'])'Inbox')
        tmp, data =, 'ALL')
        return len(data[0].split())
    def save_stats(account_name, num_emails):
        mydb = mysql.connector.connect(
            host = db_host,
            user = db_user,
            passwd = db_pass,
            database = db_database,
        mycursor = mydb.cursor()
        sql = "INSERT INTO email_stats (account_name, num_emails) VALUES (%s, %s)"
        val = (account_name, num_emails)
        mycursor.execute(sql, val)
        print(mycursor.rowcount, "record inserted.")
    for account_name, creds in IMAP_INFO.items():
        num_emails = get_num_emails(creds)
        print('Fetched', num_emails, 'in', account_name)
        save_stats(account_name, num_emails)