Make your inbox responsive with Astrid and the 4Ds of time management

A responsive inbox is almost always empty within a few minutes of checking it. It fosters rapid response times. Think of how frustrating it is to wait for days for a response, or to never get one at all!

Conflicting Purposes: Notification and Time Management

For at least 10 years now the inbox has been a constant factor in our lives. This drives many of us to use it for conflicting purposes, a noification queue and a todo list. Here are some of the symptoms:

  • Using "Mark Unread" to indicate high priority todos, "Mark Read" for low priority.
  • Sorting by date (to see new emails) leading to old "high priority" emails getting shuffled to the bottom of an ever growing list.
  • Constantly rescanning the inbox for things to do.
  • Never having an empty inbox.

Visibility and Trust in Astrid

Separating notifications from todos has significant advantages. The problem is trust and visibility in a task management system, putting it in front of my face almost as often as I check my email and maybe eventually moreso. Astrid hepls put a time management system in front of my face every day. It has a fantastic mobile interface on Android and iOS. The web interface is sufficient, though I hope they can speed it up. I pin it in Chrome, right next to my inbox. Astrid provides the visibility I need to separate notifications from time management.

Separating Concerns: Inbox as Notification Queue, Astrid for Time Management

The simplest way to achieve this separation is to treat our inbox as a notification queue. When we work on it we are actively handling notifications and scheduling tasks into something like Astrid. Processing notifications is really just a recurring task that could be scheduled too. Scott Hanselman recommends this to avoid your inbox becoming a distraction like facebook. Once the inbox is empty go back to Astrid for the next item of work.


Several blogs and videos advocate handling email, and other notifications, using the system of 4Ds: Drop it, Do it now, Do it later or Delegate it. This is a great foundation to get through your inbox quickly!

My techniques for my inbox

  • Automatic filtering to lower priority notification queues
    • If ads are important to me (ie: finding coupons or sales), why not schedule time for that? A recurring task on the weekend is a great way to handle this. If nothing else I can empty my ads folder at that time.
    • With appropriate filtering of your inbox, you can efficiently create separate notification queues with any level of priority.
    • These are automatic "Do it later"
  • Drop It
    • If the email requires no action, I delete it.
    • If necessary, I'll notify the sender of my inaction.
    • Most of the time this is junk mail or ads. I try to immediately unsubscribe or change filtering rules to move these to an "ads" folder.
  • Do It Now
    • If I need to act on an email, I'll decide when. If I can act in under a few minutes, I will. I'll waste at least that much time managing it in Astrid over the coming weeks, so it's often worth the time to do it now.
  • Delegate It Now
    • If it's something I need to delegate to someone else, and I can do that quickly, I will immediately.
    • I'll add a task in Astrid to follow up if it's something I am responsible to see to completion.
    • Usually I'll CC the original sender, especially if I'm not following up.
  • Do It Later
    • If I need more time I'll add a task in Astrid with a date when I need to come back to it.
    • Usually I'll notify the sender of the date, giving them a chance to raise timeliness concerns I may be unaware of.
    • Then I'll forget about it!
  • Delegate It Later
    • Some tasks may take time to figure out who to delegate them to, in this case I'll schedule the Delegation task as a "Do It Later".
  • Other Recurring Tasks
    • Consider scheduling time each day to check your inbox, schedule the frequency to match the level of responsiveness you want to provide. Otherwise, ignore your inbox.
    • Weekly task to unsubscribe from newsletters or ads that frequently get deleted. I prefer to get recurring news via RSS feeds. If you don't find yourself reading your RSS feeds often enough, you can always schedule a weekly task to remind yourself until it becomes second nature.
    • Consider a task per low priority notification queue you created with automatic filtering, like for processing ads.
    • Monthly task to review how I could be using my inbox more effectively.

A few Astrid notes

  • Read http://blog.astrid.com/how-to-keep-your-inbox-empty-with-astrid/, especially the email forwarding, you'll want to use that for efficiency
  • Read http://blog.astrid.com/get-a-clean-inbox-in-30-minutes/
  • Subscribe to http://blog.astrid.com/feed/ or the topic specific feeds
  • If you use gmail read http://blog.astrid.com/getting-started-on-astrids-remind-me-extension/ especially see the section on the "Remind Me" button!
  • Sign up for a premium account, the batch editing is worth it to move groups of tasks quickly.
  • Put the 4 item (or larger) widget on your mobile device on your home screen so it stares at you every time you open your phone. This is part of making Astrid visible
  • Try out the sharing feature, it's great for delegating work. This is especially great for family.
  • The "Today" view helps you stay focused.
  • Don't attach time to tasks, use a separate reminder system if you are worried about a deadline. The best way to schedule work is to pick the day it needs to happen on, then mark it higher priority if it should happen first. It's inefficient to schedule everything by time, it never works in reality.
  • Turn off mobile notifications, they just clutter your notification bar, get used to the widget and the "Today" view and checking this every day. If necessary, create a calendar alert to check Astrid until it becomes second nature.
  • The web interface is a bit slow, especially with searching, so just be aware.


