diff --git a/wally/suits/io/fio_job.py b/wally/suits/io/fio_job.py
new file mode 100644
index 0000000..0f55e91
--- /dev/null
+++ b/wally/suits/io/fio_job.py
@@ -0,0 +1,183 @@
+import abc
+import copy
+from collections import OrderedDict
+from typing import Optional, Iterator, Union, Dict, Tuple, NamedTuple, Any, cast
+
+
+from ...utils import ssize2b, b2ssize
+from ..job import JobConfig, JobParams
+
+
+Var = NamedTuple('Var', [('name', str)])
+
+
+def is_fio_opt_true(vl: Union[str, int]) -> bool:
+    return str(vl).lower() in ['1', 'true', 't', 'yes', 'y']
+
+
+class FioJobParams(JobParams):
+    """Class contains all parameters, which significantly affects fio results.
+
+        oper - operation type - read/write/randread/...
+        sync_mode - direct/sync/async/direct+sync
+        bsize - block size in KiB
+        qd - IO queue depth,
+        thcount - thread count,
+        write_perc - write perc for mixed(read+write) loads
+
+    Like block size or operation type, but not file name or file size.
+    Can be used as key in dictionary.
+    """
+
+    sync2long = {'x': "sync direct",
+                 's': "sync",
+                 'd': "direct",
+                 'a': "buffered"}
+
+    @property
+    def sync_mode_long(self) -> str:
+        return self.sync2long[self['sync_mode']]
+
+    @property
+    def summary(self) -> str:
+        """Test short summary, used mostly for file names and short image description"""
+        res = "{0[oper]}{0[sync_mode]}{0[bsize]}".format(self)
+        if self['qd'] is not None:
+            res += "_qd" + str(self['qd'])
+        if self['thcount'] not in (1, None):
+            res += "th" + str(self['thcount'])
+        if self['write_perc'] is not None:
+            res += "wr" + str(self['write_perc'])
+        return res
+
+    @property
+    def long_summary(self) -> str:
+        """Readable long summary for management and deployment engineers"""
+        res = "{0[sync_mode_long]} {0[oper]} {1}".format(self, b2ssize(self['bsize'] * 1024))
+        if self['qd'] is not None:
+            res += " QD = " + str(self['qd'])
+        if self['thcount'] not in (1, None):
+            res += " threads={0[thcount]}".format(self)
+        if self['write_perc'] is not None:
+            res += " write_perc={0[write_perc]}%".format(self)
+        return res
+
+
+class FioJobConfig(JobConfig):
+    """Fio job configuration"""
+    ds2mode = {(True, True): 'x',
+               (True, False): 's',
+               (False, True): 'd',
+               (False, False): 'a'}
+
+    op_type2short = {"randread": "rr",
+                     "randwrite": "rw",
+                     "read": "sr",
+                     "write": "sw",
+                     "randrw": "rx"}
+
+    def __init__(self, name: str, idx: int) -> None:
+        JobConfig.__init__(self, idx)
+        self.name = name
+        self._sync_mode = None  # type: Optional[str]
+        self._params = None  # type: Optional[Dict[str, Any]]
+
+    # ------------- BASIC PROPERTIES -----------------------------------------------------------------------------------
+
+    @property
+    def write_perc(self) -> Optional[int]:
+        try:
+            return int(self.vals["rwmixwrite"])
+        except (KeyError, TypeError):
+            try:
+                return 100 - int(self.vals["rwmixread"])
+            except (KeyError, TypeError):
+                return None
+
+    @property
+    def qd(self) -> int:
+        return int(self.vals['iodepth'])
+
+    @property
+    def bsize(self) -> int:
+        bsize = ssize2b(self.vals['blocksize'])
+        assert bsize % 1024 == 0
+        return bsize // 1024
+
+    @property
+    def oper(self) -> str:
+        return self.vals['rw']
+
+    @property
+    def op_type_short(self) -> str:
+        return self.op_type2short[self.vals['rw']]
+
+    @property
+    def thcount(self) -> int:
+        return int(self.vals.get('numjobs', 1))
+
+    @property
+    def sync_mode(self) -> str:
+        if self._sync_mode is None:
+            direct = is_fio_opt_true(self.vals.get('direct', '0')) or \
+                     not is_fio_opt_true(self.vals.get('buffered', '0'))
+            sync = is_fio_opt_true(self.vals.get('sync', '0'))
+            self._sync_mode = self.ds2mode[(sync, direct)]
+        return cast(str, self._sync_mode)
+
+    # ----------- COMPLEX PROPERTIES -----------------------------------------------------------------------------------
+
+    @property
+    def params(self) -> JobParams:
+        if self._params is None:
+            self._params = dict(oper=self.oper,
+                                sync_mode=self.sync_mode,
+                                bsize=self.bsize,
+                                qd=self.qd,
+                                thcount=self.thcount,
+                                write_perc=self.write_perc)
+        return cast(JobParams, FioJobParams(**cast(Dict[str, Any], self._params)))
+
+    # ------------------------------------------------------------------------------------------------------------------
+
+    def __eq__(self, o: object) -> bool:
+        if not isinstance(o, FioJobConfig):
+            return False
+        return self.vals == cast(FioJobConfig, o).vals
+
+    def copy(self) -> 'FioJobConfig':
+        return copy.deepcopy(self)
+
+    def required_vars(self) -> Iterator[Tuple[str, Var]]:
+        for name, val in self.vals.items():
+            if isinstance(val, Var):
+                yield name, val
+
+    def is_free(self) -> bool:
+        return len(list(self.required_vars())) == 0
+
+    def __str__(self) -> str:
+        res = "[{0}]\n".format(self.params.summary)
+
+        for name, val in self.vals.items():
+            if name.startswith('_') or name == name.upper():
+                continue
+            if isinstance(val, Var):
+                res += "{0}={{{1}}}\n".format(name, val.name)
+            else:
+                res += "{0}={1}\n".format(name, val)
+
+        return res
+
+    def __repr__(self) -> str:
+        return str(self)
+
+    def raw(self) -> Dict[str, Any]:
+        res = super().raw()
+        res['vals'] = list(map(list, self.vals.items()))
+        return res
+
+    @classmethod
+    def fromraw(cls, data: Dict[str, Any]) -> 'FioJobConfig':
+        data['vals'] = OrderedDict(data['vals'])
+        return cast(FioJobConfig, super().fromraw(data))
