One of the secrets of getting things done is to move as much information as possible from your memory to easily retrievable task lists and reference documents so that your mind can focus on coming up with new ideas.

For tasks, the ideal system depends on the expected duration of the task:

  1. For the tasks which can be finished within, say, 10 minutes, such as shopping lists, with no trail required, the key is speed and the ease of use – I recommend Microsoft ToDo – available on all platforms, with native MS Office365  integration
  2. For the tasks based upon emails or with a given due date and with very infrequent look ups, I recommend MS Office 365‘s Email Follow Ups and Tasks.
  3. For the tasks which will take a few hours or more to finish and which or whose notes we expect to look up frequently, I have not found anything better than Atlassian JIRA.

For reference documents, the perfect system depends on the nature of the information:

  1. Emails – Finding anything in emails is always a challenge, so the best is to move the reference information out of the emails and just archive the emails using sophisticated folder structures.
  2. Daily Journal – Daily Journal is useful for reflection and I recommend using Day One.
  3. Source Code Snippets – Use a special code snippets database, such as SnippetLabs, or just use Atlassian Confluence.
  4. Website clippings – You may try to use Evernote, but that works well only for fewer than say 40k notes. And Evernote Web Clipper has problems with certain websites, so you may prefer pure MHT files.
  5. Knowledge Base – This is the place where you store pre-processed information expected to be retrieved frequently as concisely as possible. I have not found anything better than Atlassian Confluence. Self-hosted JIRA can be easily used for public knowledge bases – see the instructionsJetBrains’s documentation website is an excellent example.

It’s frequently said that your tools fundamentally shape you and your options. Thus, choose them wisely.

Having said that, be careful NOT to over-structure yourself. Simplicity is beautiful. All task management should be a means to the goal and not the goal itself.

1. Task Management Best Practices

Plans are worthless. Planning is essential.
-Dwight D. Eisenhower

The best practice is to review all your task lists once a week and prioritize the open tasks based upon their perceived priority.

Source: StartupVitamins.com

The criteria should include

  1. The Eisenhower Box and the Eisenhower Hierarchy

  2. The 80/20 Pareto Rule – describes the imbalance between the cause and the effect where 80% of effects in a given case is caused just by 20% of causes (to find the root cause, use the 5 Whys method). Thus, you should focus on the tasks with the greatest impact on your goals by focusing on the 20% of problem root causes.

    The Pareto Analysis consists of 4 steps (Source: PMI):

2. Task Management with JIRA

JIRA is most suited for tracking and management of substantially big tasks which fall into at least one of the below categories:

  1. You expect to look up the task’s case notes and the time / resources required in the future as a reference for solving and estimation of similar or identical problems
  2. You use the tasks to show your team what tasks / issues you’re working on
  3. You cannot finish the task now and it’s a task which requires to be JIRA tracked
  4. You use the tasks as components of execution of your road map – the most common case.

When using JIRA, I recommend staying pragmatic and recommend not entering everything you work on or intend to work on as separate tasks because the more items you create, the harder the future search is and because creating a proper JIRA item with the right classification requires certain time. If truly required for time management to log work done, create a few catch-all issues, like “Team Meetings”, “General Bug Fixing” and put the details into the issue comments.

It’s principal to recognize that using JIRA does not imply one is agile. Being agile requires much more – it’s a mindset which propagates throughout that person and her team’s every single decision.

JIRA can be significantly customized, with custom JIRA items, fields, workflows etc. The below text refers to the standard setup.

NOTE: Watch the free Atlassian University’s JIRA Tutorials.

2.1 Task Creation and Organization

Every item you create in JIRA should be created with future search in mind. Thus:

  • use abbreviations consistently
  • the text should be keyword based
  • avoid creating too many small tasks for simple problems; rather, create an evergreen one (the one which is always open) and which is getting just comments or time logs

For using JIRA as a part of your road map execution, you first identify the big themes, called epics, which you break down into stories, and may be sub-tasks.

Source: Atlassian

For JIRA, an issue – the most elementary element it works with – by default – can be epic, story, task, item’s sub-task, bug, improvement or a new feature.