Stop using your inbox as a todo list. Clean it out every time you check it. Use the 4Ds to schedule a task for anything you can't handle quickly. Get used to using a time management system. This will keep your inbox responsive!


This is cool: SmartGit 4 Interactive Rebase


Let's talk objectives first, not implementation

A simple request

A few weeks ago, there was a request in our planning system: "On the customer edit form, change the button that links to payments to green if the customer has payments."

The first thing that came to mind was why? As far as I know the customer edit page is very rarely used, and it's not a hot bed of activity to get to other systems like payments. Naturally, I saw no value in the request.

The next day, I stumbled to put this nicely by talking about the cost and perhaps we could prioritize it for much later on. Honestly, I need to get better at just asking one word: "why?"

Anyways, my customer agreed to de-prioritize it, at which point I felt a mutual understanding so I asked why it was needed, my customer helped fill in the value. When deleting a customer, he wanted to know if they had any payments so he could consider the consequences.

A flood of ideas

At the instant I heard this, a flood of ideas came to mind.

  • Why not enforce rules to prohibit deleting a customer with data in other systems?
  • Perhaps we need an archival feature?
  • Perhaps we could summarize information about users from other systems into a report instead changing a button color?
  • Even easier yet, why not just audit deleted customers so if someone needs this data in the future, they can find it.
  • Why are we deleting customers?
    • Are we cleaning up old information from a system without rules to enforce constraints?
    • Are we merging customers that were accidently duplicated? Perhaps we need a merge feature if this is common?

Objectives and implementation

The specifics of my ideas aren't the point, the point is everyone on a team has knowledge that can be shared, I've often been impressed by ideas from other people. Also, at the very least, everyone should know what they are trying to accomplish, the objective. How, is the implementation and can only be discussed in the context of the objective.

Asking why

When making or receiving a request, if you feel the urge to ask why, chances are something is missing. Even when you don't have an inclination to ask it, it may still be a good idea to force yourself.

Why objectives matter

There is the possibility that one could ask why to the point we get into a philosophical debate about words, that's not what I am after. My end is to understand the objectives of the business, the value they will add and how to measure if they are met. This way I can help ensure the value is achieved, which is what will make a business successful.

If I don't know the objectives, nor the value and metrics, then an implementation you hand to me may or may not achieve that objective. Furthermore, I don't believe people intentionally hide things, so if I'm not given this information my first inclination is to doubt if anyone else has even considered it. It's easy to get lost in implementation; it's one of the exciting parts of our work!

The cost of failed implementations

Anyone in software development dreads when we have to scrap an idea for another: first A, then B, then C. In my past this has often been paired with a lack of an explanation of what objective we were trying to accomplish. Worse yet, when I have asked why, I have often found no one else has asked why. Not only is this frustrating, it drives up costs. This alone is reason enough to talk about objectives first and implementation after.


Why requirejs?

Why are we using requirejs? I've even asked it of myself. For me, organizing large javascript projects and managing dependencies led to it. There are lots of great posts about how to use requirejs but I wanted to focus on WHY.

Explicit Dependency Specifications

Open up any significant sized javascript file with 100+ lines of code, even 50, and tell me, within 5 seconds, what dependencies it has. Can't do it? You can with modules and requirejs.

