diff --git a/.gitignore b/.gitignore
index 83c08fba63f2be651b4dbee75798abfe6c694147..f8b7c8fff694053401fdc44ac33cda425cd5e353 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,9 +27,9 @@ out
 smash/smash.log
 smash/smash/smash.log
 
-
+#coverage info
 .coverage
 smash/htmlcov/
-run-coverage.bat
+run-coverage.sh
 
 media
diff --git a/requirements.txt b/requirements.txt
index d974c761791eccf6fc3aa8daf93c13a73fe9128d..566c95d432192607aea1152756c2624615cbaad3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -14,4 +14,4 @@ pyexcel-xls==0.5.0
 pyexcel==0.5.3
 pycurl==7.43.0
 django-stronghold==0.2.9
-
+timeout-decorator==0.4.0
diff --git a/smash/web/forms/study_subject_forms.py b/smash/web/forms/study_subject_forms.py
index 7101e6bbeec368de1979c6f901b033b9f96cd8b4..44afb25786f47a3d43e6a7f56a9ea1387ccbdab6 100644
--- a/smash/web/forms/study_subject_forms.py
+++ b/smash/web/forms/study_subject_forms.py
@@ -19,7 +19,7 @@ class StudySubjectForm(ModelForm):
                                                     required=False
                                                     )
 
