diff --git a/apps/assets/views/cluster.py b/apps/assets/views/cluster.py
index 835229fc1..5df58953c 100644
--- a/apps/assets/views/cluster.py
+++ b/apps/assets/views/cluster.py
@@ -60,11 +60,6 @@ class ClusterUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView)
     success_url = reverse_lazy('assets:cluster-list')
     success_message = update_success_msg
 
-    def form_valid(self, form):
-        cluster = form.save(commit=False)
-        cluster.save()
-        return super().form_valid(form)
-
     def get_context_data(self, **kwargs):
         context = {
             'app': _('assets'),
diff --git a/apps/common/forms.py b/apps/common/forms.py
index 073bb671f..ab3dadba3 100644
--- a/apps/common/forms.py
+++ b/apps/common/forms.py
@@ -4,7 +4,9 @@ import json
 
 from django import forms
 from django.utils.translation import ugettext_lazy as _
+from django.utils.html import escape
 from django.db import transaction
+from django.conf import settings
 
 from .models import Setting
 from .fields import DictField
@@ -30,28 +32,32 @@ def to_form_value(value):
 class BaseForm(forms.Form):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
-        settings = Setting.objects.all()
+        db_settings = Setting.objects.all()
         for name, field in self.fields.items():
-            db_value = getattr(settings, name).value
-            if db_value:
+            db_value = getattr(db_settings, name).value
+            django_value = getattr(settings, name) if hasattr(settings, name) else None
+            if db_value is not None:
                 field.initial = to_form_value(db_value)
+            elif django_value is not None:
+                field.initial = django_value
 
-    def save(self):
+    def save(self, category="default"):
         if not self.is_bound:
             raise ValueError("Form is not bound")
 
-        settings = Setting.objects.all()
+        db_settings = Setting.objects.all()
         if self.is_valid():
             with transaction.atomic():
                 for name, value in self.cleaned_data.items():
                     field = self.fields[name]
                     if isinstance(field.widget, forms.PasswordInput) and not value:
                         continue
-                    if value == to_form_value(getattr(settings, name).value):
+                    if value == to_form_value(getattr(db_settings, name).value):
                         continue
 
                     defaults = {
                         'name': name,
+                        'category': category,
                         'value': to_model_value(value)
                     }
                     Setting.objects.update_or_create(defaults=defaults, name=name)
@@ -129,3 +135,28 @@ class LDAPSettingForm(BaseForm):
     AUTH_LDAP_START_TLS = forms.BooleanField(
         label=_("Use SSL"), initial=False, required=False
     )
+
+
+class TerminalSettingForm(BaseForm):
+    SORT_BY_CHOICES = (
+        ('hostname', _('Hostname')),
+        ('ip', _('IP')),
+    )
+    TERMINAL_ASSET_LIST_SORT_BY = forms.ChoiceField(
+        choices=SORT_BY_CHOICES, initial='hostname', label=_("List sort by")
+    )
+    TERMINAL_HEARTBEAT_INTERVAL = forms.IntegerField(
+        initial=5, label=_("Heartbeat interval"), help_text=_("Units: seconds")
+    )
+    TERMINAL_PASSWORD_AUTH = forms.BooleanField(
+        initial=True, required=False, label=_("Password auth")
+    )
+    TERMINAL_PUBLIC_KEY_AUTH = forms.BooleanField(
+        initial=True, required=False, label=_("Public key auth")
+    )
+    TERMINAL_COMMAND_STORAGE = DictField(
+        label=_("Command storage"), help_text=_(
+            "Set terminal storage setting, `default` is the using as default,"
+            "You can set other storage and some terminal using"
+        )
+    )
diff --git a/apps/common/models.py b/apps/common/models.py
index 091b8b83a..afee1e13d 100644
--- a/apps/common/models.py
+++ b/apps/common/models.py
@@ -24,6 +24,7 @@ class SettingManager(models.Manager):
 class Setting(models.Model):
     name = models.CharField(max_length=128, unique=True, verbose_name=_("Name"))
     value = models.TextField(verbose_name=_("Value"))
+    category = models.CharField(max_length=128, default="default")
     enabled = models.BooleanField(verbose_name=_("Enabled"), default=True)
     comment = models.TextField(verbose_name=_("Comment"))
 
@@ -33,12 +34,20 @@ class Setting(models.Model):
         return self.name
 
     @property
-    def value_(self):
+    def cleaned_value(self):
         try:
             return json.loads(self.value)
         except json.JSONDecodeError:
             return None
 
+    @cleaned_value.setter
+    def cleaned_value(self, item):
+        try:
+            v = json.dumps(item)
+            self.value = v
+        except json.JSONDecodeError as e:
+            raise ValueError("Json dump error: {}".format(str(e)))
+
     @classmethod
     def refresh_all_settings(cls):
         settings_list = cls.objects.all()
@@ -53,9 +62,9 @@ class Setting(models.Model):
         setattr(settings, self.name, value)
 
         if self.name == "AUTH_LDAP":
-            if self.value_ and settings.AUTH_LDAP_BACKEND not in settings.AUTHENTICATION_BACKENDS:
+            if self.cleaned_value and settings.AUTH_LDAP_BACKEND not in settings.AUTHENTICATION_BACKENDS:
                 settings.AUTHENTICATION_BACKENDS.insert(0, settings.AUTH_LDAP_BACKEND)
-            elif not self.value_ and settings.AUTH_LDAP_BACKEND in settings.AUTHENTICATION_BACKENDS:
+            elif not self.cleaned_value and settings.AUTH_LDAP_BACKEND in settings.AUTHENTICATION_BACKENDS:
                 settings.AUTHENTICATION_BACKENDS.remove(settings.AUTH_LDAP_BACKEND)
 
         if self.name == "AUTH_LDAP_SEARCH_FILTER":
diff --git a/apps/common/templates/common/_add_terminal_command_storage_modal.html b/apps/common/templates/common/_add_terminal_command_storage_modal.html
new file mode 100644
index 000000000..678152981
--- /dev/null
+++ b/apps/common/templates/common/_add_terminal_command_storage_modal.html
@@ -0,0 +1,21 @@
+{% extends '_modal.html' %}
+{% load i18n %}
+{% block modal_id %}add_command_storage_model{% endblock %}
+{% block modal_title%}{% trans "Add command storage" %}{% endblock %}
+{% block modal_body %}
+<form method="post" action="" id="add_command_storage_form">
+    {% csrf_token %}
+    <div class="form-group">
+        <label class="control-label" for="id_assets">{% trans "Template" %}</label>
+        <a href="{% url 'assets:asset-export' %}" style="display: block">{% trans 'Download' %}</a>
+    </div>
+    <div class="form-group">
+        <label class="control-label" for="id_users">{% trans "Asset csv file" %}</label>
+        <input id="id_assets" type="file" name="file" />
+        <span class="help-block red-fonts">
+            {% trans 'If set id, will use this id update asset existed' %}
+        </span>
+    </div>
+</form>
+{% endblock %}
+{% block modal_confirm_id %}btn_asset_import{% endblock %}
diff --git a/apps/common/templates/common/basic_setting.html b/apps/common/templates/common/basic_setting.html
index 9d67d762d..496eca977 100644
--- a/apps/common/templates/common/basic_setting.html
+++ b/apps/common/templates/common/basic_setting.html
@@ -21,7 +21,7 @@
                                 <a href="{% url 'settings:ldap-setting' %}" class="text-center"><i class="fa fa-archive"></i> {% trans 'LDAP setting' %} </a>
                             </li>
                             <li>
-                                <a href="{% url 'settings:storage-setting' %}" class="text-center"><i class="fa fa-hdd-o"></i> {% trans 'Storage setting' %} </a>
+                                <a href="{% url 'settings:terminal-setting' %}" class="text-center"><i class="fa fa-hdd-o"></i> {% trans 'Terminal setting' %} </a>
                             </li>
                         </ul>
                     </div>
diff --git a/apps/common/templates/common/email_setting.html b/apps/common/templates/common/email_setting.html
index 2cd018021..1fd772db1 100644
--- a/apps/common/templates/common/email_setting.html
+++ b/apps/common/templates/common/email_setting.html
@@ -21,7 +21,7 @@
                                 <a href="{% url 'settings:ldap-setting' %}" class="text-center"><i class="fa fa-archive"></i> {% trans 'LDAP setting' %} </a>
                             </li>
                             <li>
-                                <a href="{% url 'settings:storage-setting' %}" class="text-center"><i class="fa fa-hdd-o"></i> {% trans 'Storage setting' %} </a>
+                                <a href="{% url 'settings:terminal-setting' %}" class="text-center"><i class="fa fa-hdd-o"></i> {% trans 'Terminal setting' %} </a>
                             </li>
                         </ul>
                     </div>
diff --git a/apps/common/templates/common/ldap_setting.html b/apps/common/templates/common/ldap_setting.html
index de4a196c9..f0569f873 100644
--- a/apps/common/templates/common/ldap_setting.html
+++ b/apps/common/templates/common/ldap_setting.html
@@ -21,7 +21,7 @@
                                 <a href="{% url 'settings:ldap-setting' %}" class="text-center"><i class="fa fa-archive"></i> {% trans 'LDAP setting' %} </a>
                             </li>
                             <li>
-                                <a href="{% url 'settings:storage-setting' %}" class="text-center"><i class="fa fa-hdd-o"></i> {% trans 'Storage setting' %} </a>
+                                <a href="{% url 'settings:terminal-setting' %}" class="text-center"><i class="fa fa-hdd-o"></i> {% trans 'Terminal setting' %} </a>
                             </li>
                         </ul>
                     </div>
diff --git a/apps/common/templates/common/storage_setting.html b/apps/common/templates/common/terminal_setting.html
similarity index 63%
rename from apps/common/templates/common/storage_setting.html
rename to apps/common/templates/common/terminal_setting.html
index cf2c243f1..3d0b7eb6f 100644
--- a/apps/common/templates/common/storage_setting.html
+++ b/apps/common/templates/common/terminal_setting.html
@@ -21,7 +21,7 @@
                                 <a href="{% url 'settings:ldap-setting' %}" class="text-center"><i class="fa fa-archive"></i> {% trans 'LDAP setting' %} </a>
                             </li>
                             <li class="active">
-                                <a href="{% url 'settings:storage-setting' %}" class="text-center"><i class="fa fa-hdd-o"></i> {% trans 'Storage setting' %} </a>
+                                <a href="{% url 'settings:terminal-setting' %}" class="text-center"><i class="fa fa-hdd-o"></i> {% trans 'Terminal setting' %} </a>
                             </li>
                         </ul>
                     </div>
@@ -35,26 +35,50 @@
                                          </div>
                                     {% endif %}
                                     {% csrf_token %}
+                                    <h3>{% trans "Basic setting" %}</h3>
+                                    {% for field in form %}
+                                        {% if not field.field|is_bool_field %}
+                                            {% bootstrap_field field layout="horizontal" %}
+                                        {% else %}
+                                            <div class="form-group">
+                                                <label for="{{ field.id_for_label }}" class="col-sm-2 control-label">{{ field.label }}</label>
+                                                <div class="col-sm-8">
+                                                    <div class="col-sm-1">
+                                                        {{ field }}
+                                                    </div>
+                                                    <div class="col-sm-9">
+                                                        <span class="help-block" >{{ field.help_text }}</span>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        {% endif %}
+                                    {% endfor %}
+
+                                    <div class="hr-line-dashed"></div>
                                     <h3>{% trans "Command storage" %}</h3>
                                     <table class="table table-hover " id="task-history-list-table" >
                                         <thead>
                                             <tr>
                                                 <th>{% trans 'Name' %}</th>
-                                                <th>{% trans 'Engine' %}</th>
-                                                <th>{% trans 'Action' %}</th>
+                                                <th>{% trans 'Type' %}</th>
                                             </tr>
                                         </thead>
                                         <tbody>
+                                        {% for name, setting in command_storage.items %}
+                                            <tr>
+                                                <td>{{ name }}</td>
+                                                <td>{{ setting.TYPE }}</td>
+                                            </tr>
+                                        {% endfor %}
                                         </tbody>
                                     </table>
-
+{#                                    <button class="btn btn-default btn-circle btn-add-command-storage" data-toggle="modal" data-target="#add_command_storage_model" tabindex="0" type="button"><i class="fa fa-plus"></i></button>#}
                                     <div class="hr-line-dashed"></div>
                                     <h3>{% trans "Replay storage" %}</h3>
 
                                     <div class="hr-line-dashed"></div>
                                     <div class="form-group">
                                         <div class="col-sm-4 col-sm-offset-2">
-                                            <button class="btn btn-default btn-test" type="button"> {% trans 'Test connection' %}</button>
                                             <button class="btn btn-default" type="reset"> {% trans 'Reset' %}</button>
                                             <button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
                                         </div>
@@ -68,6 +92,7 @@
             </div>
         </div>
     </div>
+    {% include 'common/_add_terminal_command_storage_modal.html' %}
 {% endblock %}
 {% block custom_foot_js %}
 <script>
@@ -97,6 +122,9 @@ $(document).ready(function () {
         success: success,
         error: error
     });
+})
+.on('click', '', function () {
+
 })
 </script>
 {% endblock %}