JIRA Issue TypeDescriptionRecommendations
EpicA collection of a number of related stories 
StoryBasic unit of work 
TaskUse Tasks for admin tasks and activities which take less time than a storyCreate a few “evergreen tasks” used for repeated activities, such as “Weekly Code Review”, “Meetings” etc.
Item’s Sub-TaskUse Sub-Tasks for a breakdown of a task into it’s components 
BugA Story for reporting a problem / defect in the solution. Useful in Searching for Bug Issues. 
ImprovementA Story for reporting minor improvements in the solution. Useful in Searching for Improvement Issues. 
New FeatureA Story reporting minor new features in the solution. Useful in Searching for New Features Issues.  For large features, use Stories. 

Do NOT create a JIRA item for ideas which may or may not get executed. Rather, create a new page in Confluence called Ideas list and put the idea there.

Time-wise, each JIRA item can be classified as follows:

JIRA Item’s Time Field TypeDescriptionRecommendations
VersionA Version differentiates various software builds.Increase version number with each breaking change.
SprintSprint is a periodic interval of usually constant time length.Use weekly sprints.

Impact-wise, each JIRA item can be further classified with following fields:

JIRA Item’s Impact Field TypeDescriptionRecommendations
ComponentSolution breakdown into meaningful units.Use as number of hierarchies:


  1. Break down the solution functionality -> e.g. UI, Persistence
  2. Break down the solution architecture -> e.g. by libraries used
LabelLabel is field used for cross-component tags. 
Custom FieldsAbstract away all necessary fields used for your workflows.You control what you measure.

Frequently used custom fields are “Business Value”, or “Story Points”.

2.2 Task Lookup

As explained, everything stored in JIRA should be structured with the future lookup in mind.

I recommend setting up a few standard Issue Filters:

  1. Not Finished and Due Within 7 days:
    status not in (Closed, Done, Resolved) AND due <= 7d
  2. Not Finished, and Not In Progress and Due Within 30 days:
    status not in (Closed, Done, Resolved, "In Progress") AND due <= 30d

2.3 Task Planning

I recommend using weekly Sprints with the Sprint Name being the week number, e.g. “Week 2017-50” because this organization quickly allows you to decipher to what week the issue has been scheduled.

2.4 Task Reporting

JIRA itself has support for basic Dashboards, but you can get much more advanced reporting using the JIRA’s Content Pack for MS PowerBI.

2.5 Source Code Repository

Git is the standard version control system nowadays, and GitHub is the most 3rd Parties’ supported GIT cloud provider. Bitbucket may be cheaper but its ecosystem may be limited.

JIRA can be connected with a GIT repository and display for each issue the relevant source code check-ins.

I recommend standardizing the check-in messages into the format “[FUSE-113] Fixed Abcde” where FUSE-113 is the JIRA issue code.

2.6 Recommended JIRA Addins

2.7 JIRA / Confluence REST API

Most JIRA / Confluence functionality can be accessed via their REST APIs.

One script every serious user of JIRA should use is a forced re-index of all issues to be run every day at night. Once in a while, some addon is automatically updated or something else happens and then JIRA asks you to re-index manually the database. This script (to be put to your cron scheduler) automates it

/usr/bin/curl --request POST --url https://myfirm.atlassian.net/rest/api/2/reindex --header 'authorization: Basic XXX' --header 'cache-control: no-cache'

where myfirm.atlassian.net is your JIRA server name and where XXX is the basic authentication string for your credentials.

2.8 JIRA / Confluence Templates

Confluence has a support for templates but they are not versioned and are unlikely to be versioned soon. For JIRA, there are some 3rd party addins for templates, such as this one.

Nevertheless, I personally prefer using Mac / Windows text expanders, such as PhraseExpander for Windows and shortly for Mac or TextExpander for all platforms.

2.9 Hosted vs. Self-Hosted JIRA + Confluence

JIRA and Confluence can be either self-hosted or hosted by Atlassian in their cloud.

