diff --git a/config.sample.json b/config.sample.json
index a0b3b3c..fc4e151 100644
--- a/config.sample.json
+++ b/config.sample.json
@@ -22,5 +22,18 @@
 
     "do_not_trim_long_sms": false,
 
-    "default_modem": "SMS0"
+    "default_modem": "SMS0",
+
+    "# handler_chooser_algorithm": "algoritma untuk memilih modem dalam mengirim SMS. Pilihan: LAST-SEEN, FORCED. Default: LAST-SEEN",
+    "handler_chooser_algorithm": "LAST-SEEN",
+
+    "# sending handler": "list modem yang dipakai untuk mengirim jika handler_chooser_algorithm === 'FORCED'",
+    "sending_handler": [
+        "SMS0",
+        "SMS1"
+    ],
+
+    "redis": {
+        "host": "127.0.0.1"
+    }
 }
\ No newline at end of file
diff --git a/lib/handler-callback-server.js b/lib/handler-callback-server.js
index 20d3b01..a04312b 100644
--- a/lib/handler-callback-server.js
+++ b/lib/handler-callback-server.js
@@ -13,6 +13,7 @@ const config = require('komodo-sdk/config');
 const logger = require('komodo-sdk/logger');
 
 const transport = require('./transport');
+const partnerLastSeen = require('./partner-last-seen');
 
 const app = express();
 messagingService.setTransport(transport);