-    referral_letter = forms.FileField(label='Select a file', widget=SecuredFileWidget(), required=False)
+    referral_letter = forms.FileField(label='Referral letter', widget=SecuredFileWidget(), required=False)
 
     voucher_types = forms.ModelMultipleChoiceField(required=False,
                                                    widget=forms.CheckboxSelectMultiple,
diff --git a/smash/web/models/constants.py b/smash/web/models/constants.py
index 865f10ccf3c1c1e17f102a0cdca273c34cdc1014..ad7354a0bda27a3c369369e0425657fa6499e708 100644
--- a/smash/web/models/constants.py
+++ b/smash/web/models/constants.py
@@ -81,6 +81,9 @@ WEEKDAY_CHOICES = (
 REDCAP_TOKEN_CONFIGURATION_TYPE = "REDCAP_TOKEN_CONFIGURATION_TYPE"
 REDCAP_BASE_URL_CONFIGURATION_TYPE = "REDCAP_BASE_URL_CONFIGURATION_TYPE"
 
+# timeout job after 15 minutes
+CRON_JOB_TIMEOUT = 15 * 60
+
 COUNTRY_OTHER_ID = 1
 COUNTRY_AFGHANISTAN_ID = 2
 
diff --git a/smash/web/redcap_connector.py b/smash/web/redcap_connector.py
index 9055a1f2ee06ae0c5452a3378b9ea4bb0e25edea..7d448fc63de628c8e6ff6b870f9ac2e84afd59ea 100644
--- a/smash/web/redcap_connector.py
+++ b/smash/web/redcap_connector.py
@@ -5,11 +5,12 @@ import logging
 import pycurl
 
 import certifi
+import timeout_decorator
 from django_cron import CronJobBase, Schedule
 
 from web.models import ConfigurationItem, StudySubject, Language
 from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, \
-    REDCAP_BASE_URL_CONFIGURATION_TYPE
+    REDCAP_BASE_URL_CONFIGURATION_TYPE, CRON_JOB_TIMEOUT
 from web.models.inconsistent_subject import InconsistentField, InconsistentSubject
 from web.models.missing_subject import MissingSubject
 
@@ -322,6 +323,7 @@ class RedCapRefreshJob(CronJobBase):
     schedule = Schedule(run_every_mins=RUN_EVERY_MINUTES)
     code = 'web.red_cap_hourly_refresh'  # a unique code
 
+    @timeout_decorator.timeout(CRON_JOB_TIMEOUT)
     def do(self):
         connector = RedcapConnector()
         if connector.is_valid():
diff --git a/smash/web/smash_email.py b/smash/web/smash_email.py
index 882c39b4b732561dc34d779ba487d2f5913d66ef..32f3bb5e79b6915d235e25b8bff40dddcafa23fb 100644
--- a/smash/web/smash_email.py
+++ b/smash/web/smash_email.py
@@ -3,6 +3,7 @@
 import logging
 
 from django.conf import settings
+from django.core import mail
 from django.core.mail import EmailMessage
 
 logger = logging.getLogger(__name__)
@@ -26,5 +27,7 @@ class EmailSender(object):
             cc=cc_recipients
         )
         message.content_subtype = "html"
+        print "mails sent: " + str(len(mail.outbox))
         message.send()
+        print "mails sent: " + str(len(mail.outbox))
         logger.info('Email sent. Subject: ' + subject + "; Recipients: " + recipients)
diff --git a/smash/web/tests/view/test_KitRequestEmailSendJob.py b/smash/web/tests/view/test_KitRequestEmailSendJob.py
index f6e58798c859a092c2481fb824cab461a3fb7d08..9959087201c359cb02141f5dedf0f390449e27e9 100644
--- a/smash/web/tests/view/test_KitRequestEmailSendJob.py
+++ b/smash/web/tests/view/test_KitRequestEmailSendJob.py
@@ -37,5 +37,6 @@ class KitRequestEmailSendJobTests(LoggedInTestCase):
         status = job.do()
 
         self.assertEqual("mail sent", status)
+        print len(mail.outbox)
         self.assertEqual(1, len(mail.outbox))
         self.assertEqual(workers_count, Worker.objects.all().count())
diff --git a/smash/web/views/kit.py b/smash/web/views/kit.py
index 7c8875662f27ed77399d44984546684d94da1127..6448b09851f0412154b567ce5b077241b7448cd2 100644
--- a/smash/web/views/kit.py
+++ b/smash/web/views/kit.py
@@ -6,6 +6,7 @@ import platform
 import time
 
 import pytz
+import timeout_decorator
 from django.contrib import messages
 from django.utils.dateparse import parse_datetime
 from django_cron import CronJobBase, Schedule
@@ -14,7 +15,7 @@ from django_cron.models import CronJobLog
 from notifications import get_filter_locations, get_today_midnight_date
 from web.models import ConfigurationItem, Language, Worker
 from web.models.constants import KIT_EMAIL_HOUR_CONFIGURATION_TYPE, \
-    KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE
+    KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE, CRON_JOB_TIMEOUT
 from web.models.constants import KIT_RECIPIENT_EMAIL_CONFIGURATION_TYPE
 from . import wrap_response
 from ..forms import KitRequestForm
@@ -140,6 +141,7 @@ class KitRequestEmailSendJob(CronJobBase):
     schedule = Schedule(run_every_mins=RUN_EVERY_MINUTES)
     code = 'web.kit_request_weekly_email'  # a unique code
 
+    @timeout_decorator.timeout(CRON_JOB_TIMEOUT)
     def do(self):
         now = datetime.datetime.utcnow()
         hour = int(ConfigurationItem.objects.get(
diff --git a/smash/web/views/voucher.py b/smash/web/views/voucher.py
index 3124cc302b93ea9e7329ee427a2e27e5394a7184..5323427791e0d480e0c4b485327d0d103e0d966d 100644
--- a/smash/web/views/voucher.py
+++ b/smash/web/views/voucher.py
@@ -1,6 +1,7 @@
 # coding=utf-8
 import logging
 
+import timeout_decorator
 from django.contrib.messages.views import SuccessMessageMixin
 from django.urls import reverse_lazy
 from django.views.generic import CreateView
@@ -11,7 +12,7 @@ from django_cron import CronJobBase, Schedule
 from web.views.notifications import get_today_midnight_date
 from web.forms import VoucherForm
 from web.models import Voucher, StudySubject, MailTemplate
-from web.models.constants import GLOBAL_STUDY_ID, VOUCHER_STATUS_NEW, VOUCHER_STATUS_EXPIRED
+from web.models.constants import GLOBAL_STUDY_ID, VOUCHER_STATUS_NEW, VOUCHER_STATUS_EXPIRED, CRON_JOB_TIMEOUT
 from . import WrappedView
 
 logger = logging.getLogger(__name__)
@@ -80,6 +81,7 @@ class ExpireVouchersJob(CronJobBase):
     code = 'web.voucher_expiry_job'  # a unique code
 
     # noinspection PyMethodMayBeStatic
+    @timeout_decorator.timeout(CRON_JOB_TIMEOUT)
     def do(self):
         due_date = get_today_midnight_date()
         vouchers = Voucher.objects.filter(status=VOUCHER_STATUS_NEW, expiry_date__lte=due_date)