Hosted JIRA and Confluence do have the below advantages

  1. Atlassian taking care of the sysops work – provisioning the servers, all software and operating system updates, automatic backups – for a reasonable price
  2. There are special iPhone Atlassian apps which do not work with your self-hosted versions.

    Nevertheless, this is less of a problem, at least for me, since I carry my notebook with me all the time and I never fell in love with the iPhone JIRA or Confluence’s App. When really needed, I can simply fire up the iPhone’s Safari browser and access the web directly.

    Furthermore, there are various 3rd party iOS apps providing access to JIRA, both self-hosted and Atlassian-hosted, some of them with offline sync of the issues with various level of success. They never worked for me either.

Having used hosted JIRA and Confluence for the last 5+ years, I am moving to their self-hosted versions for the following reasons:

  1. Personal / Corporate Brand – personal / corporate image is critical and it does show the level of detail one gives to the clients. Atlassian has refused to address this issue for over 6 years.

    It’s a big difference if the JIRA is hosted at myfirm.atlassian.net or at jira.myfirm.com. The former indicates you may be a transient hippie whereas the latter is a hallmark of a serious business.
  2. Automated Admin Processes – for example, hosted JIRA / Confluence does not allow you to trigger, and to download the generated backups from a script.
  3. Unlimited Customization of JIRA / Confluence – self-hosted JIRA / Confluence allows you to hide certain elements, and customize much more than their restricted hosted counterparts
  4. Security – you cannot download access logs, you cannot restrict access to just a few IP addresses, you cannot enable 2-factor authentication, nothing. Moreover, with the REST API open, anybody can keep trying your password with unknown Atlassian’s security measures taken, if any.
  5. Ability to install and interconnect other Atlassian software, such as Crucible or FishEye – these are not available in the Atlassian Cloud
  6. Access to substantially more 3rd party plugins for JIRA / Confluence
  7. And performance – the Atlassian-hosted JIRA / Confluence is occasionally rather slow

2.10 How to Set Up a Self-Hosted JIRA

Note: The analogous instructions apply for setting up a self-hosted Confluence.

Note: Atlassian provides ready AWS CloudFormation templates for AWS installation of their software.

I recommend setting up JIRA under Appache Httpd reverse proxy for

  • it provides an easy access to access logs for further analysis
  • it easily allows plugging in security addons, such as mod_security (there are special rules for JIRA / Confluence) or fail2ban
  • it is the easiest way to supports http2 or gzip compression
  • it is the easiest way to correctly set up SSL

I recommend installing on a Linux machine for its performance is superior to and its costs are significantly lower than a Windows Server machine.

The below instructions are for AWS EC2 Linux / RedHat VMs:

2.10.1 Apache Httpd Installation

sudo yum update -y
sudo su

# Pre-requisites
yum install -y mc mlocate at wget links perl gcc 
yum groupinstall "Development Tools" -y
yum install autoreconf automake autoconf pcre-devel openssl-devel git wget mlocate -y

# OpenSSL
yum install perl-core
cd /usr/local/src
wget https://www.openssl.org/source/openssl-1.0.2m.tar.gz
tar -zxvf openssl-1.0.2m.tar.gz
cd openssl-1.0.2m
./config --prefix=/usr --openssldir=/usr/local/openssl shared
make install

# Curl
cd /usr/local/src
mkdir curl
cd curl
curl -R -O https://curl.haxx.se/download/curl-7.57.0.tar.gz
tar zxf curl-7.57.0.tar.gz
cd curl-7.57.0
make install
mv -f /usr/bin/curl /usr/bin/curl.old
cp /usr/local/bin/curl /usr/bin/curl

# nghttp2
sudo yum install python-devel
cd /usr/local/src
git clone https://github.com/nghttp2/nghttp2
cd nghttp2
git submodule update --init
autoreconf -i
make install

# Apache httpd
yum install expat-devel
cd /usr/local/src/
wget http://www-us.apache.org/dist//httpd/httpd-2.4.29.tar.gz
tar -zxvf httpd-2.4.29.tar.gz
cd httpd-2.4.29
cd srclib 
wget http://www-us.apache.org/dist//apr/apr-1.6.3.tar.gz
tar xvf apr-1.6.3.tar.gz
mv apr-1.6.3 apr 
wget http://www-us.apache.org/dist//apr/apr-util-1.6.1.tar.gz
tar xvf apr-util-1.6.1.tar.gz
mv apr-util-1.6.1 apr-util 
wget http://www-us.apache.org/dist//apr/apr-iconv-1.2.2.tar.gz
tar xvf apr-iconv-1.2.2.tar.gz
mv apr-iconv-1.2.2 apr-iconv
cd /usr/local/src/httpd-2.4.29
./configure --prefix=/opt/httpd --enable-http2 --with-nghttp2=/usr/local/lib --enable-so --with-ssl=/usr/bin/openssl --with-included-apr 
make install

