diff --git a/hive/db/schema.py b/hive/db/schema.py
index a536fbcef3e4bba85833c1b796d7ad94590a425d..7061ebd9b2ea14bef29c6b123bc7ff410a7dfefd 100644
--- a/hive/db/schema.py
+++ b/hive/db/schema.py
@@ -10,7 +10,8 @@ from sqlalchemy.types import BOOLEAN
 
 #pylint: disable=line-too-long, too-many-lines, bad-whitespace
 
-DB_VERSION = 17
+# [DK] we changed and removed some tables so i upgraded DB_VERSION to 18
+DB_VERSION = 18
 
 def build_metadata():
     """Build schema def with SqlAlchemy"""
@@ -72,9 +73,9 @@ def build_metadata():
         'hive_posts', metadata,
         sa.Column('id', sa.Integer, primary_key=True),
         sa.Column('parent_id', sa.Integer),
-        sa.Column('author', VARCHAR(16), nullable=False),
-        sa.Column('permlink', VARCHAR(255), nullable=False),
-        sa.Column('category', VARCHAR(255), nullable=False, server_default=''),
+        sa.Column('author_id', sa.Integer, nullable=False),
+        sa.Column('permlink_id', sa.Integer, nullable=False),
+        sa.Column('category_id', sa.Integer, nullable=False),
         sa.Column('community_id', sa.Integer, nullable=True),
         sa.Column('created_at', sa.DateTime, nullable=False),
         sa.Column('depth', SMALLINT, nullable=False),
@@ -84,13 +85,74 @@ def build_metadata():
         sa.Column('is_valid', BOOLEAN, nullable=False, server_default='1'),
         sa.Column('promoted', sa.types.DECIMAL(10, 3), nullable=False, server_default='0'),
 
-        sa.ForeignKeyConstraint(['author'], ['hive_accounts.name'], name='hive_posts_fk1'),
+        sa.Column('children', SMALLINT, nullable=False, server_default='0'),
+
+        # basic/extended-stats
+        sa.Column('author_rep', sa.Float(precision=6), nullable=False, server_default='0'),
+        sa.Column('flag_weight', sa.Float(precision=6), nullable=False, server_default='0'),
+        sa.Column('total_votes', sa.Integer, nullable=False, server_default='0'),
+        sa.Column('up_votes', sa.Integer, nullable=False, server_default='0'),
+
+        # core stats/indexes
+        sa.Column('payout', sa.types.DECIMAL(10, 3), nullable=False, server_default='0'),
+        sa.Column('payout_at', sa.DateTime, nullable=False, server_default='1990-01-01'),
+        sa.Column('updated_at', sa.DateTime, nullable=False, server_default='1990-01-01'),
+        sa.Column('is_paidout', BOOLEAN, nullable=False, server_default='0'),
+
+        # ui flags/filters
+        sa.Column('is_nsfw', BOOLEAN, nullable=False, server_default='0'),
+        sa.Column('is_declined', BOOLEAN, nullable=False, server_default='0'),
+        sa.Column('is_full_power', BOOLEAN, nullable=False, server_default='0'),
+        sa.Column('is_hidden', BOOLEAN, nullable=False, server_default='0'),
+        sa.Column('is_grayed', BOOLEAN, nullable=False, server_default='0'),
+
+        # important indexes
+        sa.Column('rshares', sa.BigInteger, nullable=False, server_default='0'),
+        sa.Column('sc_trend', sa.Float(precision=6), nullable=False, server_default='0'),
+        sa.Column('sc_hot', sa.Float(precision=6), nullable=False, server_default='0'),
+
+        sa.Column('parent_author_id', sa.Integer, nullable=False),
+        sa.Column('parent_permlink_id', sa.Integer, nullable=False),
+        sa.Column('curator_payout_value', sa.String(16), nullable=False, server_default=''),
+        sa.Column('root_author_id', sa.Integer, nullable=False),
+        sa.Column('root_permlink_id', sa.Integer, nullable=False),
+        sa.Column('max_accepted_payout',  sa.String(16), nullable=False, server_default=''),
+        sa.Column('percent_steem_dollars', sa.Integer, nullable=False, server_default='-1'),
+        sa.Column('allow_replies', BOOLEAN, nullable=False, server_default='1'),
+        sa.Column('allow_votes', BOOLEAN, nullable=False, server_default='1'),
+        sa.Column('allow_curation_rewards', BOOLEAN, nullable=False, server_default='1'),
+        sa.Column('beneficiaries', sa.JSON, nullable=False, server_default='[]'),
+        sa.Column('url', sa.Text, nullable=False, server_default=''),
+        sa.Column('root_title', sa.String(255), nullable=False, server_default=''),
+
+        sa.ForeignKeyConstraint(['author_id'], ['hive_accounts.id'], name='hive_posts_fk1'),
         sa.ForeignKeyConstraint(['parent_id'], ['hive_posts.id'], name='hive_posts_fk3'),
-        sa.UniqueConstraint('author', 'permlink', name='hive_posts_ux1'),
-        sa.Index('hive_posts_ix3', 'author', 'depth', 'id', postgresql_where=sql_text("is_deleted = '0'")), # API: author blog/comments
-        sa.Index('hive_posts_ix4', 'parent_id', 'id', postgresql_where=sql_text("is_deleted = '0'")), # API: fetching children
-        sa.Index('hive_posts_ix5', 'id', postgresql_where=sql_text("is_pinned = '1' AND is_deleted = '0'")), # API: pinned post status
-        sa.Index('hive_posts_ix6', 'community_id', 'id', postgresql_where=sql_text("community_id IS NOT NULL AND is_pinned = '1' AND is_deleted = '0'")), # API: community pinned
+        sa.UniqueConstraint('author_id', 'permlink_id', name='hive_posts_ux1'),
+    )
+
+    sa.Table(
+        'hive_post_data', metadata,
+        sa.column('id', sa.Integer, nullable=False),
+        sa.column('title', VARCHAR(255), nullable=False),
+        sa.column('preview', VARCHAR(1024), nullable=False),
+        sa.column('img_url', VARCHAR(1024), nullable=False),
+        sa.Column('body', TEXT),
+        sa.Column('votes', TEXT),
+        sa.Column('json', sa.JSON)
+    )
+
+    sa.Table(
+        'hive_permlink_data', metadata,
+        sa.column('id', sa.Integer, primary_key=True),
+        sa.column('permlink', sa.String(255), nullable=False),
+        sa.UniqueConstraint('permlink', name='hive_permlink_data_permlink')
+    )
+
+    sa.Table(
+        'hive_category_data', metadata,
+        sa.column('id', sa.Integer, primary_key=True),
+        sa.column('category', sa.String(255), nullable=False),
+        sa.UniqueConstraint('category', name='hive_category_data_category')
     )
 
     sa.Table(
@@ -150,100 +212,6 @@ def build_metadata():
         sa.Index('hive_feed_cache_ix1', 'account_id', 'post_id', 'created_at'), # API (and rebuild?)
     )
 
