diff --git a/classes/log/store.php b/classes/log/store.php
index 566be0215e01d9cb6951f3dfdf86186765ef316d..d3d35bd8e42430772c89e468ed3524106143e77c 100644
--- a/classes/log/store.php
+++ b/classes/log/store.php
@@ -63,7 +63,7 @@ class store extends php_obj implements log_writer {
      * Should the event be ignored (not logged)? Overrides helper_writer.
      * @param event_base $event
      * @return bool
-     * 
+     *
      */
     protected function is_event_ignored(event_base $event) {
         return false;
@@ -75,6 +75,19 @@ class store extends php_obj implements log_writer {
      *
      */
     protected function insert_event_entries(array $events) {
+        global $DB;
+
+        // If in background mode, just save them in the database
+        if (get_config('logstore_xapi', 'backgroundmode')) {
+            $DB->insert_records('logstore_xapi_log', $events);
+        } else {
+            $this->process_events($events);
+        }
+
+    }
+
+    public function process_events(array $events) {
+
         // Initializes required services.
         $xapicontroller = new xapi_controller($this->connect_xapi_repository());
         $moodlecontroller = new moodle_controller($this->connect_moodle_repository());
@@ -82,11 +95,20 @@ class store extends php_obj implements log_writer {
 
         // Emits events to other APIs.
         foreach ($events as $event) {
+            $event = (array) $event;
             // $this->error_log('');
             // $this->error_log_value('event', $event);
             $moodleevent = $moodlecontroller->createEvent($event);
+            if (is_null($moodleevent)) {
+                continue;
+            }
+
             // $this->error_log_value('moodleevent', $moodleevent);
             $translatorevent = $translatorcontroller->createEvent($moodleevent);
+            if (is_null($translatorevent)) {
+                continue;
+            }
+
             // $this->error_log_value('translatorevent', $translatorevent);
             $xapievent = $xapicontroller->createEvent($translatorevent);
             // $this->error_log_value('xapievent', $xapievent);
diff --git a/classes/task/emit_task.php b/classes/task/emit_task.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd4b06b03c07ea2edc502b8c6bffb4939e592e7c
--- /dev/null
+++ b/classes/task/emit_task.php
@@ -0,0 +1,59 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Process events in queue.
+ *
+ * @package    logstore_xapi
+ * @copyright  2015 Michael Aherne
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace logstore_xapi\task;
+
+use tool_log\log\manager;
+use logstore_xapi\log\store;
+defined('MOODLE_INTERNAL') || die();
+
+class emit_task extends \core\task\scheduled_task {
+
+    /**
+     * Get a descriptive name for this task (shown to admins).
+     *
+     * @return string
+     */
+    public function get_name() {
+        return get_string('taskemit', 'logstore_xapi');
+    }
+
+    /**
+     * Do the job.
+     * Throw exceptions on errors (the job will be retried).
+     */
+    public function execute() {
+        global $DB;
+
+        $manager = get_log_manager();
+        $store = new store($manager);
+
+        $events = $DB->get_records('logstore_xapi_log');
+        $store->process_events($events);
+
+        $DB->delete_records_list('logstore_xapi_log', 'id', array_keys($events));
+
+        mtrace("Sent learning records to LRS.");
+    }
+}
diff --git a/db/install.xml b/db/install.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d09c1e918c8118b0866342f32af9f3dd08f64244
--- /dev/null
+++ b/db/install.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<XMLDB PATH="admin/tool/log/store/xapi/db" VERSION="20140415" COMMENT="XMLDB file for Moodle admin/tool/log/store/xapi"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="../../../../../../lib/xmldb/xmldb.xsd"
+>
+  <TABLES>
+    <TABLE NAME="logstore_xapi_log" COMMENT="xAPI holding table for cron processing">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
+        <FIELD NAME="eventname" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="component" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="action" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="target" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="objecttable" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="objectid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="crud" TYPE="char" LENGTH="1" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="edulevel" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="contextlevel" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="contextinstanceid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="relateduserid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="anonymous" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Was this event anonymous at the time of triggering?"/>
+        <FIELD NAME="other" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="origin" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="cli, cron, ws, etc."/>
+        <FIELD NAME="ip" TYPE="char" LENGTH="45" NOTNULL="false" SEQUENCE="false" COMMENT="IP address"/>
+        <FIELD NAME="realuserid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="real user id when logged-in-as"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="timecreated" UNIQUE="false" FIELDS="timecreated"/>
+        <INDEX NAME="course-time" UNIQUE="false" FIELDS="courseid, anonymous, timecreated"/>
+        <INDEX NAME="user-module" UNIQUE="false" FIELDS="userid, contextlevel, contextinstanceid, crud, edulevel, timecreated"/>
+      </INDEXES>
+    </TABLE>
+  </TABLES>
+</XMLDB>
\ No newline at end of file
diff --git a/db/tasks.php b/db/tasks.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1ddd49191b7b6ffadf8859c3911bacbd21e9a3b
--- /dev/null
+++ b/db/tasks.php
@@ -0,0 +1,37 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Standard log reader/writer cron task.
+ *
+ * @package    logstore_xapi
+ * @copyright  2015 Michael Aherne
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$tasks = array(
+    array(
+        'classname' => '\logstore_xapi\task\emit_task',
+        'blocking' => 0,
+        'minute' => '*/5',
+        'hour' => '*',
+        'day' => '*',
+        'dayofweek' => '*',
+        'month' => '*'
+    ),
+);
\ No newline at end of file
diff --git a/db/upgrade.php b/db/upgrade.php
new file mode 100644
index 0000000000000000000000000000000000000000..abb333f65b1d7a7a88299ade56f9a6fdf964ef89
--- /dev/null
+++ b/db/upgrade.php
@@ -0,0 +1,76 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * xAPI log store upgrade.
+ *
+ * @package    logstore_xapi
+ * @copyright  2015 Michael Aherne
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function xmldb_logstore_xapi_upgrade($oldversion) {
+    global $CFG, $DB;
+
+    $dbman = $DB->get_manager();
+
+    if ($oldversion < 2015081001) {
+
+        // Define table logstore_xapi_log to be created.
+        $table = new xmldb_table('logstore_xapi_log');
+
+        // Adding fields to table logstore_xapi_log.
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('eventname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('action', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('target', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('objecttable', XMLDB_TYPE_CHAR, '50', null, null, null, null);
+        $table->add_field('objectid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
+        $table->add_field('crud', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('edulevel', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('contextlevel', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('contextinstanceid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
+        $table->add_field('relateduserid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
+        $table->add_field('anonymous', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
+        $table->add_field('other', XMLDB_TYPE_TEXT, null, null, null, null, null);
+        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('origin', XMLDB_TYPE_CHAR, '10', null, null, null, null);
+        $table->add_field('ip', XMLDB_TYPE_CHAR, '45', null, null, null, null);
+        $table->add_field('realuserid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
+
+        // Adding keys to table logstore_xapi_log.
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+
+        // Adding indexes to table logstore_xapi_log.
+        $table->add_index('timecreated', XMLDB_INDEX_NOTUNIQUE, array('timecreated'));
+        $table->add_index('course-time', XMLDB_INDEX_NOTUNIQUE, array('courseid', 'anonymous', 'timecreated'));
+        $table->add_index('user-module', XMLDB_INDEX_NOTUNIQUE, array('userid', 'contextlevel', 'contextinstanceid', 'crud', 'edulevel', 'timecreated'));
+
+        // Conditionally launch create table for logstore_xapi_log.
+        if (!$dbman->table_exists($table)) {
+            $dbman->create_table($table);
+        }
+
+        // Xapi savepoint reached.
+        upgrade_plugin_savepoint(true, 2015081001, 'logstore', 'xapi');
+    }
+
+    return true;
+}
diff --git a/lang/en/logstore_xapi.php b/lang/en/logstore_xapi.php
index 1f27a2bcee93f705f07e3fdc9ba985da50136e12..f8d450cb4463c6672fa95484fc502e7b8e1db272 100644
--- a/lang/en/logstore_xapi.php
+++ b/lang/en/logstore_xapi.php
@@ -34,4 +34,9 @@ $string['pluginadministration'] = 'Logstore xAPI administration';
 $string['pluginname'] = 'Logstore xAPI';
 $string['submit'] = 'Submit';
 $string['username'] = 'Username';
-$string['xapisettingstitle'] = 'Logstore xAPI Settings';
\ No newline at end of file
+$string['xapisettingstitle'] = 'Logstore xAPI Settings';
+$string['backgroundmode'] = 'Send statements by scheduled task?';
+$string['backgroundmode_desc'] = 'This will force Moodle to send the statements to the LRS in the background,
+        via a cron task. This will make the process less close to real time, but will help to prevent unpredictable
+        Moodle performance linked to the performance of the LRS.';
+$string['taskemit'] = 'Emit records to LRS';
\ No newline at end of file
diff --git a/settings.php b/settings.php
index d1a49a6740dbba70d01f43a4d78e89bc72ed47d8..269603c4cc2326081b0941ab488947a82e17a941 100644
--- a/settings.php
+++ b/settings.php
@@ -27,13 +27,18 @@ defined('MOODLE_INTERNAL') || die();
 
 if ($hassiteconfig) {
     // Endpoint.
-    $settings->add(new admin_setting_configtext('logstore_xapi/endpoint', 
-        get_string('endpoint', 'logstore_xapi'), '', 
+    $settings->add(new admin_setting_configtext('logstore_xapi/endpoint',
+        get_string('endpoint', 'logstore_xapi'), '',
         'http://your.domain.com/endpoint/location/', PARAM_URL));
     // Username.
-    $settings->add(new admin_setting_configtext('logstore_xapi/username', 
+    $settings->add(new admin_setting_configtext('logstore_xapi/username',
         get_string('username', 'logstore_xapi'), '', 'username', PARAM_TEXT));
     // Key or password.
-    $settings->add(new admin_setting_configtext('logstore_xapi/password', 
+    $settings->add(new admin_setting_configtext('logstore_xapi/password',
         get_string('password', 'logstore_xapi'), '', 'password', PARAM_TEXT));
+
+    // Switch background batch mode on
+    $settings->add(new admin_setting_configcheckbox('logstore_xapi/backgroundmode',
+        get_string('backgroundmode', 'logstore_xapi'),
+        get_string('backgroundmode_desc', 'logstore_xapi'), 0));
 }
diff --git a/version.php b/version.php
index e0d4417c2f02966ebc7f1d365da04259e87ae946..2f3ea825258e9efc94818944ddacfa6a06db07c0 100644
--- a/version.php
+++ b/version.php
@@ -26,7 +26,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component = 'logstore_xapi';
-$plugin->version = 2015081000;
+$plugin->version = 2015081002;
 $plugin->release = '0.3.0';
 $plugin->requires = 2014111000;
 $plugin->maturity = MATURITY_BETA;