2.10.2 Atlassian JIRA Installation Database Setup for JIRA

I prefer using MySQL / Aurora as the Database backend. The necessary database steps:

  1. On AWS RDS, create a parameter group on mysql
    set innodb_log_file_size to 536870912
    set max_allowed_packet to 67108864
  2. Create the JIRA database
     CREATE DATABASE jira CHARACTER SET utf8 COLLATE utf8_bin; MySQL Connector for JAVA

Download the MySQL Connector for JAVA https://dev.mysql.com/downloads/connector/j/ and upload to /home/ec2-user. Actual JIRA Installation

Run these commands:

sudo su
yum install mysql

mkdir /usr/local/src/mysql-connector-java
mv mysql-connector-java-5.1.44.tar.gz /usr/local/src/mysql-connector-java
cd /usr/local/src/mysql-connector-java
tar -zxvf mysql-connector-java-5.1.44.tar.gz

wget https://www.atlassian.com/software/jira/downloads/binary/atlassian-jira-core-7.6.0-x64.bin
chmod a+x atlassian-jira-core-7.6.0-x64.bin

wget https://www.atlassian.com/software/jira/downloads/binary/atlassian-jira-software-7.6.0-x64.bin
chmod a+x atlassian-jira-software-7.6.0-x64.bin

When prompted for the installation type, choose the Express installation.

After the JIRA has been installed, adjust the config files as follows: httpd.conf
ServerRoot "/opt/httpd"

Protocols http/1.1 h2 h2c
H2MaxSessionStreams 10
H2MaxWorkerIdleSeconds 15
H2MaxWorkers 15
H2MinWorkers 5

LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule http2_module modules/mod_http2.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so

<IfModule unixd_module>
User daemon
Group daemon

ServerAdmin admin@myfirmname.com
ServerName jira.myfirmname.com

<Directory />
    AllowOverride none
    Require all denied

<Files ".ht*">
    Require all denied

ErrorLog "logs/error_log"
LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    CustomLog "logs/access_log" common

<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/opt/httpd/cgi-bin/"

<IfModule headers_module>
    RequestHeader unset Proxy early

<IfModule mime_module>
    TypesConfig conf/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz

<IfModule proxy_html_module>
Include conf/extra/proxy-html.conf

<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin

<IfModule http2_module>
    LogLevel http2:info

<Proxy *>
    Require all granted

SSLProxyEngine          On
ProxyRequests           Off

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/

<Location />
    Require all granted
</Location> httpd-ssl.conf

Put in there your SSL certificate’s paths. JIRA’s server.xml
<?xml version="1.0" encoding="utf-8"?>
<Server port="8005" shutdown="SHUTDOWN">
    <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

    <Service name="Catalina">
        <Connector port="8080" maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false" maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443" acceptCount="100" disableUploadTimeout="true" bindOnInit="false" proxyName="jira.myfirmname.com" proxyPort="443"  scheme="https"/>

        <Engine name="Catalina" defaultHost="localhost">
            <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
                <Context path="" docBase="${catalina.home}/atlassian-jira" reloadable="false" useHttpOnly="true">
                    <Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction"
                              factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>
                    <Manager pathname=""/>
                    <JarScanner scanManifest="false"/>

            <Valve className="org.apache.catalina.valves.AccessLogValve"
                   pattern="%a %{jira.request.id}r %{jira.request.username}r %t &quot;%m %U%q %H&quot; %s %b %D &quot;%{Referrer}i&quot; &quot;%{User-Agent}i&quot; &quot;%{jira.request.assession.id}r&quot;"/>
</Server> Reboot

Reboot the Linux box.

2.10.3 Atlassian JIRA Maintenance