@@ -31,6 +32,8 @@ function onIncomingSms(req, res) {
     res.end('OK');
     const numberWithSuffix = req.query.number + (config.number_suffix || '');
 
+    partnerLastSeen.set(req.query.number, req.query.modem);
+
     logger.info('HANDLER-CALLBACK-SERVER: Incoming SMS', { modem: req.query.modem, from: req.query.number, from_with_suffix: numberWithSuffix, msg: req.query.msg });
     messagingService.onIncomingMessage({
         me: req.query.modem,
diff --git a/lib/partner-last-seen.js b/lib/partner-last-seen.js
new file mode 100644
index 0000000..b228372
--- /dev/null
+++ b/lib/partner-last-seen.js
@@ -0,0 +1,57 @@
+"use strict";
+
+const REDIS_TTL_SECS = 3600 * 24 * 7;
+
+const config = require('komodo-sdk/config');
+
+const redis = require('redis');
+const redisClient = redis.createClient(config.redis || { host: '127.0.0.1' });
+
+const _caches = {};
+
+
+function _composeKeyword(partner) {
+    return `POCHINKI_PARTNER_LAST_SEEN_${ partner }`;
+}
+
+function get(partnerNumber) {
+    return new Promise(function(resolve) {
+
+        if (!partnerNumber) {
+            resolve(null);
+        }
+        else if (_caches[partnerNumber]) {
+            resolve(_caches[partnerNumber]);
+        }
+        else {
+            const keyword = _composeKeyword(partnerNumber);
+            
+            redisClient.get(keyword, function(err, reply) {
+                if (err) {
+                    resolve(null);
+                }
+                else if (reply) {
+                    resolve(Number(reply));
+                    _caches[partnerNumber] = Number(reply);
+                }
+                else {
+                    resolve(null);
+                }
+            })
+        }
+    })
+}
+
+function set(partnerNumber, modemName) {
+    if (!partnerNumber || !modemName) {
+        return;
+    }
+
+    _caches[partnerNumber] = modemName;
+
+    const keyword = _composeKeyword(partnerNumber);
+    redisClient.set(keyword, modemName, 'EX', REDIS_TTL_SECS);
+}
+
+exports.get = get;
+exports.set = set;
diff --git a/lib/transport.js b/lib/transport.js
index 9e2e96c..c6c9932 100644
--- a/lib/transport.js
+++ b/lib/transport.js
@@ -7,8 +7,50 @@ const config = require('komodo-sdk/config');
 const logger = require('komodo-sdk/logger');
 
 const modems = require('./modems');
+const partnerLastSeen = require('./partner-last-seen');
 
-function send(partner, msg, origin) {
+async function _getApproriateHandlerByLastSeen(partnerNumber) {
+    logger.verbose('Looking for last seen on for partner number ' + partnerNumber);
+    const lastSeenFrom = await partnerLastSeen.get(partnerNumber);
+    return lastSeenFrom;
+}
+
+function _getApproriateHandlerByForced() {
+    if (!config.sending_handler || !config.sending_handler.length) return;
+
+    const sendingHandlerCount = config.sending_handler.length;
+    const idx = Math.floor(Math.random() * sendingHandlerCount);
+    return config.sending_handler[idx];
+}
+
+async function _getApproriateHandler(partnerNumber, origin) {
+    let handlerToUse;
+
+    if (config.handler_chooser_algorithm === 'FORCED') {
+        handlerToUse = _getApproriateHandlerByForced();
+        logger.verbose('Config file mentioned to using FORCED handler chooser algorithm', { handler_to_use: handlerToUse});
+    }
+    else {
+        handlerToUse = await _getApproriateHandlerByLastSeen(partnerNumber);
+        logger.verbose('Config file mentioned to using LAST-SEEN handler chooser algorithm', { handler_to_use: handlerToUse});
+    }
+
+    if (!modems.getModemConfig(handlerToUse, config.modems)) {
+        const handlerWithSameOrigin = modems.getModemConfig(origin, config.modems);
+        if (handlerWithSameOrigin) {
+            logger.verbose('Invalid approriate handler, using handler from the same ORIGIN request by CORE to send sms')
+            handlerToUse = origin;
+        }
+        else {
+            logger.verbose('Invalid approriate handler, using default handler to send sms')
+            handlerToUse = config.default_modem;
+        }
+    }
+
+    return handlerToUse;
+}
+
+async function send(partner, msg, origin) {
     if (!partner) return;
 
     if (typeof msg !== 'string') {
@@ -19,12 +61,17 @@ function send(partner, msg, origin) {
     msg = msg.trim();
     if (!msg) return;
 
+    const reqId = uuidv4();
+
     if (msg.length > 160 && !config.do_not_trim_long_sms) {
         logger.verbose('Message trim to 160 chars');
         msg = msg.slice(0, 156) + ' ...';
     }
 
-    const handlerName = origin || config.default_modem;
+    const destinationNumber = modems.removeSuffixFromNumber(partner, config);
+
+    logger.verbose('Choosing handler name', { req_id: reqId, partner: partner, msg: msg, origin: origin });
+    let handlerName = ( await _getApproriateHandler(destinationNumber) );
 
     const modem = modems.getModemConfig(handlerName, config.modems);
     if (!modem) {
@@ -37,9 +84,6 @@ function send(partner, msg, origin) {
         return;
     }
 
-    const reqId = uuidv4();
-    const destinationNumber = modems.removeSuffixFromNumber(partner, config);
-
     const requestOptions = {
         url: modem.url,
         qs: {
@@ -50,7 +94,7 @@ function send(partner, msg, origin) {
         }
     }
 
-    logger.info('Sending message to modem handler', { req_id: reqId, partner: partner, destination_number: destinationNumber, msg: msg, handler_name: handlerName });
+    logger.info('Sending message to modem handler', { req_id: reqId, partner: partner, destination_number: destinationNumber, msg: msg, msg_length: msg.length, handler_name: handlerName });
     request(requestOptions, function(err, res, body) {
         if (err) {
             logger.warn('Error requesting to modem handler. ' + err.toString(), { req_id: reqId, handler_name: handlerName });
diff --git a/package.json b/package.json
index dd104a6..e3cb49e 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
     "express": "^4.17.1",
     "komodo-center-messaging-client-lib": "git+http://gitlab.kodesumber.com/komodo/komodo-center-messaging-client-lib.git",
     "komodo-sdk": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git",
+    "redis": "^2.8.0",
     "request": "^2.88.0",
     "uuid": "^3.3.2"
   },