diff --git a/apps/common/urls/view_urls.py b/apps/common/urls/view_urls.py
index 57594b043..466f7c49c 100644
--- a/apps/common/urls/view_urls.py
+++ b/apps/common/urls/view_urls.py
@@ -10,5 +10,5 @@ urlpatterns = [
     url(r'^$', views.BasicSettingView.as_view(), name='basic-setting'),
     url(r'^email/$', views.EmailSettingView.as_view(), name='email-setting'),
     url(r'^ldap/$', views.LDAPSettingView.as_view(), name='ldap-setting'),
-    url(r'^storage/$', views.StorageSettingView.as_view(), name='storage-setting'),
+    url(r'^terminal/$', views.TerminalSettingView.as_view(), name='terminal-setting'),
 ]
diff --git a/apps/common/views.py b/apps/common/views.py
index 6ab46ead4..8e7dc8341 100644
--- a/apps/common/views.py
+++ b/apps/common/views.py
@@ -1,9 +1,11 @@
-from django.views.generic import View, TemplateView
+from django.views.generic import TemplateView
 from django.shortcuts import render, redirect
 from django.contrib import messages
 from django.utils.translation import ugettext as _
+from django.conf import settings
 
-from .forms import EmailSettingForm, LDAPSettingForm, BasicSettingForm
+from .forms import EmailSettingForm, LDAPSettingForm, BasicSettingForm, \
+    TerminalSettingForm
 from .models import Setting
 from .mixins import AdminUserRequiredMixin
 from .signals import ldap_auth_enable
