diff --git a/README.md b/README.md
index 14b7851e513c01b1abb2aa2d7ebe87e65db65b97..14b92b3dc3e8113bd39649063faccdb554e9ef2b 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,8 @@ Then copy your resulting wheel and install it via pip on the target system.
 
 ## v0.5.4
 
-* _TBA_
+* older TempsDB databases that do not support varlens will be updated upon opening
+* added metadata support for databases
 
 ## v0.5.3
 
diff --git a/setup.py b/setup.py
index fec8254ed6b8e951e880259d620d131124600f5a..df8396fcbc05b6f5982981b490db345323585c26 100644
--- a/setup.py
+++ b/setup.py
@@ -36,12 +36,13 @@ if 'CI' in os.environ:
     #     Extension('tempsdb.chunks.base', ['tempsdb/chunks/base.pyx']),
     # ]
     # ext_modules = cythonize(extensions, compiler_directives=directives)
-ext_modules = build([Multibuild('tempsdb', find_pyx('tempsdb'), **ext_kwargs), ],
+ext_modules = build([Multibuild('tempsdb', find_pyx('tempsdb'),
+                                **ext_kwargs), ],
                      compiler_directives=directives,
                      **cythonize_kwargs)
 
 setup(name='tempsdb',
-      version='0.5.4a1',
+      version='0.5.4a3',
       packages=find_packages(include=['tempsdb', 'tempsdb.*']),
       install_requires=['satella>=2.14.24', 'ujson'],
       ext_modules=ext_modules,
diff --git a/tempsdb/database.pxd b/tempsdb/database.pxd
index ddbabf8019970d97bf3dd86b70c91bcb990fed85..f835ad92adec06a30a795bea29d81de4b1c79aa7 100644
--- a/tempsdb/database.pxd
+++ b/tempsdb/database.pxd
@@ -10,7 +10,10 @@ cdef class Database:
         object mpm
         dict open_series
         dict open_varlen_series
+        readonly dict metadata
 
+    cpdef int reload_metadata(self) except -1
+    cpdef int set_metadata(self, dict meta) except -1
     cpdef int close(self) except -1
     cpdef TimeSeries get_series(self, str name,
                                 bint use_descriptor_based_access=*)
diff --git a/tempsdb/database.pyx b/tempsdb/database.pyx
index c74171da66f25da501d5707e95a3179620e4c47d..22a6f70ca916fe9123c8bbe8025f42e9e630e809 100644
--- a/tempsdb/database.pyx
+++ b/tempsdb/database.pyx
@@ -4,6 +4,7 @@ import threading
 import warnings
 
 from satella.coding import DictDeleter
+from satella.json import read_json_from_file, write_json_to_file
 
 from tempsdb.exceptions import DoesNotExist, AlreadyExists, StillOpen
 from .series cimport TimeSeries, create_series
@@ -23,16 +24,49 @@ cdef class Database:
     :raises DoesNotExist: database does not exist, use `create_database`
 
     :ivar path: path to  the directory with the database (str)
+    :ivar metadata: metadata of this DB
     """
     def __init__(self, path: str):
         if not os.path.isdir(path):
             raise DoesNotExist('Database does not exist')
+
+        if not os.path.isdir(os.path.join(path, 'varlen')):
+            os.mkdir(os.path.join(path, 'varlen'))
+
         self.path = path
         self.closed = False
         self.open_series = {}
         self.open_varlen_series = {}
         self.lock = threading.RLock()
         self.mpm = None
+        self.metadata = {}
+        self.reload_metadata()
+
+    cpdef int reload_metadata(self) except -1:
+        """
+        Try to load the metadata again.
+        
+        This will change `metadata` attribute.
+        """
+        self.metadata = {}
+        if os.path.isfile(os.path.join(self.path, 'metadata.txt')):
+            try:
+                self.metadata = read_json_from_file(os.path.join(self.path, 'metadata.txt')).get('metadata', {})
+            except ValueError:
+                pass
+        return 0
+
+    cpdef int set_metadata(self, dict metadata) except -1:
+        """
+        Set metadata for this series.
+        
+        This will change `metadata` attribute.
+        
+        :param metadata: new metadata to set
+        """
+        write_json_to_file(os.path.join(self.path, 'metadata.txt'), {'metadata': metadata})
+        self.metadata = metadata
+        return 0
 
     cpdef list get_open_series(self):
         """
@@ -282,7 +316,7 @@ cdef class Database:
         """
         Create a new series.
         
-        Note that series cannot be named "varlen"
+        Note that series cannot be named "varlen" or "metadata.txt"
         
         :param name: name of the series
         :param block_size: size of the data field
@@ -298,8 +332,8 @@ cdef class Database:
         """
         if block_size > page_size + 8:
             raise ValueError('Invalid block size, pick larger page')
-        if name == 'varlen':
-            raise ValueError('Series cannot be named varlen')
+        if name == 'varlen' or name == 'metadata.txt':
+            raise ValueError('Series cannot be named varlen or metadata.txt')
         if os.path.isdir(os.path.join(self.path, name)):
             raise AlreadyExists('Series already exists')
         cdef TimeSeries series
diff --git a/tests/test_database.py b/tests/test_database.py
index c46991e51c5020faf251201fe80c4532c82c2874..4fd9574c4b9b67d3b9efd28e4e6be7ffa3e0ecf4 100644
--- a/tests/test_database.py
+++ b/tests/test_database.py
@@ -9,6 +9,14 @@ class TestDatabase(unittest.TestCase):
     def setUpClass(cls) -> None:
         cls.db = create_database('my_db')
 
+    def test_metadata(self):
+        meta = self.db.metadata
+        self.assertFalse(self.db.metadata)
+        meta = {'hello': 'world'}
+        self.db.set_metadata(meta)
+        self.db.reload_metadata()
+        self.assertEqual(self.db.metadata, meta)
+
     def test_add_series(self):
         ser = self.db.create_series('hello-world', 1, 10)
         ser.append(10, b'\x00')
diff --git a/unittest.Dockerfile b/unittest.Dockerfile
index df003ba56a1d43a0af8acc8341e3f3e4950edea4..1877bb59be6caac9fea5604b8fd99f351f1a798c 100644
--- a/unittest.Dockerfile
+++ b/unittest.Dockerfile
@@ -1,6 +1,6 @@
 FROM python:3.8
 
-RUN pip install satella>=2.14.24 snakehouse nose2 wheel ujson coverage indexed_gzip
+RUN pip install satella>=2.14.24 snakehouse>=1.3 nose2 wheel ujson coverage
 
 ADD tempsdb /app/tempsdb
 ADD setup.py /app/setup.py