diff --git a/src/components/node/NodeComments/index.tsx b/src/components/node/NodeComments/index.tsx
index a0da7ee0..ec5fe23e 100644
--- a/src/components/node/NodeComments/index.tsx
+++ b/src/components/node/NodeComments/index.tsx
@@ -7,7 +7,7 @@ import { ICommentGroup, IComment } from '~/redux/types';
 import { groupCommentsByUser } from '~/utils/fn';
 import { IUser } from '~/redux/auth/types';
 import { canEditComment } from '~/utils/node';
-import { nodeLockComment, nodeEditComment } from '~/redux/node/actions';
+import { nodeLockComment, nodeEditComment, nodeLoadMoreComments } from '~/redux/node/actions';
 import { INodeState } from '~/redux/node/reducer';
 import { COMMENTS_DISPLAY } from '~/redux/node/constants';
 import { plural } from '~/utils/dom';
@@ -19,11 +19,21 @@ interface IProps {
   user: IUser;
   onDelete: typeof nodeLockComment;
   onEdit: typeof nodeEditComment;
+  onLoadMore: typeof nodeLoadMoreComments;
   order?: 'ASC' | 'DESC';
 }
 
 const NodeComments: FC<IProps> = memo(
-  ({ comments, comment_data, user, onDelete, onEdit, comment_count = 0, order = 'DESC' }) => {
+  ({
+    comments,
+    comment_data,
+    user,
+    onDelete,
+    onEdit,
+    onLoadMore,
+    comment_count = 0,
+    order = 'DESC',
+  }) => {
     const comments_left = useMemo(() => Math.max(0, comment_count - comments.length), [
       comments,
       comment_count,
@@ -34,10 +44,10 @@ const NodeComments: FC<IProps> = memo(
       [comments, order]
     );
 
-    return (
-      <div className={styles.wrap}>
-        {comment_count > 0 && (
-          <div className={styles.more}>
+    const more = useMemo(
+      () =>
+        comments_left > 0 && (
+          <div className={styles.more} onClick={onLoadMore}>
             Показать ещё{' '}
             {plural(
               Math.min(comments_left, COMMENTS_DISPLAY),
@@ -47,7 +57,13 @@ const NodeComments: FC<IProps> = memo(
             )}
             {comments_left > COMMENTS_DISPLAY ? ` из ${comments_left} оставшихся` : ''}
           </div>
-        )}
+        ),
+      [comments_left, onLoadMore, COMMENTS_DISPLAY]
+    );
+
+    return (
+      <div className={styles.wrap}>
+        {order === 'DESC' && more}
 
         {groupped.map(group => (
           <Comment
@@ -59,6 +75,8 @@ const NodeComments: FC<IProps> = memo(
             onEdit={onEdit}
           />
         ))}
+
+        {order === 'ASC' && more}
       </div>
     );
   }
diff --git a/src/components/node/NodeComments/styles.scss b/src/components/node/NodeComments/styles.scss
index 4da06029..d7d3e212 100644
--- a/src/components/node/NodeComments/styles.scss
+++ b/src/components/node/NodeComments/styles.scss
@@ -20,4 +20,11 @@
   text-transform: uppercase;
   color: darken(white, 50%);
   font: $font_14_regular;
+  cursor: pointer;
+  transition: background-color 0.25s;
+  user-select: none;
+
+  &:hover {
+    background-color: lighten($comment_bg, 4%);
+  }
 }
diff --git a/src/containers/node/BorisLayout/index.tsx b/src/containers/node/BorisLayout/index.tsx
index 62d682cc..791605b9 100644
--- a/src/containers/node/BorisLayout/index.tsx
+++ b/src/containers/node/BorisLayout/index.tsx
@@ -22,6 +22,7 @@ const mapDispatchToProps = {
   nodeLoadNode: NODE_ACTIONS.nodeLoadNode,
   nodeLockComment: NODE_ACTIONS.nodeLockComment,
   nodeEditComment: NODE_ACTIONS.nodeEditComment,
+  nodeLoadMoreComments: NODE_ACTIONS.nodeLoadMoreComments,
 };
 
 type IProps = ReturnType<typeof mapStateToProps> &
@@ -37,6 +38,7 @@ const BorisLayoutUnconnected: FC<IProps> = ({
   nodeLoadNode,
   nodeLockComment,
   nodeEditComment,
+  nodeLoadMoreComments,
 }) => {
   const title = getRandomPhrase('BORIS_TITLE');
 
@@ -92,6 +94,8 @@ const BorisLayoutUnconnected: FC<IProps> = ({
               user={user}
               onDelete={nodeLockComment}
               onEdit={nodeEditComment}
+              onLoadMore={nodeLoadMoreComments}
+              order="ASC"
             />
           )}
         </Group>
diff --git a/src/containers/node/NodeLayout/index.tsx b/src/containers/node/NodeLayout/index.tsx
index a9922cf4..10be9540 100644
--- a/src/containers/node/NodeLayout/index.tsx
+++ b/src/containers/node/NodeLayout/index.tsx
@@ -15,7 +15,6 @@ import { NodeComments } from '~/components/node/NodeComments';
 import { NodeTags } from '~/components/node/NodeTags';
 import { NODE_COMPONENTS, NODE_INLINES } from '~/redux/node/constants';
 import * as NODE_ACTIONS from '~/redux/node/actions';
-import { CommentForm } from '~/components/node/CommentForm';
 import { selectUser } from '~/redux/auth/selectors';
 import pick from 'ramda/es/pick';
 import { NodeRelatedPlaceholder } from '~/components/node/NodeRelated/placeholder';
@@ -37,6 +36,7 @@ const mapDispatchToProps = {
   nodeLock: NODE_ACTIONS.nodeLock,
   nodeLockComment: NODE_ACTIONS.nodeLockComment,
   nodeEditComment: NODE_ACTIONS.nodeEditComment,
+  nodeLoadMoreComments: NODE_ACTIONS.nodeLoadMoreComments,
 };
 
 type IProps = ReturnType<typeof mapStateToProps> &
@@ -68,6 +68,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
     nodeSetCoverImage,
     nodeLockComment,
     nodeEditComment,
+    nodeLoadMoreComments,
   }) => {
     const [layout, setLayout] = useState({});
 
@@ -148,6 +149,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
                       user={user}
                       onDelete={nodeLockComment}
                       onEdit={nodeEditComment}
+                      onLoadMore={nodeLoadMoreComments}
                       order="DESC"
                     />
                   )}
diff --git a/src/redux/node/actions.ts b/src/redux/node/actions.ts
index 2e5b13bd..90fe809c 100644
--- a/src/redux/node/actions.ts
+++ b/src/redux/node/actions.ts
@@ -133,3 +133,7 @@ export const nodeSetCoverImage = (current_cover_image: IFile) => ({
   type: NODE_ACTIONS.SET_COVER_IMAGE,
   current_cover_image,
 });
+
+export const nodeLoadMoreComments = () => ({
+  type: NODE_ACTIONS.LOAD_MORE_COMMENTS,
+});
diff --git a/src/redux/node/api.ts b/src/redux/node/api.ts
index 1ff0c0ec..f9807891 100644
--- a/src/redux/node/api.ts
+++ b/src/redux/node/api.ts
@@ -103,7 +103,7 @@ export const getNodeComments = ({
   access: string;
   take?: number;
   skip?: number;
-}): Promise<IResultWithStatus<{ comments: Comment[] }>> =>
+}): Promise<IResultWithStatus<{ comments: IComment[]; comment_count: number }>> =>
   api
     .get(API.NODE.COMMENT(id), configWithToken(access, { params: { take, skip } }))
     .then(resultMiddleware)
diff --git a/src/redux/node/constants.ts b/src/redux/node/constants.ts
index a3f9b253..46e81770 100644
--- a/src/redux/node/constants.ts
+++ b/src/redux/node/constants.ts
@@ -29,6 +29,7 @@ export const NODE_ACTIONS = {
   EDIT_COMMENT: `${prefix}EDIT_COMMENT`,
   CANCEL_COMMENT_EDIT: `${prefix}CANCEL_COMMENT_EDIT`,
   CREATE: `${prefix}CREATE`,
+  LOAD_MORE_COMMENTS: `${prefix}LOAD_MORE_COMMENTS`,
 
   SET_SAVE_ERRORS: `${prefix}SET_SAVE_ERRORS`,
   SET_LOADING: `${prefix}SET_LOADING`,
diff --git a/src/redux/node/sagas.ts b/src/redux/node/sagas.ts
index 9ba52d47..8ce5a8f5 100644
--- a/src/redux/node/sagas.ts
+++ b/src/redux/node/sagas.ts
@@ -1,4 +1,4 @@
-import { takeLatest, call, put, select, delay, all } from 'redux-saga/effects';
+import { takeLatest, call, put, select, delay, all, takeLeading } from 'redux-saga/effects';
 import { push } from 'connected-react-router';
 import omit from 'ramda/es/omit';
 
@@ -53,7 +53,7 @@ import { modalSetShown, modalShowDialog } from '../modal/actions';
 import { selectFlowNodes, selectFlow } from '../flow/selectors';
 import { URLS } from '~/constants/urls';
 import { selectNode } from './selectors';
-import { IResultWithStatus, INode } from '../types';
+import { IResultWithStatus, INode, Unwrap } from '../types';
 import { NODE_EDITOR_DIALOGS } from '~/constants/dialogs';
 import { DIALOGS } from '~/redux/modal/constants';
 import { INodeState } from './reducer';
@@ -119,6 +119,36 @@ function* onNodeGoto({ id, node_type }: ReturnType<typeof nodeGotoNode>) {
   yield put(push(URLS.NODE_URL(id)));
 }
 
+function* onNodeLoadMoreComments() {
+  const {
+    current: { id },
+    comments,
+  }: ReturnType<typeof selectNode> = yield select(selectNode);
+
+  const { data, error }: Unwrap<ReturnType<typeof getNodeComments>> = yield call(
+    reqWrapper,
+    getNodeComments,
+    {
+      id,
+      take: COMMENTS_DISPLAY,
+      skip: comments.length,
+    }
+  );
+
+  const current: ReturnType<typeof selectNode> = yield select(selectNode);
+
+  if (!data || error || current.current.id != id) {
+    return;
+  }
+
+  yield put(
+    nodeSet({
+      comments: [...comments, ...data.comments],
+      comment_count: data.comment_count,
+    })
+  );
+}
+
 function* onNodeLoad({ id, order = 'ASC' }: ReturnType<typeof nodeLoadNode>) {
   yield put(nodeSetLoading(true));
   yield put(nodeSetLoadingComments(true));
@@ -338,4 +368,5 @@ export default function* nodeSaga() {
   yield takeLatest(NODE_ACTIONS.LOCK, onLockSaga);
   yield takeLatest(NODE_ACTIONS.LOCK_COMMENT, onLockCommentSaga);
   yield takeLatest(NODE_ACTIONS.EDIT_COMMENT, onEditCommentSaga);
+  yield takeLeading(NODE_ACTIONS.LOAD_MORE_COMMENTS, onNodeLoadMoreComments);
 }
diff --git a/src/redux/types.ts b/src/redux/types.ts
index 8ef305fb..adb1e0fd 100644
--- a/src/redux/types.ts
+++ b/src/redux/types.ts
@@ -191,3 +191,5 @@ export type INodeNotification = {
 };
 
 export type INotification = IMessageNotification | ICommentNotification;
+
+export type Unwrap<T> = T extends Promise<infer U> ? U : T;