function View() {
    this.name = ko.observable('bob');
    this.age = ko.observable(20);
var view = new View();
ko.applyBindings(view, $('viewPlaceHolder')[0]);    


require(['jquery', 'knockout'], function($, ko) {
    // who knows whats in here, but I do know what it needs

How often do you use this information as a developer? Think about the value in not spending 5 minutes everytime you need to know, or more likely, the value in not creating a bug because you didn't take the time to find them all or you missed one.

Explicit Export Specifications

Along with explicit dependencies, modules have an explicit mechanism to define what they export. We can quickly read a module and know what it provides by looking at the return statement, instead of wondering what globals to access. define makes explicit that it is providing an interface to consumers.

define('math', ['dependencyA', 'dependencyB'], function(dependencyA, dependencyB) {
    // horrible things to local scope
    return {
            min: min,
            max: max,
            average: average

Avoid Script Tag Soup

<script src="scripts/utils.js">
<script src="scripts/numbers.js">
<script src="scripts/common.js">
<script src="scripts/formatting.js">
<script src="scripts/thing.js">
<script src="scripts/other.js">
<script src="scripts/site.js">

Did I type the path correctly? Are they ordered properly? Did someone change the order for a reason? Did they leave a comment, is it still applicable? What if I need to refactor one of them and change its position in the list?

With requirejs we can simply work on the dependency lists alone:

define('utils', [], function(){

define('numbers', [], function(){

define('common', ['utils', 'numbers'], function(){

define('formatting', [], function(){

define('thing', ['formatting'], function(){


This makes the dependencies explicit as we've shown above and doesn't hide meaning in an ordered list of script tags that are likely copy/pasted every time someone needs to load a set of dependencies, because who is going to manage this list and limit it to only the pieces they need, in every view of every application?

Confidence in Refactoring

Unlike in static typed languages, I can't just build to see if I messed up a dependency.

If dependency management is automatic, and we have an explicit, consistent specification of what interface we export from a module, and we use a function scope to organize our locals, it becomes very easy to make changes within a module, to split modules in parts etc. Our feeble human minds can focus on one module, but have a very difficult time taking into consideration the entire scope of the application. It's not that you can't practice this with function scopes alone, but it becomes a requirement with requirejs.

Shines a Light on Circular Dependencies and Intent

It's very easy to create circular dependencies in javascript, refactoring non module code to module code lets those issues bubble up to the dependency list and makes them apparent. It also helps other developers see how modules were intended to be used together, so they don't make assumptions and violate internal dependencies. You simply cannot see this stuff without a modular approach.

Simplified Testing

This falls back to script tag soup. When we setup tests we have to worry about loading scripts, even if it's just the module we are testing. We have three choices, take your pick:

  • Copy/paste a shared list between test fixtures, suffering testing speed and potentially breaking tests when updating this list.
  • Manually create this list for each test fixture, by manually scanning for dependencies, see above.
  • Use requirejs and forget about it

Simplifies Sharing Code

We have lots of handy JS we create, but sometimes we don't share it because it's too difficult to know what it needs. With requirejs, it's easy to see what needs to go with a piece of code, to use it elsewhere.

Works Client Side

Mobile and other solutions don't always end up using a server side technology and even if they do, it varies, so a module framework on the client is a huge benefit. Especially for organizing complex mobile applications.

Optimized Build

If desired, you can combine and minify your modules into one script for an optimized experience. The great part is you can use requirejs in dev without this and only add it as a deploy step, thus alleviating the need to build every time you make a change in dev.

Other benefits

  • Only load what you need, on demand and asynchronously!
  • Lazy loaded scripts
  • Although something is coming in ES harmony

    unless someone can get Microsoft to adopt rapid IE updates, even for old IEs, AMD will be around for a long time - James Burke

  • Consistent approach to mocking modules if testing via stubbing.

Articles against modules

Articles supporting modules


Consistent Formatting via Automatic Tools

Writing is a means to convey information. Most languages, human or code, have a great deal of expressiveness built in by default. Format is expressive too. When format changes, it draws our mental attention to it, thus we should use it when we want to cause a shift in attention, like when a direct quote is italicized, or when we begin a new thought with a new paragraph. However, if we are reckless with our formatting, we can easily confuse readers. If we take the time to keep a consistent format and only change when we intend to, we are much more likely to convey our message to the reader.

Be consistent

It's impossible for the world, let alone a single person, to agree on a specific format. However, within a context, I think most would at least agree to be consistent. I would actually argue that most of us don't care about the specifics so long as it's easy to be consistent. The context is subjective, some examples might be a single file, a series of blog posts, or a particular project at work. The context is actually part of the specifics, so be consistent with it too!

Automate consistency

Manual enforcement is a disaster waiting to happen and it's a waste of time. There are lots of tools to help detect and many to help automatically fix inconsistencies. Even the most basic word processor can determine if you didn't put in a double space at the start of a sentence, and add it if desired. If paragraphs are indented, this can be automated too.

Computer languages

When starting a project, make sure you have an IDE or a tool to format your code. Here are some things to help evaluate a particular tool:

  • Is it integrated with how you write your code?
  • Can you easily execute (shortcut key) the cleanup on the current file(s) or a text selection?
  • Can you version the configuration of specific rules within a context (line wrapping, spacing, indentation)?
    • This allows others to automatically work in a new context, without needing to know the specifics.
    • WebStorm is a fantastic example of an IDE where these settings can be shared with the team.
    • The specifics of format are an artifact of the project, it evolves over time, so you should version that if you want to understand historical formats.
  • Are all of the languages covered?
    • Often, I see people clean up the primary language (c#) but not html and javascript.

Case Study: Blogging

As I was writing this, I realized how crappy it is to format this blog post. So I moved it to markdown, where I can focus on the content and not the presentation, where there are specific conventions already established to automatically format the content. For now I'm converting that to html to post to my blog, I would like to automate that step and wire it into a github repository so it's easy for me to blog about new things and not worry about the publishing step.