@@ -89,27 +91,29 @@ class LDAPSettingView(AdminUserRequiredMixin, TemplateView):
             return render(request, self.template_name, context)
 
 
-class StorageSettingView(AdminUserRequiredMixin, TemplateView):
-    form_class = LDAPSettingForm
-    template_name = "common/storage_setting.html"
+class TerminalSettingView(AdminUserRequiredMixin, TemplateView):
+    form_class = TerminalSettingForm
+    template_name = "common/terminal_setting.html"
 
     def get_context_data(self, **kwargs):
+        command_storage = settings.TERMINAL_COMMAND_STORAGE
         context = {
             'app': _('Settings'),
-            'action': _('Storage setting'),
+            'action': _('Terminal setting'),
             'form': self.form_class(),
-            'command_storage': Setting.objects.filter(name__endswith="_COMMAND_STORAGE")
+            'command_storage': command_storage,
         }
         kwargs.update(context)
         return super().get_context_data(**kwargs)
 
     def post(self, request):
+        print(request.POST)
         form = self.form_class(request.POST)
         if form.is_valid():
             form.save()
             msg = _("Update setting successfully, please restart program")
             messages.success(request, msg)
-            return redirect('settings:storage-setting')
+            return redirect('settings:terminal-setting')
         else:
             context = self.get_context_data()
             context.update({"form": form})
diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py
index 7a8aa422e..d023b587a 100644
--- a/apps/jumpserver/settings.py
+++ b/apps/jumpserver/settings.py
@@ -373,7 +373,23 @@ CAPTCHA_FOREGROUND_COLOR = '#001100'
 CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_dots',)
 CAPTCHA_TEST_MODE = CONFIG.CAPTCHA_TEST_MODE
 
-COMMAND_STORAGE_BACKEND = 'terminal.backends.command.db'
+COMMAND_STORAGE = {
+    'ENGINE': 'terminal.backends.command.db',
+}
+
+TERMINAL_COMMAND_STORAGE = {
+    'default': {
+        'TYPE': 'server',
+    },
+    # 'ali-es': {
+    #     'TYPE': 'elasticsearch',
+    #     'HOSTS': ['http://elastic:changeme@localhost:9200'],
+    # },
+    # 'ali-hz-es': {
+    #     'TYPE': 'elasticsearch',
+    #     'HOSTS': ['http://elastic:changeme@localhost:9200'],
+    # }
+}
 
 # Django bootstrap3 setting, more see http://django-bootstrap3.readthedocs.io/en/latest/settings.html
 BOOTSTRAP3 = {
diff --git a/apps/terminal/api.py b/apps/terminal/api.py
index 87311d5b2..e587d8928 100644
--- a/apps/terminal/api.py
+++ b/apps/terminal/api.py
@@ -21,7 +21,7 @@ from .serializers import TerminalSerializer, StatusSerializer, \
     SessionSerializer, TaskSerializer, ReplaySerializer
 from .hands import IsSuperUserOrAppUser, IsAppUser, \
     IsSuperUserOrAppUserOrUserReadonly
-from .backends import get_command_store, SessionCommandSerializer
+from .backends import get_terminal_command_store, SessionCommandSerializer
 
 logger = logging.getLogger(__file__)
 
@@ -196,7 +196,7 @@ class CommandViewSet(viewsets.ViewSet):
     }
 
     """
-    command_store = get_command_store()
+    command_store = get_terminal_command_store()
     serializer_class = SessionCommandSerializer
     permission_classes = (IsSuperUserOrAppUser,)
 
@@ -260,3 +260,10 @@ class SessionReplayViewSet(viewsets.ViewSet):
             return redirect(url)
         else:
             return HttpResponseNotFound()
+
+
+class LoadConfig(APIView):
+    permission_classes = (IsAppUser,)
+
+    def get(self, request):
+        pass
diff --git a/apps/terminal/backends/__init__.py b/apps/terminal/backends/__init__.py
index 6baaed3c4..8b09f0c55 100644
--- a/apps/terminal/backends/__init__.py
+++ b/apps/terminal/backends/__init__.py
@@ -2,9 +2,33 @@ from importlib import import_module
 from django.conf import settings
 from .command.serializers import SessionCommandSerializer
 
+TYPE_ENGINE_MAPPING = {
+    'elasticsearch': 'terminal.backends.command.db',
+}
+
 
 def get_command_store():
-    command_engine = import_module(settings.COMMAND_STORAGE_BACKEND)
-    command_store = command_engine.CommandStore()
-    return command_store
+    params = settings.COMMAND_STORAGE
+    engine_class = import_module(params['ENGINE'])
+    storage = engine_class.CommandStore(params)
+    return storage
+
+
+def get_terminal_command_store():
+    storage_list = {}
+    for name, params in settings.TERMINAL_COMMAND_STORAGE.items():
+        tp = params['TYPE']
+        if tp == 'server':
+            storage = get_command_store()
+        else:
+            if not TYPE_ENGINE_MAPPING.get(tp):
+                raise AssertionError("Command storage type should in {}".format(
+                    ', '.join(TYPE_ENGINE_MAPPING.keys()))
+                )
+            engine_class = import_module(TYPE_ENGINE_MAPPING[tp])
+            storage = engine_class.CommandStore(params)
+        storage_list[name] = storage
+    return storage_list
+
+
 
diff --git a/apps/terminal/backends/command/base.py b/apps/terminal/backends/command/base.py
index 0aa689738..585930a5d 100644
--- a/apps/terminal/backends/command/base.py
+++ b/apps/terminal/backends/command/base.py
@@ -19,3 +19,9 @@ class CommandBase(object):
                input=None, session=None):
         pass
 
+    @abc.abstractmethod
+    def count(self, date_from=None, date_to=None,
+               user=None, asset=None, system_user=None,
+               input=None, session=None):
+        pass
+
diff --git a/apps/terminal/backends/command/db.py b/apps/terminal/backends/command/db.py
index 27ee19a14..85b99ce80 100644
--- a/apps/terminal/backends/command/db.py
+++ b/apps/terminal/backends/command/db.py
@@ -8,7 +8,7 @@ from .base import CommandBase
 
 class CommandStore(CommandBase):
 
-    def __init__(self):
+    def __init__(self, params):
         from terminal.models import Command
         self.model = Command
 
@@ -37,9 +37,11 @@ class CommandStore(CommandBase):
             ))
         return self.model.objects.bulk_create(_commands)
 
-    def filter(self, date_from=None, date_to=None,
-               user=None, asset=None, system_user=None,
-               input=None, session=None):
+    @staticmethod
+    def make_filter_kwargs(
+            date_from=None, date_to=None,
+            user=None, asset=None, system_user=None,
+            input=None, session=None):
         filter_kwargs = {}
         date_from_default = timezone.now() - datetime.timedelta(days=7)
         date_to_default = timezone.now()
@@ -60,10 +62,28 @@ class CommandStore(CommandBase):
         if session:
             filter_kwargs['session'] = session
 
+        return filter_kwargs
+
+    def filter(self, date_from=None, date_to=None,
+               user=None, asset=None, system_user=None,
+               input=None, session=None):
+        filter_kwargs = self.make_filter_kwargs(
+            date_from=date_from, date_to=date_to, user=user,
+            asset=asset, system_user=system_user, input=input,
+            session=session,
+        )
         queryset = self.model.objects.filter(**filter_kwargs)
         return queryset
 
-    def all(self):
-        """返回所有数据"""
-        return self.model.objects.iterator()
+    def count(self, date_from=None, date_to=None,
+               user=None, asset=None, system_user=None,
+               input=None, session=None):
+        filter_kwargs = self.make_filter_kwargs(
+            date_from=date_from, date_to=date_to, user=user,
+            asset=asset, system_user=system_user, input=input,
+            session=session,
+        )
+        count = self.model.objects.filter(**filter_kwargs).count()
+        return count
+
 
diff --git a/apps/terminal/backends/command/models.py b/apps/terminal/backends/command/models.py
index 2d1387427..cc0d375e6 100644
--- a/apps/terminal/backends/command/models.py
+++ b/apps/terminal/backends/command/models.py
@@ -18,5 +18,20 @@ class AbstractSessionCommand(models.Model):
     class Meta:
         abstract = True
 
+    @classmethod
+    def from_dict(cls, d):
+        self = cls()
+        for k, v in d.items():
+            setattr(self, k, v)
+        return self
+
+    @classmethod
+    def from_multi_dict(cls, l):
+        commands = []
+        for d in l:
+            command = cls.from_dict(d)
+            commands.append(command)
+        return commands
+
     def __str__(self):
         return self.input
diff --git a/apps/terminal/forms.py b/apps/terminal/forms.py
index 5b6278c02..4253da70a 100644
--- a/apps/terminal/forms.py
+++ b/apps/terminal/forms.py
@@ -10,7 +10,7 @@ from .models import Terminal
 class TerminalForm(forms.ModelForm):
     class Meta:
         model = Terminal
-        fields = ['name', 'remote_addr', 'ssh_port', 'http_port', 'comment']
+        fields = ['name', 'remote_addr', 'ssh_port', 'http_port', 'comment', 'command_storage']
         help_texts = {
             'ssh_port': _("Coco ssh listen port"),
             'http_port': _("Coco http/ws listen port"),
diff --git a/apps/terminal/models.py b/apps/terminal/models.py
index f545baa5f..b8524f727 100644
--- a/apps/terminal/models.py
+++ b/apps/terminal/models.py
@@ -4,17 +4,27 @@ import uuid
 
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
+from django.conf import settings
 
 from users.models import User
 from .backends.command.models import AbstractSessionCommand
 
 
+def get_all_command_storage():
+    storage_choices = []
+    for k, v in settings.TERMINAL_COMMAND_STORAGE.items():
+        storage_choices.append((k, k))
+    return storage_choices
+
+
 class Terminal(models.Model):
     id = models.UUIDField(default=uuid.uuid4, primary_key=True)
     name = models.CharField(max_length=32, verbose_name=_('Name'))
     remote_addr = models.CharField(max_length=128, verbose_name=_('Remote Address'))
     ssh_port = models.IntegerField(verbose_name=_('SSH Port'), default=2222)
     http_port = models.IntegerField(verbose_name=_('HTTP Port'), default=5000)
+    command_storage = models.CharField(max_length=128, verbose_name=_("Command storage"), default='default', choices=get_all_command_storage())
+    replay_storage = models.CharField(max_length=128, verbose_name=_("Replay storage"), default='default')
     user = models.OneToOneField(User, related_name='terminal', verbose_name='Application User', null=True, on_delete=models.CASCADE)
     is_accepted = models.BooleanField(default=False, verbose_name='Is Accepted')
     is_deleted = models.BooleanField(default=False)
@@ -33,6 +43,16 @@ class Terminal(models.Model):
             self.user.is_active = active
             self.user.save()
 
+    def get_common_storage(self):
+        pass
+
+    def get_replay_storage(self):
+        pass
+
+    @property
+    def config(self):
+        return
+
     def create_app_user(self):
         random = uuid.uuid4().hex[:6]
         user, access_key = User.create_app_user(name="{}-{}".format(self.name, random), comment=self.comment)
diff --git a/apps/terminal/serializers.py b/apps/terminal/serializers.py
index 52b4d2b3c..ecea7edfd 100644
--- a/apps/terminal/serializers.py
+++ b/apps/terminal/serializers.py
@@ -5,7 +5,7 @@ from django.utils import timezone
 from rest_framework import serializers
 
 from .models import Terminal, Status, Session, Task
-from .backends import get_command_store
+from .backends import get_terminal_command_store
 
 
 class TerminalSerializer(serializers.ModelSerializer):
@@ -43,7 +43,7 @@ class TerminalSerializer(serializers.ModelSerializer):
 
 class SessionSerializer(serializers.ModelSerializer):
     command_amount = serializers.SerializerMethodField()
-    command_store = get_command_store()
+    command_store = get_terminal_command_store()
 
     class Meta:
         model = Session
diff --git a/apps/terminal/templates/terminal/terminal_modal_accept.html b/apps/terminal/templates/terminal/terminal_modal_accept.html
index b4a18b17c..fe70bb342 100644
--- a/apps/terminal/templates/terminal/terminal_modal_accept.html
+++ b/apps/terminal/templates/terminal/terminal_modal_accept.html
@@ -12,6 +12,7 @@
     {% bootstrap_field form.remote_addr layout="horizontal" %}
     {% bootstrap_field form.ssh_port layout="horizontal" %}
     {% bootstrap_field form.http_port layout="horizontal" %}
+    {% bootstrap_field form.command_storage layout="horizontal" %}
     {% bootstrap_field form.comment layout="horizontal" %}
 </form>
 
diff --git a/apps/terminal/templates/terminal/terminal_update.html b/apps/terminal/templates/terminal/terminal_update.html
index 9ebd9d2d8..cbf745608 100644
--- a/apps/terminal/templates/terminal/terminal_update.html
+++ b/apps/terminal/templates/terminal/terminal_update.html
@@ -35,6 +35,7 @@
                             {% bootstrap_field form.remote_addr layout="horizontal" %}
                             {% bootstrap_field form.ssh_port layout="horizontal" %}
                             {% bootstrap_field form.http_port layout="horizontal" %}
+                            {% bootstrap_field form.command_storage layout="horizontal" %}
 
                             <div class="hr-line-dashed"></div>
                             <h3>{% trans 'Other' %}</h3>
diff --git a/apps/terminal/templatetags/terminal_tags.py b/apps/terminal/templatetags/terminal_tags.py
index 22b517880..72822b00a 100644
--- a/apps/terminal/templatetags/terminal_tags.py
+++ b/apps/terminal/templatetags/terminal_tags.py
@@ -1,13 +1,15 @@
 # ~*~ coding: utf-8 ~*~
 
 from django import template
-from ..backends import get_command_store
+from ..backends import get_terminal_command_store
 
 register = template.Library()
-command_store = get_command_store()
+command_store_dict = get_terminal_command_store()
 
 
 @register.filter
 def get_session_command_amount(session_id):
-    return len(command_store.filter(session=str(session_id)))
-
+    amount = 0
+    for name, store in command_store_dict.items():
+        amount += store.count(session=str(session_id))
+    return amount
diff --git a/apps/terminal/views/command.py b/apps/terminal/views/command.py
index 8b0479d3e..79b2eb2cc 100644
--- a/apps/terminal/views/command.py
+++ b/apps/terminal/views/command.py
@@ -9,10 +9,10 @@ from django.utils.translation import ugettext as _
 from common.mixins import DatetimeSearchMixin
 from ..models import Command
 from .. import utils
-from ..backends import get_command_store
+from ..backends import get_terminal_command_store
 
 __all__ = ['CommandListView']
-command_store = get_command_store()
+command_store_list = get_terminal_command_store()
 
 
 class CommandListView(DatetimeSearchMixin, ListView):
@@ -39,7 +39,10 @@ class CommandListView(DatetimeSearchMixin, ListView):
             filter_kwargs['system_user'] = self.system_user
         if self.command:
             filter_kwargs['input'] = self.command
-        queryset = command_store.filter(**filter_kwargs)
+        queryset = []
+        for store in command_store_list:
+            queryset.extend(store.filter(**filter_kwargs))
+        queryset = sorted(queryset, key=lambda c: c.timestamp, reverse=True)
         return queryset
 
     def get_context_data(self, **kwargs):
diff --git a/apps/terminal/views/session.py b/apps/terminal/views/session.py
index 22d04fbaf..63fcf5eb7 100644
--- a/apps/terminal/views/session.py
+++ b/apps/terminal/views/session.py
@@ -10,7 +10,7 @@ from django.conf import settings
 from users.utils import AdminUserRequiredMixin
 from common.mixins import DatetimeSearchMixin
 from ..models import Session, Command, Terminal
-from ..backends import get_command_store
+from ..backends import get_terminal_command_store
 from .. import utils
 
 
@@ -19,7 +19,7 @@ __all__ = [
     'SessionDetailView',
 ]
 
-command_store = get_command_store()
+command_store = get_terminal_command_store()
 
 
 class SessionListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):