-    sa.Table(
-        'hive_posts_cache', metadata,
-        sa.Column('post_id', sa.Integer, primary_key=True, autoincrement=False),
-        sa.Column('author', VARCHAR(16), nullable=False),
-        sa.Column('permlink', VARCHAR(255), nullable=False),
-        sa.Column('category', VARCHAR(255), nullable=False, server_default=''),
-
-        # important/index
-        sa.Column('community_id', sa.Integer, nullable=True),
-        sa.Column('depth', SMALLINT, nullable=False, server_default='0'),
-        sa.Column('children', SMALLINT, nullable=False, server_default='0'),
-
-        # basic/extended-stats
-        sa.Column('author_rep', sa.Float(precision=6), nullable=False, server_default='0'),
-        sa.Column('flag_weight', sa.Float(precision=6), nullable=False, server_default='0'),
-        sa.Column('total_votes', sa.Integer, nullable=False, server_default='0'),
-        sa.Column('up_votes', sa.Integer, nullable=False, server_default='0'),
-
-        # basic ui fields
-        sa.Column('title', sa.String(255), nullable=False, server_default=''),
-        sa.Column('preview', sa.String(1024), nullable=False, server_default=''),
-        sa.Column('img_url', sa.String(1024), nullable=False, server_default=''),
-
-        # core stats/indexes
-        sa.Column('payout', sa.types.DECIMAL(10, 3), nullable=False, server_default='0'),
-        sa.Column('promoted', sa.types.DECIMAL(10, 3), nullable=False, server_default='0'),
-        sa.Column('created_at', sa.DateTime, nullable=False, server_default='1990-01-01'),
-        sa.Column('payout_at', sa.DateTime, nullable=False, server_default='1990-01-01'),
-        sa.Column('updated_at', sa.DateTime, nullable=False, server_default='1990-01-01'),
-        sa.Column('is_paidout', BOOLEAN, nullable=False, server_default='0'),
-
-        # ui flags/filters
-        sa.Column('is_nsfw', BOOLEAN, nullable=False, server_default='0'),
-        sa.Column('is_declined', BOOLEAN, nullable=False, server_default='0'),
-        sa.Column('is_full_power', BOOLEAN, nullable=False, server_default='0'),
-        sa.Column('is_hidden', BOOLEAN, nullable=False, server_default='0'),
-        sa.Column('is_grayed', BOOLEAN, nullable=False, server_default='0'),
-
-        # important indexes
-        sa.Column('rshares', sa.BigInteger, nullable=False, server_default='0'),
-        sa.Column('sc_trend', sa.Float(precision=6), nullable=False, server_default='0'),
-        sa.Column('sc_hot', sa.Float(precision=6), nullable=False, server_default='0'),
-
-        # bulk data
-        sa.Column('body', TEXT),
-        sa.Column('votes', TEXT),
-        sa.Column('json', sa.Text),
-        #sa.Column('raw_json', sa.Text),
-
-        sa.Column('legacy_id', sa.Integer, nullable=False, server_default='-1'),
-        sa.Column('parent_author', sa.String(16), nullable=False, server_default=''),
-        sa.Column('parent_permlink',  sa.String(255), nullable=False, server_default=''),
-        sa.Column('curator_payout_value', sa.String(16), nullable=False, server_default=''),
-        sa.Column('root_author',  sa.String(16), nullable=False, server_default=''),
-        sa.Column('root_permlink',  sa.String(255), nullable=False, server_default=''),
-        sa.Column('max_accepted_payout',  sa.String(16), nullable=False, server_default=''),
-        sa.Column('percent_steem_dollars', sa.Integer, nullable=False, server_default='-1'),
-        sa.Column('allow_replies', BOOLEAN, nullable=False, server_default='1'),
-        sa.Column('allow_votes', BOOLEAN, nullable=False, server_default='1'),
-        sa.Column('allow_curation_rewards', BOOLEAN, nullable=False, server_default='1'),
-        sa.Column('beneficiaries',  sa.JSON, nullable=False, server_default=''),
-        sa.Column('url', sa.Text, nullable=False, server_default=''),
-        sa.Column('root_title', sa.String(255), nullable=False, server_default=''),
-
-        sa.Column('author_permlink', sa.String(255 + 16, collation='C'), nullable=False, server_default=''),
-
-        # index: misc
-        sa.Index('hive_posts_cache_ix3',  'payout_at', 'post_id',           postgresql_where=sql_text("is_paidout = '0'")),         # core: payout sweep
-        sa.Index('hive_posts_cache_ix8',  'category', 'payout', 'depth',    postgresql_where=sql_text("is_paidout = '0'")),         # API: tag stats
-
-        # index: ranked posts
-        sa.Index('hive_posts_cache_ix2',  'promoted',             postgresql_where=sql_text("is_paidout = '0' AND promoted > 0")),  # API: promoted
-
-        sa.Index('hive_posts_cache_ix6a', 'sc_trend', 'post_id',  postgresql_where=sql_text("is_paidout = '0'")),                   # API: trending             todo: depth=0
-        sa.Index('hive_posts_cache_ix7a', 'sc_hot',   'post_id',  postgresql_where=sql_text("is_paidout = '0'")),                   # API: hot                  todo: depth=0
-        sa.Index('hive_posts_cache_ix6b', 'post_id',  'sc_trend', postgresql_where=sql_text("is_paidout = '0'")),                   # API: trending, filtered   todo: depth=0
-        sa.Index('hive_posts_cache_ix7b', 'post_id',  'sc_hot',   postgresql_where=sql_text("is_paidout = '0'")),                   # API: hot, filtered        todo: depth=0
-
-        sa.Index('hive_posts_cache_ix9a',             'depth', 'payout', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # API: payout               todo: rem depth
-        sa.Index('hive_posts_cache_ix9b', 'category', 'depth', 'payout', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # API: payout, filtered     todo: rem depth
-
-        sa.Index('hive_posts_cache_ix10', 'post_id', 'payout',                      postgresql_where=sql_text("is_grayed = '1' AND payout > 0")), # API: muted, by filter/date/payout
-
-        # index: stats
-        sa.Index('hive_posts_cache_ix20', 'community_id', 'author', 'payout', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # API: pending distribution; author payout
-
-        # index: community ranked posts
-        sa.Index('hive_posts_cache_ix30', 'community_id', 'sc_trend',   'post_id',  postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '0' AND depth = 0")),        # API: community trend
-        sa.Index('hive_posts_cache_ix31', 'community_id', 'sc_hot',     'post_id',  postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '0' AND depth = 0")),        # API: community hot
-        sa.Index('hive_posts_cache_ix32', 'community_id', 'created_at', 'post_id',  postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '0' AND depth = 0")),        # API: community created
-        sa.Index('hive_posts_cache_ix33', 'community_id', 'payout',     'post_id',  postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '0' AND is_paidout = '0'")), # API: community payout
-        sa.Index('hive_posts_cache_ix34', 'community_id', 'payout',     'post_id',  postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '1' AND is_paidout = '0'")), # API: community muted
-    )
-
     sa.Table(
         'hive_state', metadata,
         sa.Column('block_num', sa.Integer, primary_key=True, autoincrement=False),
@@ -369,7 +337,6 @@ def reset_autovac(db):
 
     autovac_config = { #    vacuum  analyze
         'hive_accounts':    (50000, 100000),
-        'hive_posts_cache': (25000, 25000),
         'hive_posts':       (2500, 10000),
         'hive_post_tags':   (5000, 10000),
         'hive_follows':     (5000, 5000),
diff --git a/hive/indexer/blocks.py b/hive/indexer/blocks.py
index 58af5b48ffa431036cbd6b57f887e73ec428f971..fa47f4af8f7ce4081c3f289c7a602aefaf536e3b 100644
--- a/hive/indexer/blocks.py
+++ b/hive/indexer/blocks.py
@@ -219,9 +219,9 @@ class Blocks:
 
             # remove posts: core, tags, cache entries
             if post_ids:
-                DB.query("DELETE FROM hive_posts_cache WHERE post_id IN :ids", ids=post_ids)
                 DB.query("DELETE FROM hive_post_tags   WHERE post_id IN :ids", ids=post_ids)
                 DB.query("DELETE FROM hive_posts       WHERE id      IN :ids", ids=post_ids)
+                DB.query("DELETE FROM hive_posts_data  WHERE id      IN :ids", ids=post_ids)
 
             DB.query("DELETE FROM hive_payments    WHERE block_num = :num", num=num)
             DB.query("DELETE FROM hive_blocks      WHERE num = :num", num=num)
diff --git a/hive/indexer/cached_post.py b/hive/indexer/cached_post.py
index 21ce636b35359da8966cef8e5c0ab1c8da21e2aa..e0db3053b07f11ff50a42afdcbad045e1ff8c761 100644
--- a/hive/indexer/cached_post.py
+++ b/hive/indexer/cached_post.py
@@ -504,7 +504,6 @@ class CachedPost:
                 ('json',          json.dumps(basic['json_metadata'])),
                 #('raw_json',      json.dumps(legacy_data)),
                 # TODO: check if writting fields below on every update is necessary!
-                ('legacy_id',               legacy_data['id']),
                 ('parent_author',           legacy_data['parent_author']),
                 ('parent_permlink',         legacy_data['parent_permlink']),
                 ('curator_payout_value',    legacy_data['curator_payout_value']),
diff --git a/hive/indexer/community.py b/hive/indexer/community.py
index d57c5acad001a68c8074c319ca50c08cd613d797..51df8447568c87fdeafd1f79eab98b1c8d71846a 100644
--- a/hive/indexer/community.py
+++ b/hive/indexer/community.py
@@ -235,10 +235,11 @@ class Community:
                              SELECT community_id,
                                     COUNT(*) posts,
                                     ROUND(SUM(payout)) payouts,
-                                    COUNT(DISTINCT author) authors
-                               FROM hive_posts_cache
+                                    COUNT(DISTINCT author_id) authors
+                               FROM hive_posts
                               WHERE community_id IS NOT NULL
                                 AND is_paidout = '0'
+                                AND is_deleted = '0'
                            GROUP BY community_id
                         ) p
                      ON community_id = id
diff --git a/hive/indexer/posts.py b/hive/indexer/posts.py
index 9a72cd2433dfd7803db45a84480a4f9ece265b7a..3917217a1e3e291d6c8ee60b8f92cb592eae99f6 100644
--- a/hive/indexer/posts.py
+++ b/hive/indexer/posts.py
@@ -40,8 +40,13 @@ class Posts:
             cls._ids[url] = _id
         else:
             cls._miss += 1
-            sql = """SELECT id FROM hive_posts WHERE
-                     author = :a AND permlink = :p"""
+            sql = """
+                SELECT id 
+                FROM hive_posts hp 
+                LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id 
+                LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id 
+                WHERE ha_a.name = :a AND hpd_p.permlink = :p
+            """
             _id = DB.query_one(sql, a=author, p=permlink)
             if _id:
                 cls._set_id(url, _id)
@@ -112,10 +117,11 @@ class Posts:
     @classmethod
     def insert(cls, op, date):
         """Inserts new post records."""
-        sql = """INSERT INTO hive_posts (is_valid, is_muted, parent_id, author,
-                             permlink, category, community_id, depth, created_at)
-                      VALUES (:is_valid, :is_muted, :parent_id, :author,
-                             :permlink, :category, :community_id, :depth, :date)"""
+        # TODO check if category and permlink exists
+        sql = """INSERT INTO hive_posts (is_valid, is_muted, parent_id, author_id,
+                             permlink_id, category_id, community_id, depth, created_at)
+                      VALUES (:is_valid, :is_muted, :parent_id, (SELECT id FROM hive_accounts WHERE name = :author),
+                             (SELECT id FROM hive_permlink_data WHERE permlink = :permlink), (SELECT :category), :community_id, :depth, :date)"""
         sql += ";SELECT currval(pg_get_serial_sequence('hive_posts','id'))"
         post = cls._build_post(op, date)
         result = DB.query(sql, **post)
diff --git a/hive/server/bridge_api/cursor.py b/hive/server/bridge_api/cursor.py
index 8d9477468a877d142a817fd93c6708710e7c80a9..928bfbc89ee215a2185f7b19a8e47cd405d675a7 100644
--- a/hive/server/bridge_api/cursor.py
+++ b/hive/server/bridge_api/cursor.py
@@ -104,7 +104,7 @@ async def pids_by_community(db, ids, sort, seek_id, limit):
 
     # setup
     field, pending, toponly, gray, promoted = definitions[sort]
-    table = 'hive_posts_cache'
+    table = 'hive_posts'
     where = ["community_id IN :ids"] if ids else ["community_id IS NOT NULL AND community_id != 1337319"]
 
     # select
@@ -117,8 +117,8 @@ async def pids_by_community(db, ids, sort, seek_id, limit):
 
     # seek
     if seek_id:
-        sval = "(SELECT %s FROM %s WHERE post_id = :seek_id)" % (field, table)
-        sql = """((%s < %s) OR (%s = %s AND post_id > :seek_id))"""
+        sval = "(SELECT %s FROM %s WHERE id = :seek_id)" % (field, table)
+        sql = """((%s < %s) OR (%s = %s AND id > :seek_id))"""
         where.append(sql % (field, sval, field, sval))
 
         # simpler `%s <= %s` eval has edge case: many posts with payout 0
@@ -129,8 +129,8 @@ async def pids_by_community(db, ids, sort, seek_id, limit):
         #where.append(sql % (field, sval, field, sval))
 
     # build
-    sql = ("""SELECT post_id FROM %s WHERE %s
-              ORDER BY %s DESC, post_id LIMIT :limit
+    sql = ("""SELECT id FROM %s WHERE %s
+              ORDER BY %s DESC, id LIMIT :limit
               """ % (table, ' AND '.join(where), field))
 
     # execute
@@ -157,7 +157,7 @@ async def pids_by_category(db, tag, sort, last_id, limit):
         'muted':           ('payout',   True,   False,  False,  False),
     }[sort]
 
-    table = 'hive_posts_cache'
+    table = 'hive_post'
     field = params[0]
     where = []
 
@@ -172,17 +172,17 @@ async def pids_by_category(db, tag, sort, last_id, limit):
     # filter by category or tag
     if tag:
         if sort in ['payout', 'payout_comments']:
-            where.append('category = :tag')
+            where.append('category_id = (SELECT id FROM hive_category_data WHERE category = :tag)')
         else:
             sql = "SELECT post_id FROM hive_post_tags WHERE tag = :tag"
-            where.append("post_id IN (%s)" % sql)
+            where.append("id IN (%s)" % sql)
 
     if last_id:
-        sval = "(SELECT %s FROM %s WHERE post_id = :last_id)" % (field, table)
-        sql = """((%s < %s) OR (%s = %s AND post_id > :last_id))"""
+        sval = "(SELECT %s FROM %s WHERE id = :last_id)" % (field, table)
+        sql = """((%s < %s) OR (%s = %s AND id > :last_id))"""
         where.append(sql % (field, sval, field, sval))
 
-    sql = ("""SELECT post_id FROM %s WHERE %s
+    sql = ("""SELECT id FROM %s WHERE %s
               ORDER BY %s DESC, post_id LIMIT :limit
               """ % (table, ' AND '.join(where), field))
 
@@ -390,14 +390,14 @@ async def pids_by_payout(db, account: str, start_author: str = '',
     start_id = None
     if start_permlink:
         start_id = await _get_post_id(db, start_author, start_permlink)
-        last = "(SELECT payout FROM hive_posts_cache WHERE post_id = :start_id)"
-        seek = ("""AND (payout < %s OR (payout = %s AND post_id > :start_id))"""
+        last = "(SELECT payout FROM hive_posts WHERE id = :start_id)"
+        seek = ("""AND (payout < %s OR (payout = %s AND id > :start_id))"""
                 % (last, last))
 
     sql = """
-        SELECT post_id
-          FROM hive_posts_cache
-         WHERE author = :account
+        SELECT id
+          FROM hive_posts
+         WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :account)
            AND is_paidout = '0' %s
       ORDER BY payout DESC, post_id
          LIMIT :limit
diff --git a/hive/server/bridge_api/objects.py b/hive/server/bridge_api/objects.py
index 64b845f93658ef9877ecee593c8a198f9f82d38e..956589340271dcf74c0cfad7f7b919963d197121 100644
--- a/hive/server/bridge_api/objects.py
+++ b/hive/server/bridge_api/objects.py
@@ -43,14 +43,53 @@ async def load_posts_keyed(db, ids, truncate_body=0):
     assert ids, 'no ids passed to load_posts_keyed'
 
     # fetch posts and associated author reps
-    sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
-                    promoted, payout, payout_at, is_paidout, children, votes,
-                    created_at, updated_at, rshares, json,
-                    is_hidden, is_grayed, total_votes, flag_weight,
-                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
-                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-                    allow_replies, allow_votes, allow_curation_rewards, url, root_title 
-               FROM hive_posts_cache WHERE post_id IN :ids"""
+    sql = """
+        SELECT hp.id, 
+            community_id, 
+            ha_a.name as author,
+            hpd_p.permlink as permlink,
+            hpd.title as title, 
+            hpd.body as body, 
+            hcd.category as category, 
+            depth,
+            promoted, 
+            payout, 
+            payout_at, 
+            is_paidout, 
+            children, 
+            hpd.votes as votes,
+            hp.created_at, 
+            updated_at, 
+            rshares, 
+            hpd.json as json,
+            is_hidden, 
+            is_grayed, 
+            total_votes, 
+            flag_weight,
+            ha_pa.name as parent_author,
+            hpd_pp.permlink as parent_permlink,
+            curator_payout_value, 
+            ha_ra.name as root_author,
+            hpd_rp.permlink as root_permlink,
+            max_accepted_payout, 
+            percent_steem_dollars, 
+            allow_replies, 
+            allow_votes, 
+            allow_curation_rewards, 
+            beneficiaries, 
+            url, 
+            root_title
+        FROM hive_posts hp
+        LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id
+        LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id
+        LEFT JOIN hive_post_data hpd ON hpd.id = hp.id
+        LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id
+        LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id
+        LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id
+        LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id
+        LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id
+        WHERE id IN :ids
+    """
     result = await db.query_all(sql, ids=tuple(ids))
     author_map = await _query_author_map(db, result)
 
@@ -178,7 +217,7 @@ def _condenser_profile_object(row):
                        }}}
 
 def _condenser_post_object(row, truncate_body=0):
-    """Given a hive_posts_cache row, create a legacy-style post object."""
+    """Given a hive_posts row, create a legacy-style post object."""
     paid = row['is_paidout']
 
     # condenser#3424 mitigation
@@ -186,7 +225,7 @@ def _condenser_post_object(row, truncate_body=0):
         row['category'] = 'undefined'
 
     post = {}
-    post['post_id'] = row['post_id']
+    post['post_id'] = row['id']
     post['author'] = row['author']
     post['permlink'] = row['permlink']
     post['category'] = row['category']
@@ -222,8 +261,6 @@ def _condenser_post_object(row, truncate_body=0):
 
     #post['author_reputation'] = rep_to_raw(row['author_rep'])
 
-    post['legacy_id'] = row['legacy_id']
-
     post['root_author'] = row['root_author']
     post['root_permlink'] = row['root_permlink']
 
diff --git a/hive/server/common/objects.py b/hive/server/common/objects.py
index 1e731d960d6f2520247bf56c4325e6b6a37d01e2..f2497a6c3162e574bb7d5e9be4fbc6e5fd937419 100644
--- a/hive/server/common/objects.py
+++ b/hive/server/common/objects.py
@@ -28,7 +28,7 @@ async def query_author_map(db, posts):
     return {r['name']: r for r in await db.query_all(sql, names=names)}
 
 def condenser_post_object(row, truncate_body=0):
-    """Given a hive_posts_cache row, create a legacy-style post object."""
+    """Given a hive_posts row, create a legacy-style post object."""
     paid = row['is_paidout']
 
     # condenser#3424 mitigation
@@ -36,7 +36,7 @@ def condenser_post_object(row, truncate_body=0):
         row['category'] = 'undefined'
 
     post = {}
-    post['post_id'] = row['post_id']
+    post['post_id'] = row['id']
     post['author'] = row['author']
     post['permlink'] = row['permlink']
     post['category'] = row['category']
@@ -63,8 +63,6 @@ def condenser_post_object(row, truncate_body=0):
     post['active_votes'] = _hydrate_active_votes(row['votes'])
     #post['author_reputation'] = rep_to_raw(row['author_rep'])
 
-    post['legacy_id'] = row['legacy_id']
-
     post['root_author'] = row['root_author']
     post['root_permlink'] = row['root_permlink']
 
diff --git a/hive/server/condenser_api/cursor.py b/hive/server/condenser_api/cursor.py
index 04d65b4527e735e49357af82b89ac0e2b8baa4f8..633113383b2c307e686708b250220e688cab591e 100644
--- a/hive/server/condenser_api/cursor.py
+++ b/hive/server/condenser_api/cursor.py
@@ -141,7 +141,7 @@ async def pids_by_query(db, sort, start_author, start_permlink, limit, tag):
         'payout_comments': ('payout',   True,   False,  True,   False),
     }[sort]
 
-    table = 'hive_posts_cache'
+    table = 'hive_posts'
     field = params[0]
     where = []
 
@@ -157,29 +157,67 @@ async def pids_by_query(db, sort, start_author, start_permlink, limit, tag):
         #    cid = get_community_id(tag)
         #    where.append('community_id = :cid')
         if sort in ['payout', 'payout_comments']:
-            where.append('category = :tag')
+            where.append('category_id = (SELECT id FROM hive_category_data WHERE category = :tag)')
         else:
             if tag[:5] == 'hive-':
-                where.append('category = :tag')
+                where.append('category_id = (SELECT id FROM hive_category_data WHERE category = :tag)')
                 if sort in ('trending', 'hot'):
                     where.append('depth = 0')
             sql = "SELECT post_id FROM hive_post_tags WHERE tag = :tag"
-            where.append("post_id IN (%s)" % sql)
+            where.append("id IN (%s)" % sql)
 
     start_id = None
     if start_permlink and start_author:
-        sql = "%s <= (SELECT %s FROM %s WHERE post_id = (SELECT post_id FROM hive_posts_cache WHERE author = :start_author AND permlink= :start_permlink))"
+        sql = "%s <= (SELECT %s FROM %s WHERE id = (SELECT id FROM hive_posts WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :start_author) AND permlink_id = (SELECT id FROM hive_permlink_data WHERE permlink = :start_permlink)))"
         where.append(sql % (field, field, table))
 
-    columns = ['hive_posts_cache.post_id', 'hive_posts_cache.author', 'hive_posts_cache.permlink',
-               'hive_posts_cache.title', 'hive_posts_cache.body', 'hive_posts_cache.category',
-               'hive_posts_cache.depth', 'hive_posts_cache.promoted',
-               'hive_posts_cache.payout', 'hive_posts_cache.payout_at', 'hive_posts_cache.is_paidout',
-               'hive_posts_cache.children', 'hive_posts_cache.votes', 'hive_posts_cache.created_at',
-               'hive_posts_cache.updated_at', 'hive_posts_cache.rshares', 'hive_posts_cache.raw_json',
-               'hive_posts_cache.json']
-    sql = ("SELECT %s FROM %s WHERE %s ORDER BY %s DESC LIMIT :limit"
-           % (', '.join(columns), table, ' AND '.join(where), field))
+    sql = """
+        SELECT hp.id, 
+            community_id, 
+            ha_a.name as author,
+            hpd_p.permlink as permlink,
+            hpd.title as title, 
+            hpd.body as body, 
+            hcd.category as category, 
+            depth,
+            promoted, 
+            payout, 
+            payout_at, 
+            is_paidout, 
+            children, 
+            hpd.votes as votes,
+            hp.created_at, 
+            updated_at, 
+            rshares, 
+            hpd.json as json,
+            is_hidden, 
+            is_grayed, 
+            total_votes, 
+            flag_weight,
+            ha_pa.name as parent_author,
+            hpd_pp.permlink as parent_permlink,
+            curator_payout_value, 
+            ha_ra.name as root_author,
+            hpd_rp.permlink as root_permlink,
+            max_accepted_payout, 
+            percent_steem_dollars, 
+            allow_replies, 
+            allow_votes, 
+            allow_curation_rewards, 
+            beneficiaries, 
+            url, 
+            root_title
+        FROM hive_posts hp
+        LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id
+        LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id
+        LEFT JOIN hive_post_data hpd ON hpd.id = hp.id
+        LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id
+        LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id
+        LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id
+        LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id
+        LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id
+        WHERE %s ORDER BY %s DESC LIMIT :limit
+    """ % (' AND '.join(where), field)
 
     #return await db.query_col(sql, tag=tag, start_id=start_id, limit=limit)
     return [sql, tag, start_id, limit]
diff --git a/hive/server/condenser_api/methods.py b/hive/server/condenser_api/methods.py
index be188cbd7f4f3f1b543219665825666e34efad37..e6831f6638d9acd95b134da97e192b562b9a1693 100644
--- a/hive/server/condenser_api/methods.py
+++ b/hive/server/condenser_api/methods.py
@@ -19,7 +19,53 @@ from hive.server.common.mutes import Mutes
 # pylint: disable=too-many-arguments,line-too-long,too-many-lines
 
 
-# Dummy
+SQL_TEMPLATE = """
+    SELECT hp.id, 
+        community_id, 
+        ha_a.name as author,
+        hpd_p.permlink as permlink,
+        hpd.title as title, 
+        hpd.body as body, 
+        hcd.category as category, 
+        depth,
+        promoted, 
+        payout, 
+        payout_at, 
+        is_paidout, 
+        children, 
+        hpd.votes as votes,
+        hp.created_at, 
+        updated_at, 
+        rshares, 
+        hpd.json as json,
+        is_hidden, 
+        is_grayed, 
+        total_votes, 
+        flag_weight,
+        ha_pa.name as parent_author,
+        hpd_pp.permlink as parent_permlink,
+        curator_payout_value, 
+        ha_ra.name as root_author,
+        hpd_rp.permlink as root_permlink,
+        max_accepted_payout, 
+        percent_steem_dollars, 
+        allow_replies, 
+        allow_votes, 
+        allow_curation_rewards, 
+        beneficiaries, 
+        url, 
+        root_title,
+        ha_a.reputation AS author_rep
+    FROM hive_posts hp
+    LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id
+    LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id
+    LEFT JOIN hive_post_data hpd ON hpd.id = hp.id
+    LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id
+    LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id
+    LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id
+    LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id
+    LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id
+"""
 
 @return_error_info
 async def get_account_votes(context, account):
@@ -104,18 +150,9 @@ async def get_content(context, author: str, permlink: str):
     valid_account(author)
     valid_permlink(permlink)
 
-    sql = """
-            ---get_content
-            SELECT hive_posts_cache.post_id, hive_posts_cache.author, hive_posts_cache.permlink, 
-            hive_posts_cache.title, hive_posts_cache.body, hive_posts_cache.category, hive_posts_cache.depth,
-            hive_posts_cache.promoted, hive_posts_cache.payout, hive_posts_cache.payout_at,
-            hive_posts_cache.is_paidout, hive_posts_cache.children, hive_posts_cache.votes,
-            hive_posts_cache.created_at, hive_posts_cache.updated_at, hive_posts_cache.rshares,
-            hive_posts_cache.raw_json, hive_posts_cache.json, hive_accounts.reputation AS author_rep
-            FROM hive_posts_cache JOIN hive_accounts ON (hive_posts_cache.author = hive_accounts.name)
-                                  JOIN hive_posts ON (hive_posts_cache.post_id = hive_posts.id)
-            WHERE hive_posts_cache.author = :author AND hive_posts_cache.permlink = :permlink AND NOT hive_posts.is_deleted
-          """
+    #force copy
+    sql = str(SQL_TEMPLATE)
+    sql += """ WHERE ha_a.name = :author AND hpd_p.permlink = :permlink AND NOT hp.is_deleted """
 
     result = await db.query_all(sql, author=author, permlink=permlink)
     result = dict(result[0])
@@ -125,14 +162,6 @@ async def get_content(context, author: str, permlink: str):
     assert post, 'post was not found in cache'
     return post
 
-    #post_id = await cursor.get_post_id(db, author, permlink)
-    #if not post_id:
-    #    return {'id': 0, 'author': '', 'permlink': ''}
-    #posts = await load_posts(db, [post_id])
-    #assert posts, 'post was not found in cache'
-    #return posts[0]
-
-
 @return_error_info
 async def get_content_replies(context, author: str, permlink: str):
     """Get a list of post objects based on parent."""
@@ -140,25 +169,24 @@ async def get_content_replies(context, author: str, permlink: str):
     valid_account(author)
     valid_permlink(permlink)
 
-    sql = """
-             --get_content_replies
-             SELECT post_id, author, permlink, title, body, category, depth,
-             promoted, payout, payout_at, is_paidout, children, votes,
-             created_at, updated_at, rshares, json,
-             legacy_id, parent_author, parent_permlink, curator_payout_value, 
-             root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-             allow_replies, allow_votes, allow_curation_rewards, url, root_title 
-             FROM hive_posts_cache WHERE post_id IN (
-             SELECT hp2.id FROM hive_posts hp2
-             WHERE hp2.is_deleted = '0' AND
-             hp2.parent_id = (SELECT id FROM hive_posts
-             WHERE author = :author
-             AND permlink = :permlink AND is_deleted = '0')
-             LIMIT :limit
-             )
-             ORDER BY post_id"""
-
-    result=await db.query_all(sql, author=author, permlink = permlink, limit=5000)
+    #force copy
+    sql = str(SQL_TEMPLATE)
+    sql += """
+        WHERE 
+            hp.is_deleted = '0' AND 
+            hp.parent_id = (
+                SELECT id 
+                FROM hive_posts
+                WHERE 
+                    author_id = (SELECT id FROM hive_accounts WHERE name =:author)
+                    AND permlink_id = (SELECT id FROM hive_permlink_data WHERE permlink = :permlink)
+                    AND is_deleted = '0'
+            )
+        LIMIT :limit
+        ORDER BY id
+    """
+
+    result = await db.query_all(sql, author=author, permlink=permlink, limit=5000)
 
     posts = await resultset_to_posts(db=db, resultset=result, truncate_body=0)
     return posts
@@ -204,7 +232,7 @@ async def get_discussions_by(discussion_type, context, start_author: str = '',
         valid_permlink(start_permlink, allow_empty=True),
         valid_limit(limit, 100),
         valid_tag(tag, allow_empty=True))
-    
+
     assert len(query_information) == 4, 'generated query is malformed, aborting'
     sql = query_information[0]
     sql = "---get_discussions_by_" + discussion_type + "\r\n" + sql
@@ -278,26 +306,19 @@ async def get_discussions_by_blog(context, tag: str = None, start_author: str =
     valid_permlink(start_permlink, allow_empty=True)
     valid_limit(limit, 100)
 
-    sql = """
-            ---get_discussions_by_blog
-            SELECT hive_posts_cache.post_id, hive_posts_cache.author, hive_posts_cache.permlink, 
-            hive_posts_cache.title, hive_posts_cache.body, hive_posts_cache.category, hive_posts_cache.depth,
-            hive_posts_cache.promoted, hive_posts_cache.payout, hive_posts_cache.payout_at,
-            hive_posts_cache.is_paidout, hive_posts_cache.children, hive_posts_cache.votes,
-            hive_posts_cache.created_at, hive_posts_cache.updated_at, hive_posts_cache.rshares,
-            hive_posts_cache.raw_json, hive_posts_cache.json, hive_accounts.reputation AS author_rep
-            FROM hive_posts_cache JOIN hive_accounts ON (hive_posts_cache.author = hive_accounts.name)
-                                  JOIN hive_posts ON (hive_posts_cache.post_id = hive_posts.id)
-            WHERE NOT hive_posts.is_deleted AND hive_posts_cache.post_id IN
+    #force copy
+    sql = str(SQL_TEMPLATE)
+    sql += """
+            WHERE NOT hp.is_deleted AND hp.id IN
                 (SELECT post_id FROM hive_feed_cache JOIN hive_accounts ON (hive_feed_cache.account_id = hive_accounts.id) WHERE hive_accounts.name = :author)
           """
     if start_author and start_permlink != '':
         sql += """
-         AND hive_posts_cache.created_at <= (SELECT created_at from hive_posts_cache where author = :start_author AND permlink = :start_permlink)
+         AND hp.created_at <= (SELECT created_at from hive_posts WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :start_author) AND permlink_id = (SELECT id FROM hive_permlink_data WHERE permlink = :start_permlink))
         """
 
     sql += """
-        ORDER BY hive_posts_cache.created_at DESC
+        ORDER BY hp.created_at DESC
         LIMIT :limit
     """
 
@@ -310,7 +331,7 @@ async def get_discussions_by_blog(context, tag: str = None, start_author: str =
         post = _condenser_post_object(row, truncate_body=truncate_body)
         post['active_votes'] = _mute_votes(post['active_votes'], Mutes.all())
         #posts_by_id[row['post_id']] = post
-        posts_by_id.append(post);
+        posts_by_id.append(post)
 
     return posts_by_id
 
@@ -330,18 +351,6 @@ async def get_discussions_by_feed(context, tag: str = None, start_author: str =
         valid_limit(limit, 100))
     return await load_posts_reblogs(context['db'], res, truncate_body=truncate_body)
 
-    #valid_account(start_author, allow_empty=True)
-    #valid_account(tag)
-    #valid_permlink(start_permlink, allow_empty=True)
-    #valid_limit(limit, 100)
-
-    #sql = """
-    #    
-    #"""
-
-    #if start_permlink and start_author:
-
-
 
 @return_error_info
 @nested_query_compat
@@ -355,28 +364,20 @@ async def get_discussions_by_comments(context, start_author: str = None, start_p
     valid_permlink(start_permlink, allow_empty=True)
     valid_limit(limit, 100)
 
-    sql = """
-        ---get_discussions_by_comments
-        SELECT hive_posts_cache.post_id, hive_posts_cache.author, hive_posts_cache.permlink, 
-            hive_posts_cache.title, hive_posts_cache.body, hive_posts_cache.category, hive_posts_cache.depth,
-            hive_posts_cache.promoted, hive_posts_cache.payout, hive_posts_cache.payout_at,
-            hive_posts_cache.is_paidout, hive_posts_cache.children, hive_posts_cache.votes,
-            hive_posts_cache.created_at, hive_posts_cache.updated_at, hive_posts_cache.rshares,
-            hive_posts_cache.raw_json, hive_posts_cache.json, hive_accounts.reputation AS author_rep
-            FROM hive_posts_cache JOIN hive_accounts ON (hive_posts_cache.author = hive_accounts.name)
-                                  JOIN hive_posts ON (hive_posts_cache.post_id = hive_posts.id)
-            WHERE hive_posts_cache.author = :start_author AND hive_posts_cache.depth > 0
-            AND NOT hive_posts.is_deleted
+    #force copy
+    sql = str(SQL_TEMPLATE)
+    sql += """
+            WHERE ha_a.author = :start_author AND hp.depth > 0
+            AND NOT hp.is_deleted
     """
 
     if start_permlink:
         sql += """
-            AND hive_posts_cache.post_id <= (SELECT hive_posts_cache.post_id FROM 
-            hive_posts_cache WHERE permlink = :start_permlink AND author=:start_author)
+            AND hp.id <= (SELECT hive_posts.id FROM  hive_posts WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :start_author) AND permlink_id = (SELECT id FROM hive_permlink_data WHERE permlink = :start_permlink))
         """
 
     sql += """
-        ORDER BY hive_posts_cache.post_id DESC, depth LIMIT :limit
+        ORDER BY hp.id DESC, depth LIMIT :limit
     """
 
     posts = []
@@ -398,21 +399,6 @@ async def get_replies_by_last_update(context, start_author: str = None, start_pe
                                      limit: int = 20, truncate_body: int = 0):
     """Get all replies made to any of author's posts."""
     assert start_author, '`start_author` cannot be blank'
-    #valid_account(start_author)
-    #valid_permlink(start_permlink, allow_empty=True)
-    #valid_limit(limit, 100)
-
-    #sql = """
-    #    SELECT hive_posts_cache.post_id, hive_posts_cache.author, hive_posts_cache.permlink, 
-    #        hive_posts_cache.title, hive_posts_cache.body, hive_posts_cache.category, hive_posts_cache.depth,
-    #        hive_posts_cache.promoted, hive_posts_cache.payout, hive_posts_cache.payout_at,
-    #        hive_posts_cache.is_paidout, hive_posts_cache.children, hive_posts_cache.votes,
-    #        hive_posts_cache.created_at, hive_posts_cache.updated_at, hive_posts_cache.rshares,
-    #        hive_posts_cache.raw_json, hive_posts_cache.json, hive_accounts.reputation AS author_rep
-    #        FROM hive_posts_cache JOIN hive_accounts ON (hive_posts_cache.author = hive_accounts.name)
-    #                              JOIN hive_posts ON (hive_posts_cache.post_id = hive_posts.id)
-    #
-    #"""
 
     ids = await cursor.pids_by_replies_to_account(
         context['db'],
diff --git a/hive/server/condenser_api/objects.py b/hive/server/condenser_api/objects.py
index 71148d3c59bad168150b7e464d1e06fe95a7dc81..30c216ab949f19e17ce8be2e33cdf24c7457b06b 100644
--- a/hive/server/condenser_api/objects.py
+++ b/hive/server/condenser_api/objects.py
@@ -40,13 +40,53 @@ async def load_posts_keyed(db, ids, truncate_body=0):
     assert ids, 'no ids passed to load_posts_keyed'
 
     # fetch posts and associated author reps
-    sql = """SELECT post_id, author, permlink, title, body, category, depth,
-                    promoted, payout, payout_at, is_paidout, children, votes,
-                    created_at, updated_at, rshares, json,
-                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
-                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-                    allow_replies, allow_votes, allow_curation_rewards, url, root_title 
-               FROM hive_posts_cache WHERE post_id IN :ids"""
+    sql = """
+    SELECT hp.id, 
+        community_id, 
+        ha_a.name as author,
+        hpd_p.permlink as permlink,
+        hpd.title as title, 
+        hpd.body as body, 
+        hcd.category as category, 
+        depth,
+        promoted, 
+        payout, 
+        payout_at, 
+        is_paidout, 
+        children, 
+        hpd.votes as votes,
+        hp.created_at, 
+        updated_at, 
+        rshares, 
+        hpd.json as json,
+        is_hidden, 
+        is_grayed, 
+        total_votes, 
+        flag_weight,
+        ha_pa.name as parent_author,
+        hpd_pp.permlink as parent_permlink,
+        curator_payout_value, 
+        ha_ra.name as root_author,
+        hpd_rp.permlink as root_permlink,
+        max_accepted_payout, 
+        percent_steem_dollars, 
+        allow_replies, 
+        allow_votes, 
+        allow_curation_rewards, 
+        beneficiaries, 
+        url, 
+        root_title,
+    FROM hive_posts hp
+    LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id
+    LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id
+    LEFT JOIN hive_post_data hpd ON hpd.id = hp.id
+    LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id
+    LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id
+    LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id
+    LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id
+    LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id
+    WHERE post_id IN :ids"""
+
     result = await db.query_all(sql, ids=tuple(ids))
     author_reps = await _query_author_rep_map(db, result)
 
@@ -57,7 +97,7 @@ async def load_posts_keyed(db, ids, truncate_body=0):
         row['author_rep'] = author_reps[row['author']]
         post = _condenser_post_object(row, truncate_body=truncate_body)
         post['active_votes'] = _mute_votes(post['active_votes'], muted_accounts)
-        posts_by_id[row['post_id']] = post
+        posts_by_id[row['id']] = post
 
     return posts_by_id
 
@@ -132,7 +172,7 @@ def _condenser_account_object(row):
                        }})}
 
 def _condenser_post_object(row, truncate_body=0):
-    """Given a hive_posts_cache row, create a legacy-style post object."""
+    """Given a hive_posts row, create a legacy-style post object."""
     paid = row['is_paidout']
 
     # condenser#3424 mitigation
@@ -140,7 +180,7 @@ def _condenser_post_object(row, truncate_body=0):
         row['category'] = 'undefined'
 
     post = {}
-    post['post_id'] = row['post_id']
+    post['post_id'] = row['id']
     post['author'] = row['author']
     post['permlink'] = row['permlink']
     post['category'] = row['category']
@@ -167,8 +207,6 @@ def _condenser_post_object(row, truncate_body=0):
     post['active_votes'] = _hydrate_active_votes(row['votes'])
     post['author_reputation'] = rep_to_raw(row['author_rep'])
 
-    post['legacy_id'] = row['legacy_id']
-
     post['root_author'] = row['root_author']
     post['root_permlink'] = row['root_permlink']
 
diff --git a/hive/server/condenser_api/tags.py b/hive/server/condenser_api/tags.py
index 9a4f5b5b3384a5dd004940dfbddcc163cbc0d5fe..7cb83f44b0514aeb10e85e6659db43a13795be80 100644
--- a/hive/server/condenser_api/tags.py
+++ b/hive/server/condenser_api/tags.py
@@ -11,7 +11,7 @@ async def get_top_trending_tags_summary(context):
     #return [tag['name'] for tag in await get_trending_tags('', 50)]
     sql = """
         SELECT category
-          FROM hive_posts_cache
+          FROM hive_posts
          WHERE is_paidout = '0'
       GROUP BY category
       ORDER BY SUM(payout) DESC
@@ -31,7 +31,7 @@ async def get_trending_tags(context, start_tag: str = '', limit: int = 250):
         seek = """
           HAVING SUM(payout) <= (
             SELECT SUM(payout)
-              FROM hive_posts_cache
+              FROM hive_posts
              WHERE is_paidout = '0'
                AND category = :start_tag)
         """
@@ -43,7 +43,7 @@ async def get_trending_tags(context, start_tag: str = '', limit: int = 250):
              COUNT(*) AS total_posts,
              SUM(CASE WHEN depth = 0 THEN 1 ELSE 0 END) AS top_posts,
              SUM(payout) AS total_payouts
-        FROM hive_posts_cache
+        FROM hive_posts
        WHERE is_paidout = '0'
     GROUP BY category %s
     ORDER BY SUM(payout) DESC
diff --git a/hive/server/database_api/methods.py b/hive/server/database_api/methods.py
index 4142ec1b196c741f39d6e49a50fcd2b09bb2370d..f47e8b2d39267850ca1a0a1ff544e09723348169 100644
--- a/hive/server/database_api/methods.py
+++ b/hive/server/database_api/methods.py
@@ -2,11 +2,69 @@
 from hive.server.common.helpers import return_error_info, valid_limit
 from hive.server.common.objects import condenser_post_object
 
+SQL_TEMPLATE = """
+    SELECT hp.id, 
+        community_id, 
+        ha_a.name as author,
+        hpd_p.permlink as permlink,
+        hpd.title as title, 
+        hpd.body as body, 
+        hcd.category as category, 
+        depth,
+        promoted, 
+        payout, 
+        payout_at, 
+        is_paidout, 
+        children, 
+        hpd.votes as votes,
+        hp.created_at, 
+        updated_at, 
+        rshares, 
+        hpd.json as json,
+        is_hidden, 
+        is_grayed, 
+        total_votes, 
+        flag_weight,
+        ha_pa.name as parent_author,
+        hpd_pp.permlink as parent_permlink,
+        curator_payout_value, 
+        ha_ra.name as root_author,
+        hpd_rp.permlink as root_permlink,
+        max_accepted_payout, 
+        percent_steem_dollars, 
+        allow_replies, 
+        allow_votes, 
+        allow_curation_rewards, 
+        beneficiaries, 
+        url, 
+        root_title
+    FROM hive_posts hp
+    LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id
+    LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id
+    LEFT JOIN hive_post_data hpd ON hpd.id = hp.id
+    LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id
+    LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id
+    LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id
+    LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id
+    LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id
+    WHERE
+"""
+
 async def get_post_id_by_author_and_permlink(db, author: str, permlink: str, limit: int):
     """Return post ids for given author and permlink"""
-    sql = """SELECT post_id FROM hive_posts_cache WHERE author = :author AND permlink = :permlink ORDER BY author ASC, permlink ASC, post_id ASC LIMIT :limit"""
+    sql = """
+        SELECT hp.id 
+        FROM hive_posts hp
+        LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id
+        LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id
+        WHERE ha_a.name >= :author AND hpd_p.permlink >= :permlink 
+        ORDER BY ha_a.name ASC 
+        LIMIT :limit
+    """
     result = await db.query_row(sql, author=author, permlink=permlink, limit=limit)
-    return result.post_id
+    if result is not None:
+        return int(result.get('post_id', 0))
+    return 0
 
 @return_error_info
 async def list_comments(context, start: list, limit: int, order: str):
@@ -27,56 +85,38 @@ async def list_comments(context, start: list, limit: int, order: str):
         if author or permlink:
             post_id = await get_post_id_by_author_and_permlink(db, author, permlink, 1)
 
-        sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
-                    promoted, payout, payout_at, is_paidout, children, votes,
-                    created_at, updated_at, rshares, json,
-                    is_hidden, is_grayed, total_votes, flag_weight,
-                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
-                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-                    allow_replies, allow_votes, allow_curation_rewards, beneficiaries, url, root_title 
-               FROM hive_posts_cache WHERE payout_at >= :start AND post_id >= :post_id ORDER BY payout_at ASC, post_id ASC LIMIT :limit"""
+        sql = str(SQL_TEMPLATE)
+        sql += "hp.payout_at >= :start AND hp.id >= :post_id ORDER BY hp.payout_at ASC, hp.id ASC LIMIT :limit"
+
         result = await db.query_all(sql, start=start[0], limit=limit, post_id=post_id)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
     elif order == 'by_permlink':
         assert len(start) == 2, "Expecting two arguments"
 
-        sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
-                    promoted, payout, payout_at, is_paidout, children, votes,
-                    created_at, updated_at, rshares, json,
-                    is_hidden, is_grayed, total_votes, flag_weight,
-                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
-                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-                    allow_replies, allow_votes, allow_curation_rewards, beneficiaries, url, root_title 
-               FROM hive_posts_cache WHERE author >= :author AND permlink >= :permlink ORDER BY author ASC, permlink ASC LIMIT :limit"""
+        sql = str(SQL_TEMPLATE)
+        sql += 'ha_a.name >= :author COLLATE "C" AND hpd_p.permlink >= :permlink COLLATE "C" ORDER BY ha_a.name COLLATE "C" ASC LIMIT :limit'
+
         result = await db.query_all(sql, author=start[0], permlink=start[1], limit=limit)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
     elif order == 'by_root':
         assert len(start) == 4, "Expecting 4 arguments"
+        raise NotImplementedError('by_root')
+
+        sql = str(SQL_TEMPLATE)
+        sql += "get_rows_by_root(:root_author, :root_permlink, :child_author, :child_permlink) ORDER BY post_id ASC LIMIT :limit"
 
-        sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
-                    promoted, payout, payout_at, is_paidout, children, votes,
-                    created_at, updated_at, rshares, json,
-                    is_hidden, is_grayed, total_votes, flag_weight,
-                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
-                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-                    allow_replies, allow_votes, allow_curation_rewards, beneficiaries, url, root_title 
-               FROM get_rows_by_root(:root_author, :root_permlink, :child_author, :child_permlink) ORDER BY post_id ASC LIMIT :limit"""
         result = await db.query_all(sql, root_author=start[0], root_permlink=start[1], child_author=start[2], child_permlink=start[3], limit=limit)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
     elif order == 'by_parent':
         assert len(start) == 4, "Expecting 4 arguments"
+        raise NotImplementedError('by_parent')
+
+        sql = str(SQL_TEMPLATE)
+        sql += "get_rows_by_parent(:parent_author, :parent_permlink, :child_author, :child_permlink) LIMIT :limit"
 
-        sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
-                    promoted, payout, payout_at, is_paidout, children, votes,
-                    created_at, updated_at, rshares, json,
-                    is_hidden, is_grayed, total_votes, flag_weight,
-                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
-                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-                    allow_replies, allow_votes, allow_curation_rewards, beneficiaries, url, root_title 
-               FROM get_rows_by_parent(:parent_author, :parent_permlink, :child_author, :child_permlink) LIMIT :limit"""
         result = await db.query_all(sql, parent_author=start[0], parent_permlink=start[1], child_author=start[2], child_permlink=start[3], limit=limit)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
@@ -90,14 +130,9 @@ async def list_comments(context, start: list, limit: int, order: str):
         if author or permlink:
             post_id = await get_post_id_by_author_and_permlink(db, child_author, child_permlink, 1)
 
-        sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
-                    promoted, payout, payout_at, is_paidout, children, votes,
-                    created_at, updated_at, rshares, json,
-                    is_hidden, is_grayed, total_votes, flag_weight,
-                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
-                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-                    allow_replies, allow_votes, allow_curation_rewards, beneficiaries, url, root_title 
-               FROM hive_posts_cache WHERE parent_author >= :parent_author AND updated_at >= :updated_at AND post_id >= :post_id ORDER BY parent_author ASC, updated_at ASC, post_id ASC LIMIT :limit"""
+        sql = str(SQL_TEMPLATE)
+        sql += "ha_pa.name >= :parent_author AND hp.updated_at >= :updated_at AND hp.id >= :post_id ORDER BY ha_pa.name ASC, updated_at ASC, hp.id ASC LIMIT :limit"
+
         result = await db.query_all(sql, parent_author=start[0], updated_at=start[1], post_id=post_id, limit=limit)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
@@ -112,16 +147,35 @@ async def list_comments(context, start: list, limit: int, order: str):
         if author or permlink:
             post_id = await get_post_id_by_author_and_permlink(db, author, permlink, 1)
 
-        sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
-                    promoted, payout, payout_at, is_paidout, children, votes,
-                    created_at, updated_at, rshares, json,
-                    is_hidden, is_grayed, total_votes, flag_weight,
-                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
-                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
-                    allow_replies, allow_votes, allow_curation_rewards, beneficiaries, url, root_title 
-               FROM hive_posts_cache WHERE author >= :author AND updated_at >= :updated_at AND post_id >= :post_id ORDER BY parent_author ASC, updated_at ASC, post_id ASC LIMIT :limit"""
+        sql = str(SQL_TEMPLATE)
+        sql += "ha_a.name >= :author AND hp.updated_at >= :updated_at AND hp.id >= :post_id ORDER BY ha_a.name ASC, hp.updated_at ASC, hp.id ASC LIMIT :limit"
+
         result = await db.query_all(sql, author=start[0], updated_at=start[1], post_id=post_id, limit=limit)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
 
     return comments
+
+@return_error_info
+async def find_comments(context, start: list, limit: int, order: str):
+    """ Search for comments: limit and order is ignored in hive code """
+    comments = []
+
+    assert len(start) <= 1000, "Parameters count is greather than max allowed (1000)"
+    db = context['db']
+
+    # make a copy
+    sql = str(SQL_TEMPLATE)
+
+    idx = 0
+    for arg in start:
+        if idx > 0:
+            sql += " OR "
+        sql += "(ha_a.name = '{}' AND hpd_p.permlink = '{}')".format(arg[0], arg[1])
+        idx += 1
+
+    result = await db.query_all(sql)
+    for row in result:
+        comments.append(condenser_post_object(dict(row)))
+
+    return comments
diff --git a/hive/server/hive_api/community.py b/hive/server/hive_api/community.py
index 47963d1ce30661bd7e23a315713acfbed5aa497b..fa572de000d4773868331037f22b9e3179afd9c1 100644
--- a/hive/server/hive_api/community.py
+++ b/hive/server/hive_api/community.py
@@ -353,8 +353,16 @@ async def top_community_muted(context, community):
 
 async def _top_community_posts(db, community, limit=50):
     # TODO: muted equivalent
-    sql = """SELECT author, votes, payout FROM hive_posts_cache
-              WHERE category = :community AND is_paidout = '0'
-                AND post_id IN (SELECT id FROM hive_posts WHERE is_muted = '0')
-           ORDER BY payout DESC LIMIT :limit"""
+    sql = """
+    SELECT ha_a.name as author,
+        hpd.votes as votes,
+        payout
+    FROM hive_posts hp
+    LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id
+    LEFT JOIN hive_post_data hpd ON hpd.id = hp.id
+    LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id
+    WHERE hcdcategory = :community AND is_paidout = '0'
+        AND post_id IN (SELECT id FROM hive_posts WHERE is_muted = '0')
+    ORDER BY payout DESC LIMIT :limit"""
+    
     return await db.query_all(sql, community=community, limit=limit)
diff --git a/hive/server/hive_api/objects.py b/hive/server/hive_api/objects.py
index c8c74a37ed8f28951d1f9243b31d60e90b893a2f..05dfe19de769ba67128c76f4ccd415b73021994e 100644
--- a/hive/server/hive_api/objects.py
+++ b/hive/server/hive_api/objects.py
@@ -68,10 +68,22 @@ async def comments_by_id(db, ids, observer=None):
     """Given an array of post ids, returns comment objects keyed by id."""
     assert ids, 'no ids passed to comments_by_id'
 
-    sql = """SELECT post_id, author, permlink, body, depth,
-                    payout, payout_at, is_paidout, created_at, updated_at,
-                    rshares, is_hidden, is_grayed, votes
-               FROM hive_posts_cache WHERE post_id IN :ids""" #votes
+    sql = """SELECT hp.id,
+                    (SELECT name FROM hive_accounts ha WHERE ha.id = hp.author_id) as author,
+                    (SELECT permlink FROM hive_permlink_data hpd WHERE hpd.id = hp.permlink_id) as permlink,
+                    (SELECT body FROM hive_post_data hpa WHERE hpa.id = hp.id) as body,
+                    hp.depth,
+                    hp.payout,
+                    hp.payout_at,
+                    hp.is_paidout,
+                    hp.created_at,
+                    hp.updated_at,
+                    hp.rshares,
+                    hp.is_hidden,
+                    hp.is_grayed,
+                    hp.votes
+               FROM hive_posts hp
+               WHERE hp.id IN :ids""" #votes
     result = await db.query_all(sql, ids=tuple(ids))
 
     authors = set()
@@ -79,7 +91,7 @@ async def comments_by_id(db, ids, observer=None):
     for row in result:
         top_votes, observer_vote = _top_votes(row, 5, observer)
         post = {
-            'id': row['post_id'],
+            'id': row['id'],
             'author': row['author'],
             'url': row['author'] + '/' + row['permlink'],
             'depth': row['depth'],
@@ -108,10 +120,23 @@ async def posts_by_id(db, ids, observer=None, lite=True):
     """Given a list of post ids, returns lite post objects in the same order."""
 
     # pylint: disable=too-many-locals
-    sql = """SELECT post_id, author, permlink, title, img_url, payout, promoted,
-                    created_at, payout_at, is_nsfw, rshares, votes,
-                    is_muted, is_invalid, %s
-               FROM hive_posts_cache WHERE post_id IN :ids"""
+    sql = """SELECT hp.id,
+                    author,
+                    permlink,
+                    title,
+                    img_url,
+                    hp.payout,
+                    hp.promoted,
+                    hp.created_at,
+                    hp.payout_at,
+                    hp.is_nsfw,
+                    hp.rshares,
+                    hp.votes,
+                    hp.is_muted,
+                    hp.is_invalid,
+                    %s
+               FROM hive_posts hp 
+               WHERE post_id IN :ids"""
     fields = ['preview'] if lite else ['body', 'updated_at', 'json']
     sql = sql % (', '.join(fields))
 
diff --git a/hive/server/hive_api/thread.py b/hive/server/hive_api/thread.py
index 27d98423528e2874e31e9c827ee013d99a155ee1..b3f03f7c96deb08faf22ea6e029b9adbfe28d391 100644
--- a/hive/server/hive_api/thread.py
+++ b/hive/server/hive_api/thread.py
@@ -29,7 +29,7 @@ async def fetch_more_children(context, root_id, last_sibling_id, sort='top',
                                  valid_limit(limit, 50),
                                  observer)
 
-_SORTS = dict(hot='sc_hot', top='payout', new='post_id')
+_SORTS = dict(hot='sc_hot', top='payout', new='id')
 async def _fetch_children(db, root_id, start_id, sort, limit, observer=None):
     """Fetch truncated children from tree."""
     mutes = set()
@@ -41,10 +41,10 @@ async def _fetch_children(db, root_id, start_id, sort, limit, observer=None):
     # find most relevant ids in subset
     seek = ''
     if start_id:
-        seek = """AND %s < (SELECT %s FROM hive_posts_cache
-                             WHERE post_id = :start_id)""" % (field, field)
-    sql = """SELECT post_id FROM hive_posts_cache
-              WHERE post_id IN :ids %s ORDER BY %s DESC
+        seek = """AND %s < (SELECT %s FROM hive_posts
+                             WHERE id = :start_id)""" % (field, field)
+    sql = """SELECT id FROM hive_posts
+              WHERE id IN :ids %s ORDER BY %s DESC
               LIMIT :limit""" % (seek, field)
     relevant_ids = await db.query_col(sql, ids=tuple(parent.keys()),
                                       start_id=start_id, limit=limit)
diff --git a/hive/server/serve.py b/hive/server/serve.py
index 873387dba2df1a3b9759d0d1242e10f783697474..9593dce1c9eacad0db9db9e0074ec6deab6f3229 100644
--- a/hive/server/serve.py
+++ b/hive/server/serve.py
@@ -140,7 +140,8 @@ def build_methods():
 
     # database_api methods
     methods.add(**{
-        'database_api.list_comments' : database_api.list_comments
+        'database_api.list_comments' : database_api.list_comments,
+        'database_api.find_comments' : database_api.find_comments
     })
 
     return methods
diff --git a/hive/utils/post.py b/hive/utils/post.py
index 9f299710f34a957d826f6ed2f8101cecc9023c68..8e4de28b7e2ea4db9a4fd938445cdd1b5d492761 100644
--- a/hive/utils/post.py
+++ b/hive/utils/post.py
@@ -60,7 +60,6 @@ def post_to_internal(post, post_id, level='insert', promoted=None):
             ('is_paidout',    basic['is_paidout']),
             ('json',          json.dumps(basic['json_metadata'])),
             #('raw_json',      json.dumps(legacy_data)),
-            ('legacy_id',               legacy_data['id']),
             ('parent_author',           legacy_data['parent_author']),
             ('parent_permlink',         legacy_data['parent_permlink']),
             ('curator_payout_value',    legacy_data['curator_payout_value']),
diff --git a/tests/manual_tests/list_comments_by_permlink.py b/tests/manual_tests/list_comments_by_permlink.py
index a5ef3e3339c49b317af35cb243bf3c149d07c3d8..8822f581b0634803c3b234a65c896c34570d4c65 100644
--- a/tests/manual_tests/list_comments_by_permlink.py
+++ b/tests/manual_tests/list_comments_by_permlink.py
@@ -1,5 +1,5 @@
 #!/usr/bin/python3
-from .test_base import run_test
+from test_base import run_test
 
 if __name__ == '__main__':
     reference_hive_node_url = 'https://api.hive.blog'
diff --git a/tests/server/test_server_database_api.py b/tests/server/test_server_database_api.py
index 9e8c1691db94931b604106c2f8343463df189cea..3bcb65bd289ddff068464de1b95ef22383528f73 100644
--- a/tests/server/test_server_database_api.py
+++ b/tests/server/test_server_database_api.py
@@ -12,7 +12,7 @@ def test_list_comments_by_cashout_time(client):
   assert reference_data
   assert test_data
   assert len(reference_data) == len(test_data)
-  to_compare = keys = ['author','permlink']
+  to_compare = ['author','permlink']
   for idx in range(len(reference_data)):
     for key in to_compare:
       assert reference_data[idx][key] == test_data[idx][key]
@@ -24,7 +24,7 @@ def test_list_comments_by_permlink(client):
   assert reference_data
   assert test_data
   assert len(reference_data) == len(test_data)
-  to_compare = keys = ['author','permlink']
+  to_compare = ['author','permlink']
   for idx in range(len(reference_data)):
     for key in to_compare:
       assert reference_data[idx][key] == test_data[idx][key]
@@ -35,7 +35,7 @@ def test_list_comments_by_root(client):
   assert reference_data
   assert test_data
   assert len(reference_data) == len(test_data)
-  to_compare = keys = ['author','permlink','root_author','root_permlink']
+  to_compare = ['author','permlink','root_author','root_permlink']
   for idx in range(len(reference_data)):
     for key in to_compare:
       assert reference_data[idx][key] == test_data[idx][key]
@@ -46,7 +46,7 @@ def test_list_comments_by_parent(client):
   assert reference_data
   assert test_data
   assert len(reference_data) == len(test_data)
-  to_compare = keys = ['author','permlink','parent_author','parent_permlink']
+  to_compare = ['author','permlink','parent_author','parent_permlink']
   for idx in range(len(reference_data)):
     for key in to_compare:
       assert reference_data[idx][key] == test_data[idx][key]